def __new__(metatype, name, bases, namespace): asis = namespace.pop('__asis__', False) if asis: resource = type.__new__(metatype, name, bases, namespace) associate_resource_version(resource) return resource base_class = None if namespace.get('abstract', False): base_class = bases[0] if len(bases) > 1 or base_class.name is not None: raise SpecificationError('abstract resource %r may only inherit from a single' ' abstract base resource' % name) else: for candidate in bases: if getattr(candidate, 'abstract', False): continue elif base_class is None: base_class = candidate else: raise SpecificationError('concrete resource %r must inherit from only one' 'concrete resource' % name) if not base_class: raise SpecificationError('resource %r must inherit from exactly one non-abstract ' 'base resource' % name) configuration = getattr(base_class, 'configuration', None) if not configuration: configuration = namespace.get('configuration', None) if not configuration: return type.__new__(metatype, name, (base_class,), namespace) elif not isinstance(configuration, Configuration): raise SpecificationError('invalid configuration') schema = namespace.pop('schema', {}) if isinstance(schema, (type, ClassType)): schema = pull_class_dict(schema) if not isinstance(schema, dict): raise SpecificationError('resource %r has an invalid schema' % name) removed_fields = set() for attr in schema.keys(): if isinstance(schema[attr], Field): schema[attr].name = attr else: if schema[attr] is None: removed_fields.add(attr) del schema[attr] requested_requests = namespace.pop('requests', None) if isinstance(requested_requests, basestring): requested_requests = requested_requests.split(' ') if requested_requests is None: requested_requests = configuration.default_requests declared_requests = {} removed_attrs = set() for attr in namespace.keys(): if attr not in metatype.ATTRS and not attr.startswith('_'): if isinstance(namespace[attr], (type, ClassType)): declared_requests[attr] = namespace.pop(attr) elif namespace[attr] is None: removed_attrs.add(attr) namespace.pop(attr) resource = type.__new__(metatype, name, (base_class,), namespace) if resource.version is not None: if not (isinstance(resource.version, int) and resource.version >= 1): raise SpecificationError('resource %r declares an invalid version' % name) resource.requests = {} resource.schema = {} resource.subresources = {} resource.validators = {} inherited_requests = set() for base in reversed(bases): if hasattr(base, 'schema'): resource.schema.update(base.schema) resource.subresources.update(base.subresources) resource.validators.update(base.validators) for name, request in base.requests.iteritems(): inherited_requests.add(request) resource.requests[name] = request resource.schema.update(schema) for name in removed_fields: if name in resource.schema: del resource.schema[name] if isinstance(resource.composite_key, basestring): resource.composite_key = resource.composite_key.split(' ') id_field = configuration.id_field if id_field.name in resource.schema: resource.schema[id_field.name].is_identifier = True elif id_field.name not in removed_fields: resource.schema[id_field.name] = id_field.clone(is_identifier=True) resource.id_field = resource.schema.get(id_field.name) for name, request in declared_requests.iteritems(): resource.requests[name] = Request.construct(resource, request) for attr, value in namespace.iteritems(): if isinstance(value, Subresource): value.name = attr resource.subresources[attr] = value elif isinstance(value, classmethod): value = getattr(resource, attr) if getattr(value, '__validates__', False): resource.validators[value.__name__] = value delattr(resource, value.__name__) resource.description = dedent(resource.__doc__ or '') if resource.name is None: associate_resource_version(resource) return resource if requested_requests: for name in requested_requests: constructor = configuration.standard_requests.get(name) if constructor: request = resource.requests.get(name) if request and request in inherited_requests and request.auto_constructed: request = None if not request: request = constructor(resource) if request: resource.requests[name] = request else: raise SpecificationError('resource %r requests unknown standard request %r' % (resource.name, name)) for collection in (resource.requests, resource.validators): for name in collection.keys(): if name in removed_attrs: del collection[name] for validator in resource.validators.itervalues(): if validator.requests is None: set_function_attr(validator, 'requests', configuration.validated_requests) for request_name in validator.requests: if request_name in resource.requests: resource.requests[request_name].validators.append(validator) associate_resource_version(resource) return resource
def __new__(metatype, name, bases, namespace): candidates = [getattr(base, 'configuration', None) for base in bases] candidates.append(namespace.get('configuration', None)) configuration = None for candidate in candidates: if isinstance(candidate, Configuration): if not configuration or candidate == configuration: configuration = candidate else: raise SpecificationError('conflicting mesh configurations') if not configuration: return type.__new__(metatype, name, bases, namespace) schema = namespace.pop('schema', {}) if isinstance(schema, (type, ClassType)): schema = pull_class_dict(schema) if not isinstance(schema, dict): raise SpecificationError('resource %r has an invalid schema' % name) removed_fields = set() for attr in schema.keys(): if isinstance(schema[attr], Field): schema[attr].name = attr else: if schema[attr] is None: removed_fields.add(attr) del schema[attr] requested_requests = namespace.pop('requests', None) if isinstance(requested_requests, basestring): requested_requests = requested_requests.split(' ') if requested_requests is None: requested_requests = configuration.standard_requests.keys() declared_requests = {} removed_attrs = set() for attr in namespace.keys(): if attr not in metatype.ATTRS and not attr.startswith('_'): if isinstance(namespace[attr], (type, ClassType)): declared_requests[attr] = namespace.pop(attr) elif namespace[attr] is None: removed_attrs.add(attr) namespace.pop(attr) resource = type.__new__(metatype, name, bases, namespace) if resource.name is not None: if not (isinstance(resource.version, int) and resource.version >= 1): raise SpecificationError('resource %r declares an invalid version' % name) elif resource.version is not None: raise SpecificationError('abstract resource %r must not declare a version' % name) resource.requests = {} resource.schema = {} resource.validators = {} inherited_requests = set() for base in reversed(bases): if hasattr(base, 'schema'): resource.schema.update(base.schema) resource.validators.update(base.validators) for name, request in base.requests.iteritems(): inherited_requests.add(request) resource.requests[name] = request resource.schema.update(schema) for name in removed_fields: if name in resource.schema: del resource.schema[name] id_field = configuration.id_field if id_field.name in resource.schema: resource.schema[id_field.name].is_identifier = True else: resource.schema[id_field.name] = id_field.clone(is_identifier=True) resource.id_field = resource.schema[id_field.name] for name, request in declared_requests.iteritems(): resource.requests[name] = Request.construct(resource, request) for attr, value in namespace.iteritems(): if isinstance(value, classmethod): value = getattr(resource, attr) if getattr(value, '__validates__', False): resource.validators[value.__name__] = value delattr(resource, value.__name__) resource.description = dedent(resource.__doc__ or '') if resource.name is None: return resource if requested_requests: for name in requested_requests: constructor = configuration.standard_requests.get(name) if constructor: request = resource.requests.get(name) if request and request in inherited_requests and request.auto_constructed: request = None if not request: request = constructor(resource) if request: resource.requests[name] = request else: raise SpecificationError('resource %r requests unknown standard request %r' % (resource.name, name)) for collection in (resource.requests, resource.validators): for name in collection.keys(): if name in removed_attrs: del collection[name] for validator in resource.validators.itervalues(): if validator.requests is None: set_function_attr(validator, 'requests', configuration.validated_requests) for request_name in validator.requests: if request_name in resource.requests: resource.requests[request_name].validators.append(validator) versions = getattr(resource, 'versions', None) if versions is None: versions = resource.versions = {} if resource.version in versions: raise SpecificationError('duplicate version') versions[resource.version] = resource return resource
def __new__(metatype, name, bases, namespace): candidates = [getattr(base, 'configuration', None) for base in bases] candidates.append(namespace.get('configuration', None)) configuration = None for candidate in candidates: if isinstance(candidate, Configuration): if not configuration or candidate == configuration: configuration = candidate else: raise SpecificationError('conflicting mesh configurations') if not configuration: return type.__new__(metatype, name, bases, namespace) schema = namespace.pop('schema', {}) if isinstance(schema, (type, ClassType)): schema = pull_class_dict(schema) if not isinstance(schema, dict): raise SpecificationError('resource %r has an invalid schema' % name) removed_fields = set() for attr in schema.keys(): if isinstance(schema[attr], Field): schema[attr].name = attr else: if schema[attr] is None: removed_fields.add(attr) del schema[attr] requested_requests = namespace.pop('requests', None) if isinstance(requested_requests, basestring): requested_requests = requested_requests.split(' ') if requested_requests is None: requested_requests = configuration.standard_requests.keys() declared_requests = {} removed_attrs = set() for attr in namespace.keys(): if attr not in metatype.ATTRS and not attr.startswith('_'): if isinstance(namespace[attr], (type, ClassType)): declared_requests[attr] = namespace.pop(attr) elif namespace[attr] is None: removed_attrs.add(attr) namespace.pop(attr) resource = type.__new__(metatype, name, bases, namespace) if resource.name is not None: if not (isinstance(resource.version, int) and resource.version >= 1): raise SpecificationError( 'resource %r declares an invalid version' % name) elif resource.version is not None: raise SpecificationError( 'abstract resource %r must not declare a version' % name) resource.requests = {} resource.schema = {} resource.validators = {} inherited_requests = set() for base in reversed(bases): if hasattr(base, 'schema'): resource.schema.update(base.schema) resource.validators.update(base.validators) for name, request in base.requests.iteritems(): inherited_requests.add(request) resource.requests[name] = request resource.schema.update(schema) for name in removed_fields: if name in resource.schema: del resource.schema[name] id_field = configuration.id_field if id_field.name in resource.schema: resource.schema[id_field.name].is_identifier = True else: resource.schema[id_field.name] = id_field.clone(is_identifier=True) resource.id_field = resource.schema[id_field.name] for name, request in declared_requests.iteritems(): resource.requests[name] = Request.construct(resource, request) for attr, value in namespace.iteritems(): if isinstance(value, classmethod): value = getattr(resource, attr) if getattr(value, '__validates__', False): resource.validators[value.__name__] = value delattr(resource, value.__name__) resource.description = dedent(resource.__doc__ or '') if resource.name is None: return resource if requested_requests: for name in requested_requests: constructor = configuration.standard_requests.get(name) if constructor: request = resource.requests.get(name) if request and request in inherited_requests and request.auto_constructed: request = None if not request: request = constructor(resource) if request: resource.requests[name] = request else: raise SpecificationError( 'resource %r requests unknown standard request %r' % (resource.name, name)) for collection in (resource.requests, resource.validators): for name in collection.keys(): if name in removed_attrs: del collection[name] for validator in resource.validators.itervalues(): if validator.requests is None: set_function_attr(validator, 'requests', configuration.validated_requests) for request_name in validator.requests: if request_name in resource.requests: resource.requests[request_name].validators.append( validator) versions = getattr(resource, 'versions', None) if versions is None: versions = resource.versions = {} if resource.version in versions: raise SpecificationError('duplicate version') versions[resource.version] = resource return resource