<commit_before># Copyright (c) 2012-2017, Mark Peek <mark@peek.org>
# All rights reserved.
#
# See LICENSE file for full license.

from . import AWSObject, AWSProperty
from .validators import boolean, double
from .validators import integer, integer_range, positive_integer

class CsvClassifier(AWSProperty):
    props = {
        'AllowSingleColumn': (boolean, False),
        'ContainsHeader': (basestring, False),
        'Delimiter': (basestring, False),
        'DisableValueTrimming': (boolean, False),
        'Header': ([basestring], False),
        'Name': (basestring, False),
        'QuoteSymbol': (basestring, False),
    }

class GrokClassifier(AWSProperty):
    props = {
        'Classification': (basestring, True),
        'CustomPatterns': (basestring, False),
        'GrokPattern': (basestring, True),
        'Name': (basestring, False),
    }

class JsonClassifier(AWSProperty):
    props = {
        'JsonPath': (basestring, True),
        'Name': (basestring, False),
    }

class XMLClassifier(AWSProperty):
    props = {
        'Classification': (basestring, True),
        'Name': (basestring, False),
        'RowTag': (basestring, True),
    }

class Classifier(AWSObject):
    resource_type = "AWS::Glue::Classifier"

    props = {
        'CsvClassifier': (CsvClassifier, False),
        'GrokClassifier': (GrokClassifier, False),
        'JsonClassifier': (JsonClassifier, False),
        'XMLClassifier': (XMLClassifier, False),
    }

class PhysicalConnectionRequirements(AWSProperty):
    props = {
        'AvailabilityZone': (basestring, False),
        'SecurityGroupIdList': ([basestring], False),
        'SubnetId': (basestring, False),
    }

def connection_type_validator(type):
    valid_types = [
        'JDBC',
        'KAFKA',
        'MONGODB',
        'SFTP',
    ]
    if type not in valid_types:
        raise ValueError('% is not a valid value for ConnectionType' % type)
    return type

class ConnectionInput(AWSProperty):
    props = {
        'ConnectionProperties': (dict, True),
        'ConnectionType': (connection_type_validator, True),
        'Description': (basestring, False),
        'MatchCriteria': ([basestring], False),
        'Name': (basestring, False),
        'PhysicalConnectionRequirements':
            (PhysicalConnectionRequirements, False),
    }

class Connection(AWSObject):
    resource_type = "AWS::Glue::Connection"

    props = {
        'CatalogId': (basestring, True),
        'ConnectionInput': (ConnectionInput, True),
    }

class Schedule(AWSProperty):
    props = {
        'ScheduleExpression': (basestring, False),
    }

def delete_behavior_validator(value):
    valid_values = [
        'LOG',
        'DELETE_FROM_DATABASE',
        'DEPRECATE_IN_DATABASE',
    ]
    if value not in valid_values:
        raise ValueError('% is not a valid value for DeleteBehavior' % value)
    return value

def update_behavior_validator(value):
    valid_values = [
        'LOG',
        'UPDATE_IN_DATABASE',
    ]
    if value not in valid_values:
        raise ValueError('% is not a valid value for UpdateBehavior' % value)
    return value

class SchemaChangePolicy(AWSProperty):
    props = {
        'DeleteBehavior': (delete_behavior_validator, False),
        'UpdateBehavior': (update_behavior_validator, False),
    }

class CatalogTarget(AWSProperty):
    props = {
        'DatabaseName': (basestring, False),
        'Tables': ([basestring], False),
    }

class DynamoDBTarget(AWSProperty):
    props = {
        'Path': (basestring, False),
    }

class JdbcTarget(AWSProperty):
    props = {
        'ConnectionName': (basestring, False),
        'Exclusions': ([basestring], False),
        'Path': (basestring, False),
    }

class S3Target(AWSProperty):
    props = {
        'Exclusions': ([basestring], False),
        'Path': (basestring, False),
    }

class Targets(AWSProperty):
    props = {
        'CatalogTargets': ([CatalogTarget], False),
        'DynamoDBTargets': ([DynamoDBTarget], False),
        'JdbcTargets': ([JdbcTarget], False),
        'S3Targets': ([S3Target], False),
    }

class Crawler(AWSObject):
    resource_type = "AWS::Glue::Crawler"

    props = {
        'Classifiers': ([basestring], False),
        'Configuration': (basestring, False),
        'CrawlerSecurityConfiguration': (basestring, False),
        'DatabaseName': (basestring, True),
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Role': (basestring, True),
        'Schedule': (Schedule, False),
        'SchemaChangePolicy': (SchemaChangePolicy, False),
        'TablePrefix': (basestring, False),
        'Tags': (dict, False),
        'Targets': (Targets, True),
    }

class ConnectionPasswordEncryption(AWSProperty):
    props = {
        'KmsKeyId': (basestring, False),
        'ReturnConnectionPasswordEncrypted': (boolean, False),
    }

class EncryptionAtRest(AWSProperty):
    props = {
        'CatalogEncryptionMode': (basestring, False),
        'SseAwsKmsKeyId': (basestring, False),
    }

class DataCatalogEncryptionSettingsProperty(AWSProperty):
    props = {
        'ConnectionPasswordEncryption':
            (ConnectionPasswordEncryption, False),
        'EncryptionAtRest': (EncryptionAtRest, False),
    }

class DataCatalogEncryptionSettings(AWSObject):
    resource_type = "AWS::Glue::DataCatalogEncryptionSettings"

    props = {
        'CatalogId': (basestring, True),
        'DataCatalogEncryptionSettings':
            (DataCatalogEncryptionSettingsProperty, True),
    }

class DatabaseInput(AWSProperty):
    props = {
        'Description': (basestring, False),
        'LocationUri': (basestring, False),
        'Name': (basestring, False),
        'Parameters': (dict, False),
    }

class Database(AWSObject):
    resource_type = "AWS::Glue::Database"

    props = {
        'CatalogId': (basestring, True),
        'DatabaseInput': (DatabaseInput, True),
    }

class DevEndpoint(AWSObject):
    resource_type = "AWS::Glue::DevEndpoint"

    props = {
        'Arguments': (dict, False),
        'EndpointName': (basestring, False),
        'ExtraJarsS3Path': (basestring, False),
        'ExtraPythonLibsS3Path': (basestring, False),
        'GlueVersion': (basestring, False),
        'NumberOfNodes': (integer, False),
        'NumberOfWorkers': (integer, False),
        'PublicKey': (basestring, False),
        'PublicKeys': ([basestring], False),
        'RoleArn': (basestring, True),
        'SecurityConfiguration': (basestring, False),
        'SecurityGroupIds': ([basestring], False),
        'SubnetId': (basestring, False),
        'Tags': (dict, False),
        'WorkerType': (basestring, False),
    }

class ConnectionsList(AWSProperty):
    props = {
        'Connections': ([basestring], False),
    }

class ExecutionProperty(AWSProperty):
    props = {
        'MaxConcurrentRuns': (positive_integer, False),
    }

class JobCommand(AWSProperty):
    props = {
        'Name': (basestring, False),
        'PythonVersion': (basestring, False),
        'ScriptLocation': (basestring, False),
    }

class NotificationProperty(AWSProperty):
    props = {
        'NotifyDelayAfter': (integer, False),
    }

class Job(AWSObject):
    resource_type = "AWS::Glue::Job"

    props = {
        'AllocatedCapacity': (double, False),
        'Command': (JobCommand, True),
        'Connections': (ConnectionsList, False),
        'DefaultArguments': (dict, False),
        'Description': (basestring, False),
        'ExecutionProperty': (ExecutionProperty, False),
        'GlueVersion': (basestring, False),
        'LogUri': (basestring, False),
        'MaxCapacity': (double, False),
        'MaxRetries': (double, False),
        'Name': (basestring, False),
        'NotificationProperty': (NotificationProperty, False),
        'NumberOfWorkers': (integer, False),
        'Role': (basestring, True),
        'SecurityConfiguration': (basestring, False),
        'Tags': (dict, False),
        'Timeout': (integer, False),
        'WorkerType': (basestring, False),
    }

class GlueTables(AWSProperty):
    props = {
        'CatalogId': (basestring, False),
        'ConnectionName': (basestring, False),
        'DatabaseName': (basestring, True),
        'TableName': (basestring, True),
    }

class InputRecordTables(AWSProperty):
    props = {
        'GlueTables': ([GlueTables], False),
    }

class FindMatchesParameters(AWSProperty):
    props = {
        'AccuracyCostTradeoff': (float, False),
        'EnforceProvidedLabels': (boolean, False),
        'PrecisionRecallTradeoff': (float, False),
        'PrimaryKeyColumnName': (basestring, True),
    }

class TransformParameters(AWSProperty):
    props = {
        'FindMatchesParameters': (FindMatchesParameters, False),
        'TransformType': (basestring, True),
    }

class MLTransform(AWSObject):
    resource_type = "AWS::Glue::MLTransform"

    props = {
        'Description': (basestring, False),
        'GlueVersion': (basestring, False),
        'InputRecordTables': (InputRecordTables, True),
        'MaxCapacity': (double, False),
        'MaxRetries': (integer, False),
        'Name': (basestring, False),
        'NumberOfWorkers': (integer, False),
        'Role': (basestring, True),
        'Tags': (dict, False),
        'Timeout': (integer, False),
        'TransformParameters': (TransformParameters, True),
        'WorkerType': (basestring, False),
    }

class Column(AWSProperty):
    props = {
        'Comment': (basestring, False),
        'Name': (basestring, True),
        'Type': (basestring, False),
    }

class Order(AWSProperty):
    props = {
        'Column': (basestring, True),
        'SortOrder': (integer_range(0, 1), False),
    }

