示例#1
0
    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
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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