class SerdeInfo(AWSProperty):
    props = {
        'Name': (basestring, False),
        'Parameters': (dict, False),
        'SerializationLibrary': (basestring, False),
    }

class SkewedInfo(AWSProperty):
    props = {
        'SkewedColumnNames': ([basestring], False),
        'SkewedColumnValues': ([basestring], False),
        'SkewedColumnValueLocationMaps': (dict, False),
    }

class StorageDescriptor(AWSProperty):
    props = {
        'BucketColumns': ([basestring], False),
        'Columns': ([Column], False),
        'Compressed': (boolean, False),
        'InputFormat': (basestring, False),
        'Location': (basestring, False),
        'NumberOfBuckets': (positive_integer, False),
        'OutputFormat': (basestring, False),
        'Parameters': (dict, False),
        'SerdeInfo': (SerdeInfo, False),
        'SkewedInfo': (SkewedInfo, False),
        'SortColumns': ([Order], False),
        'StoredAsSubDirectories': (boolean, False),
    }

class PartitionInput(AWSProperty):
    props = {
        'Parameters': (dict, False),
        'StorageDescriptor': (StorageDescriptor, False),
        'Values': ([basestring], True),
    }

class Partition(AWSObject):
    resource_type = "AWS::Glue::Partition"

    props = {
        'CatalogId': (basestring, True),
        'DatabaseName': (basestring, True),
        'PartitionInput': (PartitionInput, True),
        'TableName': (basestring, True),
    }

class CloudWatchEncryption(AWSProperty):
    props = {
        'CloudWatchEncryptionMode': (basestring, False),
        'KmsKeyArn': (basestring, False),
    }

class JobBookmarksEncryption(AWSProperty):
    props = {
        'JobBookmarksEncryptionMode': (basestring, False),
        'KmsKeyArn': (basestring, False),
    }

class S3Encryption(AWSProperty):
    props = {
        'KmsKeyArn': (basestring, False),
        'S3EncryptionMode': (basestring, False),
    }

class EncryptionConfiguration(AWSProperty):
    props = {
        'CloudWatchEncryption': (CloudWatchEncryption, False),
        'JobBookmarksEncryption': (JobBookmarksEncryption, False),
        'S3Encryptions': ([S3Encryption], False),
    }

class SecurityConfiguration(AWSObject):
    resource_type = "AWS::Glue::SecurityConfiguration"

    props = {
        'EncryptionConfiguration': (EncryptionConfiguration, True),
        'Name': (basestring, True),
    }

def table_type_validator(type):
    valid_types = [
        'EXTERNAL_TABLE',
        'VIRTUAL_VIEW',
    ]
    if type not in valid_types:
        raise ValueError('% is not a valid value for TableType' % type)
    return type

class TableInput(AWSProperty):
    props = {
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Owner': (basestring, False),
        'Parameters': (dict, False),
        'PartitionKeys': ([Column], False),
        'Retention': (positive_integer, False),
        'StorageDescriptor': (StorageDescriptor, False),
        'TableType': (table_type_validator, False),
        'ViewExpandedText': (basestring, False),
        'ViewOriginalText': (basestring, False),
    }

class Table(AWSObject):
    resource_type = "AWS::Glue::Table"

    props = {
        'CatalogId': (basestring, True),
        'DatabaseName': (basestring, True),
        'TableInput': (TableInput, True),
    }

class Action(AWSProperty):
    props = {
        'Arguments': (dict, False),
        'CrawlerName': (basestring, False),
        'JobName': (basestring, False),
        'SecurityConfiguration': (basestring, False),
    }

class Condition(AWSProperty):
    props = {
        'CrawlerName': (basestring, False),
        'CrawlState': (basestring, False),
        'JobName': (basestring, False),
        'LogicalOperator': (basestring, False),
        'State': (basestring, False),
    }

class Predicate(AWSProperty):
    props = {
        'Conditions': ([Condition], False),
        'Logical': (basestring, False),
    }

def trigger_type_validator(type):
    valid_types = [
        'SCHEDULED',
        'CONDITIONAL',
        'ON_DEMAND',
    ]
    if type not in valid_types:
        raise ValueError('% is not a valid value for Type' % type)
    return type

class Trigger(AWSObject):
    resource_type = "AWS::Glue::Trigger"

    props = {
        'Actions': ([Action], True),
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Predicate': (Predicate, False),
        'Schedule': (basestring, False),
        'StartOnCreation': (boolean, False),
        'Tags': (dict, False),
        'Type': (basestring, True),
        'WorkflowName': (basestring, False),
    }

class Workflow(AWSObject):
    resource_type = "AWS::Glue::Workflow"

    props = {
        'DefaultRunProperties': (dict, False),
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Tags': (dict, False),
    }
<commit_msg>AWS::Glue::Connection.ConnectionInput.ConnectionType AllowedValues expansion (NETWORK) (#1826)<commit_after># Copyright (c) 2012-2017, Mark Peek <mark@peek.org>
# All rights reserved.
#
# See LICENSE file for full license.

from . import AWSObject, AWSProperty
from .validators import boolean, double
from .validators import integer, integer_range, positive_integer

class CsvClassifier(AWSProperty):
    props = {
        'AllowSingleColumn': (boolean, False),
        'ContainsHeader': (basestring, False),
        'Delimiter': (basestring, False),
        'DisableValueTrimming': (boolean, False),
        'Header': ([basestring], False),
        'Name': (basestring, False),
        'QuoteSymbol': (basestring, False),
    }

class GrokClassifier(AWSProperty):
    props = {
        'Classification': (basestring, True),
        'CustomPatterns': (basestring, False),
        'GrokPattern': (basestring, True),
        'Name': (basestring, False),
    }

class JsonClassifier(AWSProperty):
    props = {
        'JsonPath': (basestring, True),
        'Name': (basestring, False),
    }

class XMLClassifier(AWSProperty):
    props = {
        'Classification': (basestring, True),
        'Name': (basestring, False),
        'RowTag': (basestring, True),
    }

class Classifier(AWSObject):
    resource_type = "AWS::Glue::Classifier"

    props = {
        'CsvClassifier': (CsvClassifier, False),
        'GrokClassifier': (GrokClassifier, False),
        'JsonClassifier': (JsonClassifier, False),
        'XMLClassifier': (XMLClassifier, False),
    }

class PhysicalConnectionRequirements(AWSProperty):
    props = {
        'AvailabilityZone': (basestring, False),
        'SecurityGroupIdList': ([basestring], False),
        'SubnetId': (basestring, False),
    }

def connection_type_validator(type):
    valid_types = [
        'JDBC',
        'KAFKA',
        'MONGODB',
        'NETWORK',
        'SFTP',
    ]
    if type not in valid_types:
        raise ValueError('% is not a valid value for ConnectionType' % type)
    return type

class ConnectionInput(AWSProperty):
    props = {
        'ConnectionProperties': (dict, True),
        'ConnectionType': (connection_type_validator, True),
        'Description': (basestring, False),
        'MatchCriteria': ([basestring], False),
        'Name': (basestring, False),
        'PhysicalConnectionRequirements':
            (PhysicalConnectionRequirements, False),
    }

class Connection(AWSObject):
    resource_type = "AWS::Glue::Connection"

    props = {
        'CatalogId': (basestring, True),
        'ConnectionInput': (ConnectionInput, True),
    }

class Schedule(AWSProperty):
    props = {
        'ScheduleExpression': (basestring, False),
    }

def delete_behavior_validator(value):
    valid_values = [
        'LOG',
        'DELETE_FROM_DATABASE',
        'DEPRECATE_IN_DATABASE',
    ]
    if value not in valid_values:
        raise ValueError('% is not a valid value for DeleteBehavior' % value)
    return value

def update_behavior_validator(value):
    valid_values = [
        'LOG',
        'UPDATE_IN_DATABASE',
    ]
    if value not in valid_values:
        raise ValueError('% is not a valid value for UpdateBehavior' % value)
    return value

class SchemaChangePolicy(AWSProperty):
    props = {
        'DeleteBehavior': (delete_behavior_validator, False),
        'UpdateBehavior': (update_behavior_validator, False),
    }

class CatalogTarget(AWSProperty):
    props = {
        'DatabaseName': (basestring, False),
        'Tables': ([basestring], False),
    }

class DynamoDBTarget(AWSProperty):
    props = {
        'Path': (basestring, False),
    }

class JdbcTarget(AWSProperty):
    props = {
        'ConnectionName': (basestring, False),
        'Exclusions': ([basestring], False),
        'Path': (basestring, False),
    }

class S3Target(AWSProperty):
    props = {
        'Exclusions': ([basestring], False),
        'Path': (basestring, False),
    }

class Targets(AWSProperty):
    props = {
        'CatalogTargets': ([CatalogTarget], False),
        'DynamoDBTargets': ([DynamoDBTarget], False),
        'JdbcTargets': ([JdbcTarget], False),
        'S3Targets': ([S3Target], False),
    }

class Crawler(AWSObject):
    resource_type = "AWS::Glue::Crawler"

    props = {
        'Classifiers': ([basestring], False),
        'Configuration': (basestring, False),
        'CrawlerSecurityConfiguration': (basestring, False),
        'DatabaseName': (basestring, True),
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Role': (basestring, True),
        'Schedule': (Schedule, False),
        'SchemaChangePolicy': (SchemaChangePolicy, False),
        'TablePrefix': (basestring, False),
        'Tags': (dict, False),
        'Targets': (Targets, True),
    }

class ConnectionPasswordEncryption(AWSProperty):
    props = {
        'KmsKeyId': (basestring, False),
        'ReturnConnectionPasswordEncrypted': (boolean, False),
    }

class EncryptionAtRest(AWSProperty):
    props = {
        'CatalogEncryptionMode': (basestring, False),
        'SseAwsKmsKeyId': (basestring, False),
    }

class DataCatalogEncryptionSettingsProperty(AWSProperty):
    props = {
        'ConnectionPasswordEncryption':
            (ConnectionPasswordEncryption, False),
        'EncryptionAtRest': (EncryptionAtRest, False),
    }

class DataCatalogEncryptionSettings(AWSObject):
    resource_type = "AWS::Glue::DataCatalogEncryptionSettings"

    props = {
        'CatalogId': (basestring, True),
        'DataCatalogEncryptionSettings':
            (DataCatalogEncryptionSettingsProperty, True),
    }

class DatabaseInput(AWSProperty):
    props = {
        'Description': (basestring, False),
        'LocationUri': (basestring, False),
        'Name': (basestring, False),
        'Parameters': (dict, False),
    }

class Database(AWSObject):
    resource_type = "AWS::Glue::Database"

    props = {
        'CatalogId': (basestring, True),
        'DatabaseInput': (DatabaseInput, True),
    }

class DevEndpoint(AWSObject):
    resource_type = "AWS::Glue::DevEndpoint"

    props = {
        'Arguments': (dict, False),
        'EndpointName': (basestring, False),
        'ExtraJarsS3Path': (basestring, False),
        'ExtraPythonLibsS3Path': (basestring, False),
        'GlueVersion': (basestring, False),
        'NumberOfNodes': (integer, False),
        'NumberOfWorkers': (integer, False),
        'PublicKey': (basestring, False),
        'PublicKeys': ([basestring], False),
        'RoleArn': (basestring, True),
        'SecurityConfiguration': (basestring, False),
        'SecurityGroupIds': ([basestring], False),
        'SubnetId': (basestring, False),
        'Tags': (dict, False),
        'WorkerType': (basestring, False),
    }

class ConnectionsList(AWSProperty):
    props = {
        'Connections': ([basestring], False),
    }

class ExecutionProperty(AWSProperty):
    props = {
        'MaxConcurrentRuns': (positive_integer, False),
    }

class JobCommand(AWSProperty):
    props = {
        'Name': (basestring, False),
        'PythonVersion': (basestring, False),
        'ScriptLocation': (basestring, False),
    }

class NotificationProperty(AWSProperty):
    props = {
        'NotifyDelayAfter': (integer, False),
    }

class Job(AWSObject):
    resource_type = "AWS::Glue::Job"

    props = {
        'AllocatedCapacity': (double, False),
        'Command': (JobCommand, True),
        'Connections': (ConnectionsList, False),
        'DefaultArguments': (dict, False),
        'Description': (basestring, False),
        'ExecutionProperty': (ExecutionProperty, False),
        'GlueVersion': (basestring, False),
        'LogUri': (basestring, False),
        'MaxCapacity': (double, False),
        'MaxRetries': (double, False),
        'Name': (basestring, False),
        'NotificationProperty': (NotificationProperty, False),
        'NumberOfWorkers': (integer, False),
        'Role': (basestring, True),
        'SecurityConfiguration': (basestring, False),
        'Tags': (dict, False),
        'Timeout': (integer, False),
        'WorkerType': (basestring, False),
    }

class GlueTables(AWSProperty):
    props = {
        'CatalogId': (basestring, False),
        'ConnectionName': (basestring, False),
        'DatabaseName': (basestring, True),
        'TableName': (basestring, True),
    }

class InputRecordTables(AWSProperty):
    props = {
        'GlueTables': ([GlueTables], False),
    }

class FindMatchesParameters(AWSProperty):
    props = {
        'AccuracyCostTradeoff': (float, False),
        'EnforceProvidedLabels': (boolean, False),
        'PrecisionRecallTradeoff': (float, False),
        'PrimaryKeyColumnName': (basestring, True),
    }

class TransformParameters(AWSProperty):
    props = {
        'FindMatchesParameters': (FindMatchesParameters, False),
        'TransformType': (basestring, True),
    }

class MLTransform(AWSObject):
    resource_type = "AWS::Glue::MLTransform"

    props = {
        'Description': (basestring, False),
        'GlueVersion': (basestring, False),
        'InputRecordTables': (InputRecordTables, True),
        'MaxCapacity': (double, False),
        'MaxRetries': (integer, False),
        'Name': (basestring, False),
        'NumberOfWorkers': (integer, False),
        'Role': (basestring, True),
        'Tags': (dict, False),
        'Timeout': (integer, False),
        'TransformParameters': (TransformParameters, True),
        'WorkerType': (basestring, False),
    }

class Column(AWSProperty):
    props = {
        'Comment': (basestring, False),
        'Name': (basestring, True),
        'Type': (basestring, False),
    }

class Order(AWSProperty):
    props = {
        'Column': (basestring, True),
        'SortOrder': (integer_range(0, 1), False),
    }

class SerdeInfo(AWSProperty):
    props = {
        'Name': (basestring, False),
        'Parameters': (dict, False),
        'SerializationLibrary': (basestring, False),
    }

class SkewedInfo(AWSProperty):
    props = {
        'SkewedColumnNames': ([basestring], False),
        'SkewedColumnValues': ([basestring], False),
        'SkewedColumnValueLocationMaps': (dict, False),
    }

class StorageDescriptor(AWSProperty):
    props = {
        'BucketColumns': ([basestring], False),
        'Columns': ([Column], False),
        'Compressed': (boolean, False),
        'InputFormat': (basestring, False),
        'Location': (basestring, False),
        'NumberOfBuckets': (positive_integer, False),
        'OutputFormat': (basestring, False),
        'Parameters': (dict, False),
        'SerdeInfo': (SerdeInfo, False),
        'SkewedInfo': (SkewedInfo, False),
        'SortColumns': ([Order], False),
        'StoredAsSubDirectories': (boolean, False),
    }

class PartitionInput(AWSProperty):
    props = {
        'Parameters': (dict, False),
        'StorageDescriptor': (StorageDescriptor, False),
        'Values': ([basestring], True),
    }

class Partition(AWSObject):
    resource_type = "AWS::Glue::Partition"

    props = {
        'CatalogId': (basestring, True),
        'DatabaseName': (basestring, True),
        'PartitionInput': (PartitionInput, True),
        'TableName': (basestring, True),
    }

class CloudWatchEncryption(AWSProperty):
    props = {
        'CloudWatchEncryptionMode': (basestring, False),
        'KmsKeyArn': (basestring, False),
    }

class JobBookmarksEncryption(AWSProperty):
    props = {
        'JobBookmarksEncryptionMode': (basestring, False),
        'KmsKeyArn': (basestring, False),
    }

class S3Encryption(AWSProperty):
    props = {
        'KmsKeyArn': (basestring, False),
        'S3EncryptionMode': (basestring, False),
    }

class EncryptionConfiguration(AWSProperty):
    props = {
        'CloudWatchEncryption': (CloudWatchEncryption, False),
        'JobBookmarksEncryption': (JobBookmarksEncryption, False),
        'S3Encryptions': ([S3Encryption], False),
    }

class SecurityConfiguration(AWSObject):
    resource_type = "AWS::Glue::SecurityConfiguration"

    props = {
        'EncryptionConfiguration': (EncryptionConfiguration, True),
        'Name': (basestring, True),
    }

def table_type_validator(type):
    valid_types = [
        'EXTERNAL_TABLE',
        'VIRTUAL_VIEW',
    ]
    if type not in valid_types:
        raise ValueError('% is not a valid value for TableType' % type)
    return type

class TableInput(AWSProperty):
    props = {
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Owner': (basestring, False),
        'Parameters': (dict, False),
        'PartitionKeys': ([Column], False),
        'Retention': (positive_integer, False),
        'StorageDescriptor': (StorageDescriptor, False),
        'TableType': (table_type_validator, False),
        'ViewExpandedText': (basestring, False),
        'ViewOriginalText': (basestring, False),
    }

class Table(AWSObject):
    resource_type = "AWS::Glue::Table"

    props = {
        'CatalogId': (basestring, True),
        'DatabaseName': (basestring, True),
        'TableInput': (TableInput, True),
    }

class Action(AWSProperty):
    props = {
        'Arguments': (dict, False),
        'CrawlerName': (basestring, False),
        'JobName': (basestring, False),
        'SecurityConfiguration': (basestring, False),
    }

class Condition(AWSProperty):
    props = {
        'CrawlerName': (basestring, False),
        'CrawlState': (basestring, False),
        'JobName': (basestring, False),
        'LogicalOperator': (basestring, False),
        'State': (basestring, False),
    }

class Predicate(AWSProperty):
    props = {
        'Conditions': ([Condition], False),
        'Logical': (basestring, False),
    }

def trigger_type_validator(type):
    valid_types = [
        'SCHEDULED',
        'CONDITIONAL',
        'ON_DEMAND',
    ]
    if type not in valid_types:
        raise ValueError('% is not a valid value for Type' % type)
    return type

class Trigger(AWSObject):
    resource_type = "AWS::Glue::Trigger"

    props = {
        'Actions': ([Action], True),
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Predicate': (Predicate, False),
        'Schedule': (basestring, False),
        'StartOnCreation': (boolean, False),
        'Tags': (dict, False),
        'Type': (basestring, True),
        'WorkflowName': (basestring, False),
    }

class Workflow(AWSObject):
    resource_type = "AWS::Glue::Workflow"

    props = {
        'DefaultRunProperties': (dict, False),
        'Description': (basestring, False),
        'Name': (basestring, False),
        'Tags': (dict, False),
    }
<|endoftext|>


<commit_before>#!/usr/bin/env python
description = ">> New automated psf version"
usage = "%prog image [options] "

import lsc
import time
import sys
import os
from pyraf import iraf
from optparse import OptionParser

if __name__ == "__main__":
    start_time = time.time()
    parser = OptionParser(usage=usage, description=description)
    parser.add_option("-f", "--fwhm", dest="fwhm", type=float, help='starting FWHM  \t\t\t %default')
    parser.add_option("-t", "--threshold", dest="threshold", default=10., type='float',
                      help='Source detection threshold \t\t\t %default')
    parser.add_option("-p", "--psfstars", dest="psfstars", default=6, type='int',
                      help='Maximum number of psf stars \t\t\t %default')
    parser.add_option("-d", "--distance", dest="distance", default=5,
                      type='int', help='Minimum star separation (in unit of FWHM) \t\t %default')
    parser.add_option("--function", dest="psffun", default='gauss', type='str',
                      help='psf function (gauss,auto,moffat15,moffat25,penny1,penny2,lorentz) \t\t %default')
    parser.add_option("-r", "--redo", action="store_true", dest='redo', default=False,
                      help='Re-do \t\t\t\t [%default]')
    parser.add_option("-i", "--interactive", action="store_true", dest='interactive', default=False,
                      help='Interactive \t\t\t [%default]')
    parser.add_option("-s", "--show", dest="show", action='store_true',
                      default=False, help='Show PSF output \t\t [%default]')
    parser.add_option("--use-sextractor", action="store_true", help="use souces from sextractor instead of catalog")
    parser.add_option("-c", "--catalog", dest="catalog", default='', type='str',
                      help='use input catalog  \t\t %default')
    parser.add_option("--fix", action="store_true", dest='fixaperture', default=False,
                      help='fixaperture \t\t\t [%default]')
    parser.add_option("--datamin", type=int, default=-100,
                      help="value below which pixels are considered bad")
    parser.add_option("--datamax", type=int,
                      help="value above which pixels are considered saturated (default = SATURATE in header)")

    option, args = parser.parse_args()
    if len(args) < 1:
        sys.argv.append('--help')
    option, args = parser.parse_args()
    imglist = lsc.util.readlist(args[0])
    _catalog = option.catalog
    fixaperture = option.fixaperture
    psffun = option.psffun
    if psffun not in ['gauss', 'auto', 'lorentz', 'moffat15', 'moffat25', 'penny1', 'penny2']:
        sys.argv.append('--help')
    option, args = parser.parse_args()

    for img in imglist:
        if os.path.exists(img.replace('.fits', '.psf.fits')) and not option.redo:
            print img + ': psf already calculated'
        else:
            if 'optimal' in img: # PyZOGY difference images
                img_for_psf = img.replace('.fits', '.zogypsf')
                fwhm0 = 5
                make_sn2 = False
                psfstars = 1
                catalog = lsc.__path__[0] + '/standard/cat/zero.cat'
            else:
                img_for_psf = img.replace('.fits', '')
                fwhm0 = option.fwhm
                make_sn2 = True
                psfstars = option.psfstars
                if not option.use_sextractor and not option.catalog:
                    for system in ['sloan', 'apass', 'landolt']:
                        catalog = lsc.util.getcatalog(img, system)
                        if catalog:
                            break
                else:
                    catalog = option.catalog
            while True:
                result, fwhm = lsc.lscpsfdef.ecpsf(img_for_psf, fwhm0, option.threshold, psfstars,
                                                   option.distance, option.interactive, psffun, fixaperture,
                                                   catalog, option.datamin, option.datamax, option.show, make_sn2)
                print '\n### ' + str(result)
                if option.show:
#                    lsc.util.marksn2(img + '.fits', img + '.sn2.fits', 1, '')
                    iraf.delete('tmp.psf.fit?', verify=False)
                    iraf.seepsf(img.replace('.fits', '.psf'), '_psf.psf')
                    iraf.surface('_psf.psf')
                    aa = raw_input('>>>good psf [[y]/n] ? ')
                    if not aa or aa.lower()[0] == 'y':
                        break
                    if aa.lower()[0] == 'n':
                        result = 0
                        bb = raw_input('If you want to try again, type the new FWHM to try here. Otherwise press enter to continue. ')
                        if bb: fwhm0 = float(bb)
                        else: break
                else:
                    break

            iraf.delete("tmp.*", verify="no")
            iraf.delete("_psf.*", verify="no")
            print  "********** Completed in ", int(time.time() - start_time), "sec"
            print result
            try:
                basename = os.path.basename(img)
                if result == 1:
                    lsc.mysqldef.updatevalue('photlco', 'psf', basename.replace('.fits', '.psf.fits'), basename)
                    lsc.mysqldef.updatevalue('photlco', 'fwhm', fwhm, basename)
                    lsc.mysqldef.updatevalue('photlco', 'mag', 9999, basename)
                    lsc.mysqldef.updatevalue('photlco', 'psfmag', 9999, basename)
                    lsc.mysqldef.updatevalue('photlco', 'apmag', 9999, basename)
                    if 'diff' not in img and os.path.isfile(img + '.diff.fits') and os.path.isfile(img + '.sn2.fits'):
                        # update diff info is file available
                        os.system('cp ' + img + '.sn2.fits ' + img + '.diff.sn2.fits')
                        lsc.mysqldef.updatevalue('photlco', 'psf', basename + '.psf.fits', basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'fwhm', fwhm, basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'mag', 9999, basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'psfmag', 9999, basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'apmag', 9999, basename + '.diff.fits')
                else:
                    print 'psf not good, database not updated '
                    lsc.mysqldef.updatevalue('photlco', 'psf', 'X', basename + '.fits')
                    if os.path.isfile(img + '.diff.fits'):
                        lsc.mysqldef.updatevalue('photlco', 'psf', 'X', basename + '.diff.fits')
            except:
                print 'module mysqldef not found'

<commit_msg>enable adjusting FWHM for ZOGY PSFs<commit_after>#!/usr/bin/env python
description = ">> New automated psf version"
usage = "%prog image [options] "

import lsc
import time
import sys
import os
from pyraf import iraf
from optparse import OptionParser

if __name__ == "__main__":
    start_time = time.time()
    parser = OptionParser(usage=usage, description=description)
    parser.add_option("-f", "--fwhm", dest="fwhm", type=float, help='starting FWHM  \t\t\t %default')
    parser.add_option("-t", "--threshold", dest="threshold", default=10., type='float',
                      help='Source detection threshold \t\t\t %default')
    parser.add_option("-p", "--psfstars", dest="psfstars", default=6, type='int',
                      help='Maximum number of psf stars \t\t\t %default')
    parser.add_option("-d", "--distance", dest="distance", default=5,
                      type='int', help='Minimum star separation (in unit of FWHM) \t\t %default')
    parser.add_option("--function", dest="psffun", default='gauss', type='str',
                      help='psf function (gauss,auto,moffat15,moffat25,penny1,penny2,lorentz) \t\t %default')
    parser.add_option("-r", "--redo", action="store_true", dest='redo', default=False,
                      help='Re-do \t\t\t\t [%default]')
    parser.add_option("-i", "--interactive", action="store_true", dest='interactive', default=False,
                      help='Interactive \t\t\t [%default]')
    parser.add_option("-s", "--show", dest="show", action='store_true',
                      default=False, help='Show PSF output \t\t [%default]')
    parser.add_option("--use-sextractor", action="store_true", help="use souces from sextractor instead of catalog")
    parser.add_option("-c", "--catalog", dest="catalog", default='', type='str',
                      help='use input catalog  \t\t %default')
    parser.add_option("--fix", action="store_true", dest='fixaperture', default=False,
                      help='fixaperture \t\t\t [%default]')
    parser.add_option("--datamin", type=int, default=-100,
                      help="value below which pixels are considered bad")
    parser.add_option("--datamax", type=int,
                      help="value above which pixels are considered saturated (default = SATURATE in header)")

    option, args = parser.parse_args()
    if len(args) < 1:
        sys.argv.append('--help')
    option, args = parser.parse_args()
    imglist = lsc.util.readlist(args[0])
    _catalog = option.catalog
    fixaperture = option.fixaperture
    psffun = option.psffun
    if psffun not in ['gauss', 'auto', 'lorentz', 'moffat15', 'moffat25', 'penny1', 'penny2']:
        sys.argv.append('--help')
    option, args = parser.parse_args()

    for img in imglist:
        if os.path.exists(img.replace('.fits', '.psf.fits')) and not option.redo:
            print img + ': psf already calculated'
        else:
            if 'optimal' in img: # PyZOGY difference images
                img_for_psf = img.replace('.fits', '.zogypsf')
                if option.fwhm:
                    fwhm0 = option.fwhm
                else:
                    fwhm0 = 5
                make_sn2 = False
                psfstars = 1
                catalog = lsc.__path__[0] + '/standard/cat/zero.cat'
            else:
                img_for_psf = img.replace('.fits', '')
                fwhm0 = option.fwhm
                make_sn2 = True
                psfstars = option.psfstars
                if not option.use_sextractor and not option.catalog:
                    for system in ['sloan', 'apass', 'landolt']:
                        catalog = lsc.util.getcatalog(img, system)
                        if catalog:
                            break
                else:
                    catalog = option.catalog
            while True:
                result, fwhm = lsc.lscpsfdef.ecpsf(img_for_psf, fwhm0, option.threshold, psfstars,
                                                   option.distance, option.interactive, psffun, fixaperture,
                                                   catalog, option.datamin, option.datamax, option.show, make_sn2)
                print '\n### ' + str(result)
                if option.show:
#                    lsc.util.marksn2(img + '.fits', img + '.sn2.fits', 1, '')
                    iraf.delete('tmp.psf.fit?', verify=False)
                    iraf.seepsf(img.replace('.fits', '.psf'), '_psf.psf')
                    iraf.surface('_psf.psf')
                    aa = raw_input('>>>good psf [[y]/n] ? ')
                    if not aa or aa.lower()[0] == 'y':
                        break
                    if aa.lower()[0] == 'n':
                        result = 0
                        bb = raw_input('If you want to try again, type the new FWHM to try here. Otherwise press enter to continue. ')
                        if bb: fwhm0 = float(bb)
                        else: break
                else:
                    break

            iraf.delete("tmp.*", verify="no")
            iraf.delete("_psf.*", verify="no")
            print  "********** Completed in ", int(time.time() - start_time), "sec"
            print result
            try:
                basename = os.path.basename(img)
                if result == 1:
                    lsc.mysqldef.updatevalue('photlco', 'psf', basename.replace('.fits', '.psf.fits'), basename)
                    lsc.mysqldef.updatevalue('photlco', 'fwhm', fwhm, basename)
                    lsc.mysqldef.updatevalue('photlco', 'mag', 9999, basename)
                    lsc.mysqldef.updatevalue('photlco', 'psfmag', 9999, basename)
                    lsc.mysqldef.updatevalue('photlco', 'apmag', 9999, basename)
                    if 'diff' not in img and os.path.isfile(img + '.diff.fits') and os.path.isfile(img + '.sn2.fits'):
                        # update diff info is file available
                        os.system('cp ' + img + '.sn2.fits ' + img + '.diff.sn2.fits')
                        lsc.mysqldef.updatevalue('photlco', 'psf', basename + '.psf.fits', basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'fwhm', fwhm, basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'mag', 9999, basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'psfmag', 9999, basename + '.diff.fits')
                        lsc.mysqldef.updatevalue('photlco', 'apmag', 9999, basename + '.diff.fits')
                else:
                    print 'psf not good, database not updated '
                    lsc.mysqldef.updatevalue('photlco', 'psf', 'X', basename + '.fits')
                    if os.path.isfile(img + '.diff.fits'):
                        lsc.mysqldef.updatevalue('photlco', 'psf', 'X', basename + '.diff.fits')
            except:
                print 'module mysqldef not found'

<|endoftext|>


<commit_before>from haystack.views import SearchView
import logging

logger = logging.getLogger(__name__)

class PersistentSearchView(SearchView):
    __name__ = "PersistentSearchView"

    def extra_context(self):
        """
        Save results to session
        """
        extra = super(PersistentSearchView, self).extra_context()

        if self.form.is_valid():
            self.request.session['search_query'] = self.form.cleaned_data
        if self.results:
            # Access the first result to prevent ZeroDivisionError
            self.results[0]
            self.request.session['search_results'] = self.results
            self.request.session['search_results_per_page'] = self.results_per_page
        return extra

<commit_msg>fix search<commit_after>from haystack.views import SearchView
import logging

logger = logging.getLogger(__name__)

class PersistentSearchView(SearchView):
    __name__ = "PersistentSearchView"

    def extra_context(self):
        """
        Save results to session
        """
        extra = super(PersistentSearchView, self).extra_context()

        if self.form.is_valid():
            self.request.session['search_query'] = self.form.cleaned_data
#        import ipdb; ipdb.set_trace()
        if self.results:
            # Access the first result to prevent ZeroDivisionError
            self.results[0]
        self.request.session['search_results'] = self.results
        self.request.session['search_results_per_page'] = self.results_per_page
        return extra

<|endoftext|>


<commit_before>
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import numpy as np
from ATEMWidget import ATEMWidget
from Canvas import Canvas
from GridWorker import GridWorker

class GridWidget(ATEMWidget):
    """docstring for GridWidget"""

    def __init__(self, parent):
        super(GridWidget, self).__init__(parent)
        self.parent = parent
        self.gridStore = {}
        self.init_grids()
        self.init_ui()

        self.absMinValue = 1e-20
        self.absMaxValue = 1e20

        self.show()

    def init_ui(self):
        """ Docstring """

        imshowOpts = {'origin':'lower',
                      'cmap':'jet',
                      'interpolation':'bilinear'}

        self.obsCanvas = Canvas(parent=self)
        obsToolbar = NavigationToolbar(self.obsCanvas, self, coordinates=False)
        self.obs_im = self.obsCanvas.axes.imshow([[0.]], **imshowOpts)
        self.selCrossXobs, = self.obsCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.selCrossYobs, = self.obsCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.obsCanvas.fig.colorbar(self.obs_im)
        self.obsCanvas.canvasClicked.connect(self.canvasClicked)

        self.predCanvas = Canvas(parent=self, share_ax=self.obsCanvas.axes)
        predToolbar = NavigationToolbar(self.predCanvas, self, coordinates=False)
        self.pred_im = self.predCanvas.axes.imshow([[0.]], **imshowOpts)
        self.selCrossXpred, = self.predCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.selCrossYpred, = self.predCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.predCanvas.fig.colorbar(self.pred_im)
        self.predCanvas.canvasClicked.connect(self.canvasClicked)

        self.highSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.highSlider.setMaximum(100)
        self.highSlider.setValue(100)
        self.highSlider.valueChanged.connect(self.setClim)

        self.lowSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.lowSlider.setMaximum(100)
        self.lowSlider.setValue(0)
        self.lowSlider.valueChanged.connect(self.setClim)

        lc1 = QtWidgets.QVBoxLayout()
        lc1.addWidget(self.obsCanvas)
        lc1.addWidget(obsToolbar)

        lc2 = QtWidgets.QVBoxLayout()
        lc2.addWidget(self.predCanvas)
        lc2.addWidget(predToolbar)

        lh = QtWidgets.QHBoxLayout()
        lh.addLayout(lc1)
        lh.addLayout(lc2)

        l = QtWidgets.QVBoxLayout(self)
        l.addLayout(lh)
        l.addWidget(self.highSlider)
        l.addWidget(self.lowSlider)

    def init_grids(self):

        self.gridWorker_Obs = GridWorker(self.parent.data, 'dBdt_Z')
        self.gridWorker_Obs.grdOpts['number_cells'] = 256
        self.gridWorker_Obs.finishedGrid.connect(self.storeGrid)
        self.gridWorker_Obs.start()

        self.gridWorker_Pred = GridWorker(self.parent.data, 'dBdt_Z_pred')
        self.gridWorker_Pred.grdOpts['number_cells'] = 256
        self.gridWorker_Pred.finishedGrid.connect(self.storeGrid)
        self.gridWorker_Pred.start()

    @QtCore.pyqtSlot(dict)
    def storeGrid(self, event):
        if not event['ch'] in self.gridStore:
            self.gridStore[event['ch']] = {}
        self.gridStore[event['ch']][event['tInd']] = event

    def draw(self):
        self.obsCanvas.draw()
        self.predCanvas.draw()

    @QtCore.pyqtSlot(dict)
    def canvasClicked(self, event):
        signal = {'name':'closestLoc',
                  'x':event['xdata'],
                  'y':event['ydata']}
        self.ChangeSelectionSignal.emit(signal)

    def setClim(self):
        lsVal = self.lowSlider.value()
        hsVal = self.highSlider.value()
        if lsVal >= hsVal:
            self.lowSlider.setValue(hsVal-1)
            lsVal = self.lowSlider.value()
        dv = self.absMaxValue-self.absMinValue
        clMin = self.absMinValue+dv*lsVal/100.
        clMax = self.absMinValue+dv*hsVal/100.
        self.obs_im.set_clim(clMin, clMax)
        self.pred_im.set_clim(clMin, clMax)
        self.draw()

    def setLocation(self, loc):
        """ Docstring """
        x = loc.iloc[0].x
        y = loc.iloc[0].y
        self.selCrossXobs.set_data(self.obsCanvas.axes.get_xlim(), [y, y])
        self.selCrossYobs.set_data([x, x], self.obsCanvas.axes.get_ylim())
        self.selCrossXpred.set_data(self.predCanvas.axes.get_xlim(), [y, y])
        self.selCrossYpred.set_data([x, x], self.predCanvas.axes.get_ylim())
        self.draw()

    def setTime(self, data_times):

        tInd = data_times.iloc[0].tInd

        if 'dBdt_Z' in self.gridStore:
            grid_obs = self.gridStore['dBdt_Z'][tInd]['grid']
            x_vector = self.gridStore['dBdt_Z'][tInd]['x_vector']
            y_vector = self.gridStore['dBdt_Z'][tInd]['y_vector']
            self.obs_im.set_data(grid_obs)
            self.obs_im.set_extent((x_vector[0], x_vector[-1],
                                    y_vector[0], y_vector[-1]))

            self.absMinValue = np.nanmin(grid_obs)
            self.absMaxValue = np.nanmax(grid_obs)

        if 'dBdt_Z_pred' in self.gridStore:
            grid_pred = self.gridStore['dBdt_Z_pred'][tInd]['grid']
            x_vector = self.gridStore['dBdt_Z_pred'][tInd]['x_vector']
            y_vector = self.gridStore['dBdt_Z_pred'][tInd]['y_vector']

            if np.any(grid_pred):
                self.pred_im.set_data(grid_pred)
                self.pred_im.set_extent((x_vector[0], x_vector[-1],
                                         y_vector[0], y_vector[-1]))
            else:
                self.pred_im.set_data(np.nan*np.ones((2, 2)))

        self.setClim()
        self.draw()
<commit_msg>Fixed bug that crashed ATEMview when no observed data loaded.<commit_after>
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import numpy as np
from ATEMWidget import ATEMWidget
from Canvas import Canvas
from GridWorker import GridWorker

class GridWidget(ATEMWidget):
    """docstring for GridWidget"""

    def __init__(self, parent):
        super(GridWidget, self).__init__(parent)
        self.parent = parent
        self.gridStore = {}
        self.init_grids()
        self.init_ui()

        self.absMinValue = 1e-20
        self.absMaxValue = 1e20

        self.show()

    def init_ui(self):
        """ Docstring """

        imshowOpts = {'origin':'lower',
                      'cmap':'jet',
                      'interpolation':'bilinear'}

        self.obsCanvas = Canvas(parent=self)
        obsToolbar = NavigationToolbar(self.obsCanvas, self, coordinates=False)
        self.obs_im = self.obsCanvas.axes.imshow([[0.]], **imshowOpts)
        self.selCrossXobs, = self.obsCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.selCrossYobs, = self.obsCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.obsCanvas.fig.colorbar(self.obs_im)
        self.obsCanvas.canvasClicked.connect(self.canvasClicked)

        self.predCanvas = Canvas(parent=self, share_ax=self.obsCanvas.axes)
        predToolbar = NavigationToolbar(self.predCanvas, self, coordinates=False)
        self.pred_im = self.predCanvas.axes.imshow([[0.]], **imshowOpts)
        self.selCrossXpred, = self.predCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.selCrossYpred, = self.predCanvas.axes.plot([], [], '--', c='r', lw=0.5, zorder=0)
        self.predCanvas.fig.colorbar(self.pred_im)
        self.predCanvas.canvasClicked.connect(self.canvasClicked)

        self.highSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.highSlider.setMaximum(100)
        self.highSlider.setValue(100)
        self.highSlider.valueChanged.connect(self.setClim)

        self.lowSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.lowSlider.setMaximum(100)
        self.lowSlider.setValue(0)
        self.lowSlider.valueChanged.connect(self.setClim)

        lc1 = QtWidgets.QVBoxLayout()
        lc1.addWidget(self.obsCanvas)
        lc1.addWidget(obsToolbar)

        lc2 = QtWidgets.QVBoxLayout()
        lc2.addWidget(self.predCanvas)
        lc2.addWidget(predToolbar)

        lh = QtWidgets.QHBoxLayout()
        lh.addLayout(lc1)
        lh.addLayout(lc2)

        l = QtWidgets.QVBoxLayout(self)
        l.addLayout(lh)
        l.addWidget(self.highSlider)
        l.addWidget(self.lowSlider)

    def init_grids(self):

        self.gridWorker_Obs = GridWorker(self.parent.data, 'dBdt_Z')
        self.gridWorker_Obs.grdOpts['number_cells'] = 256
        self.gridWorker_Obs.finishedGrid.connect(self.storeGrid)
        self.gridWorker_Obs.start()

        if self.parent.data.has_pred:
            self.gridWorker_Pred = GridWorker(self.parent.data, 'dBdt_Z_pred')
            self.gridWorker_Pred.grdOpts['number_cells'] = 256
            self.gridWorker_Pred.finishedGrid.connect(self.storeGrid)
            self.gridWorker_Pred.start()

    @QtCore.pyqtSlot(dict)
    def storeGrid(self, event):
        if not event['ch'] in self.gridStore:
            self.gridStore[event['ch']] = {}
        self.gridStore[event['ch']][event['tInd']] = event

    def draw(self):
        self.obsCanvas.draw()
        self.predCanvas.draw()

    @QtCore.pyqtSlot(dict)
    def canvasClicked(self, event):
        signal = {'name':'closestLoc',
                  'x':event['xdata'],
                  'y':event['ydata']}
        self.ChangeSelectionSignal.emit(signal)

    def setClim(self):
        lsVal = self.lowSlider.value()
        hsVal = self.highSlider.value()
        if lsVal >= hsVal:
            self.lowSlider.setValue(hsVal-1)
            lsVal = self.lowSlider.value()
        dv = self.absMaxValue-self.absMinValue
        clMin = self.absMinValue+dv*lsVal/100.
        clMax = self.absMinValue+dv*hsVal/100.
        self.obs_im.set_clim(clMin, clMax)
        self.pred_im.set_clim(clMin, clMax)
        self.draw()

    def setLocation(self, loc):
        """ Docstring """
        x = loc.iloc[0].x
        y = loc.iloc[0].y
        self.selCrossXobs.set_data(self.obsCanvas.axes.get_xlim(), [y, y])
        self.selCrossYobs.set_data([x, x], self.obsCanvas.axes.get_ylim())
        self.selCrossXpred.set_data(self.predCanvas.axes.get_xlim(), [y, y])
        self.selCrossYpred.set_data([x, x], self.predCanvas.axes.get_ylim())
        self.draw()

    def setTime(self, data_times):

        tInd = data_times.iloc[0].tInd

        if 'dBdt_Z' in self.gridStore:
            grid_obs = self.gridStore['dBdt_Z'][tInd]['grid']
            x_vector = self.gridStore['dBdt_Z'][tInd]['x_vector']
            y_vector = self.gridStore['dBdt_Z'][tInd]['y_vector']
            self.obs_im.set_data(grid_obs)
            self.obs_im.set_extent((x_vector[0], x_vector[-1],
                                    y_vector[0], y_vector[-1]))

            self.absMinValue = np.nanmin(grid_obs)
            self.absMaxValue = np.nanmax(grid_obs)

        if 'dBdt_Z_pred' in self.gridStore:
            grid_pred = self.gridStore['dBdt_Z_pred'][tInd]['grid']
            x_vector = self.gridStore['dBdt_Z_pred'][tInd]['x_vector']
            y_vector = self.gridStore['dBdt_Z_pred'][tInd]['y_vector']

            if np.any(grid_pred):
                self.pred_im.set_data(grid_pred)
                self.pred_im.set_extent((x_vector[0], x_vector[-1],
                                         y_vector[0], y_vector[-1]))
            else:
                self.pred_im.set_data(np.nan*np.ones((2, 2)))

        self.setClim()
        self.draw()
<|endoftext|>


<commit_before>import sys
import posixpath
import collections

from . import codegen
from .. import const, parse

class Compiler:

    @classmethod
    # Compile a parser output tree into an immutable code object.
    #
    # :param into_codeobj: a temporary mutable code object to use.
    #
    def compile(cls, expr, into=None, name='<module>', qualname='', hook=lambda self: 0):

        self = cls()
        self.assigned_to    = None
        self.qualified_name = qualname
        self.code = codegen.MutableCode() if into is None else into
        self.code.filename = expr.location.filename
        self.code.lineno   = expr.location.start[1]
        hook(self)
        self.opcode('RETURN_VALUE', expr, delta=0)
        return self.code.compile(name)

    def name(self, default, qname=''):

        name = default if self.assigned_to is None else repr(self.assigned_to)
        return qname + (qname and '.') + ('<{}>' if ' ' in name else '{}') .format(name)

    # Push the results of some expressions onto the stack.
    #
    # NOTE `load(a=b)` loads string `'a'`, then the result of `b`.
    # NOTE `load`ing an expression multiple times evaluates it multiple times.
    #   Use `DUP_TOP` opcode when necessary.
    #
    def load(self, *es, **kws):

        for e in es:

            hasattr(e, 'location') and self.code.mark(e)

            if isinstance(e, parse.tree.Expression):

                self.call(*e)

            elif isinstance(e, parse.tree.Link):

                self.opcode(
                    'LOAD_DEREF' if e in self.code.cellvars  else
                    'LOAD_FAST'  if e in self.code.varnames  else
                    'LOAD_DEREF' if e in self.code.cellnames else
                    'LOAD_NAME'  if self.code.slowlocals     else
                    'LOAD_GLOBAL', arg=e, delta=1
                )

            elif isinstance(e, parse.tree.Constant):

                self.opcode('LOAD_CONST', arg=e.value, delta=1)

            else:

                self.opcode('LOAD_CONST', arg=e, delta=1)

        for k, v in kws.items():

            self.load(str(k), v)

    # Append a single opcode with some non-integer arguments.
    #
    # :param args: objects to pass to :meth:`load`.
    #
    # :param delta: how much items the opcode will pop **excluding :obj:`args`**
    #
    # :param arg: the argument to that opcode, defaults to `len(args)`.
    #
    def opcode(self, opcode, *args, delta, **kwargs):

        self.load(*args)
        return self.code.append(opcode, kwargs.get('arg', len(args)), -len(args) + delta)

    # Store whatever is on top of the stack in a variable.
    #
    # :param dup: whether to leave the stored object on the stack afterwards.
    #
    # Supported name schemes::
    #
    #   name = ...              | variable assignment
    #   object.name = ...       | object.__setattr__('name', ...)
    #   object !! object = ...  | object.__setitem__(object, ...)
    #   scheme, ... = ...       | recursive iterable unpacking
    #
    def store_top(self, var, dup=True):

        dup and self.opcode('DUP_TOP', delta=1)

        type, var, args = parse.syntax.assignment_target(var)

        if type == const.AT.UNPACK:

            ln, star = args
            op  = 'UNPACK_SEQUENCE' if star < 0 else 'UNPACK_EX'
            arg = ln                if star < 0 else star + 256 * (ln - star - 1)
            self.opcode(op, arg=arg, delta=ln - 1)

            for item in var:

                self.store_top(item, dup=False)

        elif type == const.AT.ATTR:

            self.opcode('STORE_ATTR', args, arg=var, delta=-1)

        elif type == const.AT.ITEM:

            self.opcode('STORE_SUBSCR', args, var, delta=-1)

        else:

            var in self.builtins   and parse.syntax.error(const.ERR.BUILTIN_ASSIGNMENT, var)
          # var in self.fake_attrs and parse.syntax.error(const.ERR.BUILTIN_ASSIGNMENT, var)

            self.opcode(
                'STORE_DEREF' if var in self.code.cellnames else
                'STORE_DEREF' if var in self.code.cellvars else
                'STORE_NAME'  if self.code.slowlocals else
                'STORE_FAST', arg=var, delta=-1
            )

    # Create a function from a given immutable code object and default arguments.
    #
    # Note that this completely freezes its `cellnames`, meaning that
    # all variables created after the code object will be ignored
    # by the closed function.
    #
    def make_function(self, code, defaults, kwdefaults):

        self.load(**kwdefaults)
        self.load(*defaults)

        if code.co_freevars:

            for freevar in code.co_freevars:

                self.opcode('LOAD_CLOSURE', arg=self.code.cellify(freevar), delta=1)

            self.opcode('BUILD_TUPLE', arg=len(code.co_freevars), delta=-len(code.co_freevars) + 1)

        self.opcode(
            'MAKE_CLOSURE' if code.co_freevars else 'MAKE_FUNCTION', code,
            # Python <  3.3: MAKE_FUNCTION(code)
            # Python >= 3.3: MAKE_FUNCTION(code, qualname)
            *[self.name(code.co_name, self.qualified_name)] if sys.hexversion >= 0x03030000 else [],
            arg  =    len(defaults) + 256 * len(kwdefaults),
            delta=1 - len(defaults) -   2 * len(kwdefaults) - bool(code.co_freevars)
        )

    # Load an attribute given its name.
    #
    # Default behavior is to use LOAD_ATTR(name).
    # Built-in functions may override that.
    #
    def ldattr(self, name):

        isinstance(name, parse.tree.Link) or parse.syntax.error(const.ERR.NONCONST_ATTR, name)
        self.fake_attrs[name](self) if name in self.fake_attrs else \
        self.opcode('LOAD_ATTR', arg=name, delta=0)

    def nativecall(self, args, preloaded, infix=False):

        defs  = args, None, None, {}, (), ()
        args, _, _, kwargs, vararg, varkwarg = defs if infix else parse.syntax.argspec(args, definition=False)

        self.load(*args, **kwargs)
        self.opcode(
            'CALL_FUNCTION' + ('_VAR' if vararg else '') + ('_KW' if varkwarg else ''),
            *vararg + varkwarg,
            arg  = len(args) + 256 * len(kwargs) + preloaded,
            delta=-len(args) -   2 * len(kwargs) - preloaded
        )

    def loadcall(self, args):

        self.load(*args) if len(args) < 2 else self.call(*args)

    # Left-bind `f` with `arg`.
    #
    # Same as `bind f arg`.
    #
    def infixbindl(self, f, arg):

        self.opcode('CALL_FUNCTION', parse.tree.Link('bind'), f, arg, arg=2, delta=-1)

    # Right-bind `f` with `args`.
    #
    # No direct equivalent; `R a b c` means `infixbindr(R, a, b, c)`
    # and is interpreted as `R (a b c)` by default.
    #
    def infixbindr(self, f, *args):

        self.load(parse.tree.Link('bind'))
        self.opcode('CALL_FUNCTION', parse.tree.Link('flip'), f, arg=1, delta=1)
        self.loadcall(args)
        self.opcode('CALL_FUNCTION', arg=2, delta=-1)

  ### ESSENTIAL BUILT-INS

    #
    # function argument ... keyword: value *: varargs **: varkwargs
    #
    # Call a (possibly built-in) function.
    #
    def call(self, f, *args, rightbind=False):

        if f.infix and f == '':  # empty link can't be closed

            (f, *args), rightbind = args, True

        if f.infix and not f.closed and (rightbind or len(args) == 1):

            self.bind_hooks[rightbind][f](self, f, *args)

        elif isinstance(f, parse.tree.Link) and f in self.builtins:

            self.builtins[f](self, *args)

        else:

            self.load(f)
            self.nativecall(args, 0, f.infix and not f.closed)

    #
    # name = expression
    #
    # Store the result of `expression` in `name`.
    # If `expression` is `import`, attempt to derive the module name
    # from `name`.
    #
    def store(self, var, expr):

        e = self.assigned_to
        self.assigned_to = var
        self.load(expr)
        self.assigned_to = e
        self.store_top(var)

    #
    # argspec -> body
    #
    # Create a function with a given argument specification
    # that evaluates its body on call.
    #
    # `argspec` may be empty (i.e. `Constant(None)`.)
    #
    def function(self, args, body):

        args, kwargs, defs, kwdefs, varargs, varkwargs = parse.syntax.argspec(args, definition=True)
        argnames, targets = [], {}

        for index, arg in enumerate(args):

            if isinstance(arg, parse.tree.Link) and arg not in argnames:

                argnames.append(arg)

            else:

                argnames.append('pattern-{}'.format(index))
                targets['pattern-{}'.format(index)] = arg

        def hook(self):

            for name, pattern in targets.items():

                self.opcode('LOAD_FAST', arg=name, delta=1)
                self.store_top(pattern, dup=False)

        code = codegen.MutableCode(True, argnames, kwargs, varargs, varkwargs, self.code)
        code = self.compile(body, code, self.name('<lambda>'), self.name('<lambda>', self.qualified_name) + '.<locals>', hook)
        self.make_function(code, defs, kwdefs)

    #
    # object.attribute
    #
    # Retrieve an attribute of some object.
    #
    def getattr(self, a, b):

        self.load(a)
        self.ldattr(b)

    #
    # expression_1 (insert line break here) expression_2
    #
    # Evaluate some expressions in a strict order, return the value of the last one.
    #
    def chain(self, a, *bs):

        self.load(a)

        for b in bs:

            self.opcode('POP_TOP', delta=-1)
            self.load(b)

    #
    # import '/global_module'
    # import '/global_module/with_submodule' qualified
    # import 'relative_module'
    # import '../relative_module_in_parent_package'
    #
    # Import a module given a POSIX-style path.
    # Normally, this function works as `from ... import ...` in Python;
    # however, supplying "qualified" keyword after a module name makes it
    # work like a simple `import`. (This only affects paths with multiple slashes.)
    #
    def import_(self, name, qualified=None):

        isinstance(name, parse.tree.Constant) or parse.syntax.error('should be constant', name)
        isinstance(name.value, str) or parse.syntax.error('should be a string', name)

        qualified in (None, 'qualified') or parse.syntax.error('"qualified"', name)

        path = posixpath.normpath(name.value).split(posixpath.sep)

        parent = 1

        while path and not path[0]:

            path.pop(0)
            parent = 0

        while path and path[0] == posixpath.curdir:

            path.pop(0)

        while path and path[0] == posixpath.pardir:

            path.pop(0)
            parent += 1

        path or parse.syntax.error('no module name', name)

        if qualified:

            parent and parse.syntax.error('cannot perform qualified relative imports', qualified)
            self.opcode('IMPORT_NAME', 0, None, arg='.'.join(path), delta=1)
            self.store_top(parse.tree.Link(path[0]).before(name))

        else:

            *mod, mname = path
            self.opcode('IMPORT_NAME', parent, (mname,) if mod else None, arg='.'.join(mod) or mname, delta=-1)
            mod and self.opcode('IMPORT_FROM', arg=mname, delta=1)
            self.store_top(parse.tree.Link(mname).before(name))
            mod and self.opcode('ROT_TWO', delta=0)
            mod and self.opcode('POP_TOP', delta=-1)

    builtins = {
        '':   call
      , '=':  store
      , '.':  getattr
      , '\n': chain
      , '->': function
      , 'import': import_
    }

    fake_attrs = {}
    bind_hooks = {
        False: collections.defaultdict(lambda: Compiler.infixbindl)
      , True:  collections.defaultdict(lambda: Compiler.infixbindr)
    }
<commit_msg>Fix a couple of comments.<commit_after>import sys
import posixpath
import collections

from . import codegen
from .. import const, parse

class Compiler:

    @classmethod
    # Compile a parser output tree into an immutable code object.
    #
    # :param into: a temporary mutable code object to use.
    #
    def compile(cls, expr, into=None, name='<module>', qualname='', hook=lambda self: 0):

        self = cls()
        self.assigned_to    = None
        self.qualified_name = qualname
        self.code = codegen.MutableCode() if into is None else into
        self.code.filename = expr.location.filename
        self.code.lineno   = expr.location.start[1]
        hook(self)
        self.opcode('RETURN_VALUE', expr, delta=0)
        return self.code.compile(name)

    def name(self, default, qname=''):

        name = default if self.assigned_to is None else repr(self.assigned_to)
        return qname + (qname and '.') + ('<{}>' if ' ' in name else '{}') .format(name)

    # Push the results of some expressions onto the stack.
    #
    # NOTE `load(a=b)` loads string `'a'`, then the result of `b`.
    # NOTE `load`ing an expression multiple times evaluates it multiple times.
    #   Use `DUP_TOP` opcode when necessary.
    #
    def load(self, *es, **kws):

        for e in es:

            hasattr(e, 'location') and self.code.mark(e)

            if isinstance(e, parse.tree.Expression):

                self.call(*e)

            elif isinstance(e, parse.tree.Link):

                self.opcode(
                    'LOAD_DEREF' if e in self.code.cellvars  else
                    'LOAD_FAST'  if e in self.code.varnames  else
                    'LOAD_DEREF' if e in self.code.cellnames else
                    'LOAD_NAME'  if self.code.slowlocals     else
                    'LOAD_GLOBAL', arg=e, delta=1
                )

            elif isinstance(e, parse.tree.Constant):

                self.opcode('LOAD_CONST', arg=e.value, delta=1)

            else:

                self.opcode('LOAD_CONST', arg=e, delta=1)

        for k, v in kws.items():

            self.load(str(k), v)

    # Append a single opcode with some non-integer arguments.
    #
    # :param args: objects to pass to :meth:`load`.
    #
    # :param delta: how much items the opcode will pop **excluding :obj:`args`**
    #
    # :param arg: the argument to that opcode, defaults to `len(args)`.
    #
    def opcode(self, opcode, *args, delta, **kwargs):

        self.load(*args)
        return self.code.append(opcode, kwargs.get('arg', len(args)), -len(args) + delta)

    # Store whatever is on top of the stack in a variable.
    #
    # :param dup: whether to leave the stored object on the stack afterwards.
    #
    # Supported name schemes::
    #
    #   name = ...              | variable assignment
    #   object.name = ...       | object.__setattr__('name', ...)
    #   object !! object = ...  | object.__setitem__(object, ...)
    #   scheme, ... = ...       | recursive iterable unpacking
    #
    def store_top(self, var, dup=True):

        dup and self.opcode('DUP_TOP', delta=1)

        type, var, args = parse.syntax.assignment_target(var)

        if type == const.AT.UNPACK:

            ln, star = args
            op  = 'UNPACK_SEQUENCE' if star < 0 else 'UNPACK_EX'
            arg = ln                if star < 0 else star + 256 * (ln - star - 1)
            self.opcode(op, arg=arg, delta=ln - 1)

            for item in var:

                self.store_top(item, dup=False)

        elif type == const.AT.ATTR:

            self.opcode('STORE_ATTR', args, arg=var, delta=-1)

        elif type == const.AT.ITEM:

            self.opcode('STORE_SUBSCR', args, var, delta=-1)

        else:

            var in self.builtins   and parse.syntax.error(const.ERR.BUILTIN_ASSIGNMENT, var)
          # var in self.fake_attrs and parse.syntax.error(const.ERR.BUILTIN_ASSIGNMENT, var)

            self.opcode(
                'STORE_DEREF' if var in self.code.cellnames else
                'STORE_DEREF' if var in self.code.cellvars else
                'STORE_NAME'  if self.code.slowlocals else
                'STORE_FAST', arg=var, delta=-1
            )

    # Create a function from a given immutable code object and default arguments.
    #
    # Note that this completely freezes its `cellnames`, meaning that
    # all variables created after the code object will be ignored
    # by the closed function.
    #
    def make_function(self, code, defaults, kwdefaults):

        self.load(**kwdefaults)
        self.load(*defaults)

        if code.co_freevars:

            for freevar in code.co_freevars:

                self.opcode('LOAD_CLOSURE', arg=self.code.cellify(freevar), delta=1)

            self.opcode('BUILD_TUPLE', arg=len(code.co_freevars), delta=-len(code.co_freevars) + 1)

        self.opcode(
            'MAKE_CLOSURE' if code.co_freevars else 'MAKE_FUNCTION', code,
            # Python <  3.3: MAKE_FUNCTION(code)
            # Python >= 3.3: MAKE_FUNCTION(code, qualname)
            *[self.name(code.co_name, self.qualified_name)] if sys.hexversion >= 0x03030000 else [],
            arg  =    len(defaults) + 256 * len(kwdefaults),
            delta=1 - len(defaults) -   2 * len(kwdefaults) - bool(code.co_freevars)
        )

    # Load an attribute given its name.
    #
    # Default behavior is to use LOAD_ATTR(name).
    # Built-in functions may override that.
    #
    def ldattr(self, name):

        isinstance(name, parse.tree.Link) or parse.syntax.error(const.ERR.NONCONST_ATTR, name)
        self.fake_attrs[name](self) if name in self.fake_attrs else \
        self.opcode('LOAD_ATTR', arg=name, delta=0)

    def nativecall(self, args, preloaded, infix=False):

        defs  = args, None, None, {}, (), ()
        args, _, _, kwargs, vararg, varkwarg = defs if infix else parse.syntax.argspec(args, definition=False)

        self.load(*args, **kwargs)
        self.opcode(
            'CALL_FUNCTION' + ('_VAR' if vararg else '') + ('_KW' if varkwarg else ''),
            *vararg + varkwarg,
            arg  = len(args) + 256 * len(kwargs) + preloaded,
            delta=-len(args) -   2 * len(kwargs) - preloaded
        )

    def loadcall(self, args):

        self.load(*args) if len(args) < 2 else self.call(*args)

    # Left-bind `f` with `arg`.
    #
    # Same as `bind f arg`.
    #
    def infixbindl(self, f, arg):

        self.opcode('CALL_FUNCTION', parse.tree.Link('bind'), f, arg, arg=2, delta=-1)

    # Right-bind `f` with `args`.
    #
    # No direct equivalent; `R a b c` means `infixbindr(R, a, b, c)`
    # and is interpreted as `R (a b c)` by default.
    #
    def infixbindr(self, f, *args):

        self.load(parse.tree.Link('bind'))
        self.opcode('CALL_FUNCTION', parse.tree.Link('flip'), f, arg=1, delta=1)
        self.loadcall(args)
        self.opcode('CALL_FUNCTION', arg=2, delta=-1)

  ### ESSENTIAL BUILT-INS

    #
    # function argument ... keyword: value *: varargs **: varkwargs
    #
    # Call a (possibly built-in) function.
    #
    def call(self, f, *args, rightbind=False):

        if f.infix and f == '':  # empty link can't be closed

            (f, *args), rightbind = args, True

        if f.infix and not f.closed and (rightbind or len(args) == 1):

            self.bind_hooks[rightbind][f](self, f, *args)

        elif isinstance(f, parse.tree.Link) and f in self.builtins:

            self.builtins[f](self, *args)

        else:

            self.load(f)
            self.nativecall(args, 0, f.infix and not f.closed)

    #
    # name = expression
    #
    # Store the result of `expression` in `name`.
    #
    def store(self, var, expr):

        e = self.assigned_to
        self.assigned_to = var
        self.load(expr)
        self.assigned_to = e
        self.store_top(var)

    #
    # argspec -> body
    #
    # Create a function with a given argument specification
    # that evaluates its body on call.
    #
    # `argspec` may be empty (i.e. `Constant(None)`.)
    #
    def function(self, args, body):

        args, kwargs, defs, kwdefs, varargs, varkwargs = parse.syntax.argspec(args, definition=True)
        argnames, targets = [], {}

        for index, arg in enumerate(args):

            if isinstance(arg, parse.tree.Link) and arg not in argnames:

                argnames.append(arg)

            else:

                argnames.append('pattern-{}'.format(index))
                targets['pattern-{}'.format(index)] = arg

        def hook(self):

            for name, pattern in targets.items():

                self.opcode('LOAD_FAST', arg=name, delta=1)
                self.store_top(pattern, dup=False)

        code = codegen.MutableCode(True, argnames, kwargs, varargs, varkwargs, self.code)
        code = self.compile(body, code, self.name('<lambda>'), self.name('<lambda>', self.qualified_name) + '.<locals>', hook)
        self.make_function(code, defs, kwdefs)

    #
    # object.attribute
    #
    # Retrieve an attribute of some object.
    #
    def getattr(self, a, b):

        self.load(a)
        self.ldattr(b)

    #
    # expression_1 (insert line break here) expression_2
    #
    # Evaluate some expressions in a strict order, return the value of the last one.
    #
    def chain(self, a, *bs):

        self.load(a)

        for b in bs:

            self.opcode('POP_TOP', delta=-1)
            self.load(b)

    #
    # import '/global_module'
    # import '/global_module/with_submodule' qualified
    # import 'relative_module'
    # import '../relative_module_in_parent_package'
    #
    # Import a module given a POSIX-style path.
    # Normally, this function works as `from ... import ...` in Python;
    # however, supplying "qualified" keyword after a module name makes it
    # work like a simple `import`. (This only affects paths with multiple slashes.)
    #
    def import_(self, name, qualified=None):

        isinstance(name, parse.tree.Constant) or parse.syntax.error('should be constant', name)
        isinstance(name.value, str) or parse.syntax.error('should be a string', name)

        qualified in (None, 'qualified') or parse.syntax.error('"qualified"', name)

        path = posixpath.normpath(name.value).split(posixpath.sep)

        parent = 1

        while path and not path[0]:

            path.pop(0)
            parent = 0

        while path and path[0] == posixpath.curdir:

            path.pop(0)

        while path and path[0] == posixpath.pardir:

            path.pop(0)
            parent += 1

        path or parse.syntax.error('no module name', name)

        if qualified:

            parent and parse.syntax.error('cannot perform qualified relative imports', qualified)
            self.opcode('IMPORT_NAME', 0, None, arg='.'.join(path), delta=1)
            self.store_top(parse.tree.Link(path[0]).before(name))

        else:

            *mod, mname = path
            self.opcode('IMPORT_NAME', parent, (mname,) if mod else None, arg='.'.join(mod) or mname, delta=-1)
            mod and self.opcode('IMPORT_FROM', arg=mname, delta=1)
            self.store_top(parse.tree.Link(mname).before(name))
            mod and self.opcode('ROT_TWO', delta=0)
            mod and self.opcode('POP_TOP', delta=-1)

    builtins = {
        '':   call
      , '=':  store
      , '.':  getattr
      , '\n': chain
      , '->': function
      , 'import': import_
    }

    fake_attrs = {}
    bind_hooks = {
        False: collections.defaultdict(lambda: Compiler.infixbindl)
      , True:  collections.defaultdict(lambda: Compiler.infixbindr)
    }
<|endoftext|>


<commit_before><commit_msg>an here we know when the ehart beats  - ahumpa bump bump<commit_after><|endoftext|>


<commit_before><commit_msg>SQLAlchemy 0.7's column.foreign_keys is a set and has no _list (addresses #112)<commit_after><|endoftext|>


<commit_before><commit_msg>fix: outputspec<commit_after><|endoftext|>