def _build_object(self, nm, clsdata, parents):
        logger.debug("Building object {0}".format(nm))

        props = {}

        properties = {}
        for p in parents:
            properties = util.propmerge(properties, p.__propinfo__)

        if 'properties' in clsdata:
            properties = util.propmerge(properties, clsdata['properties'])

        name_translation = {}

        for prop, detail in properties.items():
            properties[prop]['raw_name'] = prop
            name_translation[prop] = prop.replace('@', '')
            prop = name_translation[prop]

            if detail.get('type', None) == 'object':
                uri = "{0}/{1}_{2}".format(nm,
                                           prop, "<anonymous>")
                self.resolved[uri] = self.construct(
                    uri,
                    detail,
                    (ProtocolBase,))

                props[prop] = make_property(prop,
                    {'type': self.resolved[uri]},
                      self.resolved[uri].__doc__)
                properties[prop]['type'] = self.resolved[uri]

            elif 'type' not in detail and '$ref' in detail:
                ref = detail['$ref']
                uri = util.resolve_ref_uri(self.resolver.resolution_scope, ref)
                if uri not in self.resolved:
                    with self.resolver.resolving(ref) as resolved:
                        self.resolved[uri] = self.construct(
                            uri,
                            resolved,
                            (ProtocolBase,))

                props[prop] = make_property(prop,
                                            {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[prop]['$ref'] = uri
                properties[prop]['type'] = self.resolved[uri]

            elif 'oneOf' in detail:
                potential = self.resolve_classes(detail['oneOf'])
                desc = detail[
                    'description'] if 'description' in detail else ""
                props[prop] = make_property(prop,
                                            {'type': potential}, desc
                                            )

            elif 'type' in detail and detail['type'] == 'array':
                if 'items' in detail and isinstance(detail['items'], dict):
                    if '$ref' in detail['items']:
                        uri = util.resolve_ref_uri(
                            self.resolver.resolution_scope,
                            detail['items']['$ref'])
                        typ = self.construct(uri, detail['items'])
                        propdata = {
                            'type': 'array',
                            'validator': validators.ArrayValidator.create(
                                uri,
                                item_constraint=typ)}
                    else:
                        uri = "{0}/{1}_{2}".format(nm,
                                                   prop, "<anonymous_field>")
                        try:
                            typ = self.construct(uri, detail['items'])
                            propdata = {'type': 'array',
                                        'validator': validators.ArrayValidator.create(uri, item_constraint=typ,
                                                                                addl_constraints=detail)}
                        except NotImplementedError:
                            typ = detail['items']
                            propdata = {'type': 'array',
                                        'validator': validators.ArrayValidator.create(uri,
                                                                                item_constraint=typ,
                                                                                addl_constraints=detail)}

                    props[prop] = make_property(prop,
                                                propdata,
                                                typ.__doc__)
                elif 'items' in detail:
                    typs = []
                    for i, elem in enumerate(detail['items']):
                        uri = "{0}/{1}/<anonymous_{2}>".format(nm, prop, i)
                        typ = self.construct(uri, detail['items'])
                        typs.append(typ)

                    props[prop] = make_property(prop,
                                                {'type': 'tuple',
                                                 'items': typ},
                                                typ.__doc__)

            else:
                desc = detail[
                    'description'] if 'description' in detail else ""
                uri = "{0}/{1}".format(nm, prop)
                typ = self.construct(uri, detail)

                props[prop] = make_property(prop, {'type': typ}, desc)

        """ If this object itself has a 'oneOf' designation, then
        make the validation 'type' the list of potential objects.
        """
        if 'oneOf' in clsdata:
            klasses = self.resolve_classes(clsdata['oneOf'])
            # Need a validation to check that it meets one of them
            props['__validation__'] = {'type': klasses}

        props['__extensible__'] = True
        if 'additionalProperties' in clsdata:
          addlProp = clsdata['additionalProperties']

          if addlProp is False:
            props['__extensible__'] = False
          elif addlProp is True:
            props['__extensible__'] = True
          else:
            if '$ref' in addlProp:
                refs = self.resolve_classes([addlProp])
            else:
                uri = "{0}/{1}_{2}".format(nm,
                                           "<additionalProperties>", "<anonymous>")
                self.resolved[uri] = self.construct(
                    uri,
                    addlProp,
                    (ProtocolBase,))
                refs = [self.resolved[uri]]

            props['__extensible__'] = refs[0]


        props['__prop_names__'] = name_translation

        props['__propinfo__'] = properties
        required = set.union(*[p.__required__ for p in parents])

        if 'required' in clsdata:
            for prop in clsdata['required']:
                required.add(prop)

        invalid_requires = [req for req in required if req not in props['__propinfo__']]
        if len(invalid_requires) > 0:
          raise validators.ValidationError("Schema Definition Error: {0} schema requires "
                                           "'{1}', but properties are not defined"
                                           .format(nm, invalid_requires))

        props['__required__'] = required

        cls = type(str(nm.split('/')[-1]), tuple(parents), props)

        return cls
    def _build_object(self, nm, clsdata, parents,**kw):
        logger.debug(util.lazy_format("Building object {0}", nm))

        # To support circular references, we tag objects that we're
        # currently building as "under construction"
        self.under_construction.add(nm)

        props = {}
        defaults = set()

        properties = {}
        for p in parents:
            properties = util.propmerge(properties, p.__propinfo__)

        if 'properties' in clsdata:
            properties = util.propmerge(properties, clsdata['properties'])

        name_translation = {}

        for prop, detail in properties.items():
            logger.debug(util.lazy_format("Handling property {0}.{1}",nm, prop))
            properties[prop]['raw_name'] = prop
            name_translation[prop] = prop.replace('@', '')
            prop = name_translation[prop]

            if detail.get('default', None) is not None:
                defaults.add(prop)

            if detail.get('type', None) == 'object':
                uri = "{0}/{1}_{2}".format(nm,
                                           prop, "<anonymous>")
                self.resolved[uri] = self.construct(
                    uri,
                    detail,
                    (ProtocolBase,))

                props[prop] = make_property(prop,
                                            {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[prop]['type'] = self.resolved[uri]

            elif 'type' not in detail and '$ref' in detail:
                ref = detail['$ref']
                uri = util.resolve_ref_uri(self.resolver.resolution_scope, ref)
                logger.debug(util.lazy_format(
                    "Resolving reference {0} for {1}.{2}",
                    ref, nm, prop
                ))
                if uri in self.resolved:
                    typ = self.resolved[uri]
                else:
                    typ = self.construct(uri, detail, (ProtocolBase,))

                props[prop] = make_property(prop,
                                            {'type': typ},
                                            typ.__doc__)
                properties[prop]['$ref'] = uri
                properties[prop]['type'] = typ

            elif 'oneOf' in detail:
                potential = self.resolve_classes(detail['oneOf'])
                logger.debug(util.lazy_format("Designating {0} as oneOf {1}", prop, potential))
                desc = detail[
                    'description'] if 'description' in detail else ""
                props[prop] = make_property(prop,
                                            {'type': potential}, desc
                                            )

            elif 'type' in detail and detail['type'] == 'array':
                if 'items' in detail and isinstance(detail['items'], dict):
                    if '$ref' in detail['items']:
                        uri = util.resolve_ref_uri(
                            self.resolver.resolution_scope,
                            detail['items']['$ref'])
                        typ = self.construct(uri, detail['items'])
                        constraints = copy.copy(detail)
                        constraints['strict'] = kw.get('strict')
                        propdata = {
                            'type': 'array',
                            'validator': python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
                                uri,
                                item_constraint=typ,
                                **constraints)}

                    else:
                        uri = "{0}/{1}_{2}".format(nm,
                                                   prop, "<anonymous_field>")
                        try:
                            if 'oneOf' in detail['items']:
                                typ = TypeProxy([
                                    self.construct(uri + "_%s" % i, item_detail)
                                    if '$ref' not in item_detail else
                                    self.construct(util.resolve_ref_uri(
                                        self.resolver.resolution_scope,
                                        item_detail['$ref']),
                                        item_detail)

                                    for i, item_detail in enumerate(detail['items']['oneOf'])]
                                    )
                            else:
                                typ = self.construct(uri, detail['items'])

                            constraints = copy.copy(detail)
                            constraints['strict'] = kw.get('strict')
                            propdata = {'type': 'array',
                                        'validator': python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
                                            uri,
                                            item_constraint=typ,
                                            **constraints)}

                        except NotImplementedError:
                            typ = detail['items']
                            constraints = copy.copy(detail)
                            constraints['strict'] = kw.get('strict')
                            propdata = {'type': 'array',
                                        'validator': python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
                                            uri,
                                            item_constraint=typ,
                                            **constraints)}

                    props[prop] = make_property(prop,
                                                propdata,
                                                typ.__doc__)
                elif 'items' in detail:
                    typs = []
                    for i, elem in enumerate(detail['items']):
                        uri = "{0}/{1}/<anonymous_{2}>".format(nm, prop, i)
                        typ = self.construct(uri, elem)
                        typs.append(typ)

                    props[prop] = make_property(prop,
                                                {'type': typs},
                                                )

            else:
                desc = detail[
                    'description'] if 'description' in detail else ""
                uri = "{0}/{1}".format(nm, prop)
                typ = self.construct(uri, detail)

                props[prop] = make_property(prop, {'type': typ}, desc)

        """ If this object itself has a 'oneOf' designation, then
        make the validation 'type' the list of potential objects.
        """
        if 'oneOf' in clsdata:
            klasses = self.resolve_classes(clsdata['oneOf'])
            # Need a validation to check that it meets one of them
            props['__validation__'] = {'type': klasses}

        props['__extensible__'] = pattern_properties.ExtensibleValidator(
            nm,
            clsdata,
            self)

        props['__prop_names__'] = name_translation

        props['__propinfo__'] = properties
        required = set.union(*[p.__required__ for p in parents])

        if 'required' in clsdata:
            for prop in clsdata['required']:
                required.add(prop)

        invalid_requires = [req for req in required if req not in props['__propinfo__']]
        if len(invalid_requires) > 0:
          raise validators.ValidationError("Schema Definition Error: {0} schema requires "
                                           "'{1}', but properties are not defined"
                                           .format(nm, invalid_requires))

        props['__required__'] = required
        props['__has_default__'] = defaults
        if required and kw.get("strict"):
            props['__strict__'] = True

        props['__title__'] = clsdata.get('title')
        cls = type(str(nm.split('/')[-1]), tuple(parents), props)
        self.under_construction.remove(nm)

        return cls
Ejemplo n.º 3
0
    def _build_object(self, nm, clsdata, parents, **kw):
        logger.debug(util.lazy_format("Building object {0}", nm))

        # To support circular references, we tag objects that we're
        # currently building as "under construction"
        self.under_construction.add(nm)

        props = {}
        defaults = set()

        properties = {}
        for p in parents:
            properties = util.propmerge(properties, p.__propinfo__)

        if "properties" in clsdata:
            properties = util.propmerge(properties, clsdata["properties"])

        name_translation = {}

        for prop, detail in properties.items():
            logger.debug(util.lazy_format("Handling property {0}.{1}", nm, prop))
            properties[prop]["raw_name"] = prop
            name_translation[prop] = prop.replace("@", "")
            prop = name_translation[prop]

            if detail.get("default", None) is not None:
                defaults.add(prop)

            if detail.get("type", None) == "object":
                uri = "{0}/{1}_{2}".format(nm, prop, "<anonymous>")
                self.resolved[uri] = self.construct(uri, detail, (ProtocolBase,))

                props[prop] = make_property(
                    prop, {"type": self.resolved[uri]}, self.resolved[uri].__doc__
                )
                properties[prop]["type"] = self.resolved[uri]

            elif "type" not in detail and "$ref" in detail:
                ref = detail["$ref"]
                typ = self.resolve_type(ref, ".".join([nm, prop]))

                props[prop] = make_property(prop, {"type": typ}, typ.__doc__)
                properties[prop]["$ref"] = ref
                properties[prop]["type"] = typ

            elif "oneOf" in detail:
                potential = self.expand_references(nm, detail["oneOf"])
                logger.debug(
                    util.lazy_format("Designating {0} as oneOf {1}", prop, potential)
                )
                desc = detail["description"] if "description" in detail else ""
                props[prop] = make_property(prop, {"type": potential}, desc)

            elif "type" in detail and detail["type"] == "array":
                if "items" in detail and isinstance(detail["items"], dict):
                    if "$ref" in detail["items"]:
                        typ = self.resolve_type(detail["items"]["$ref"], nm)
                        constraints = copy.copy(detail)
                        constraints["strict"] = kw.get("strict")
                        propdata = {
                            "type": "array",
                            "validator": python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
                                nm, item_constraint=typ, **constraints
                            ),
                        }

                    else:
                        uri = "{0}/{1}_{2}".format(nm, prop, "<anonymous_field>")
                        try:
                            if "oneOf" in detail["items"]:
                                typ = TypeProxy(
                                    self.construct_objects(
                                        detail["items"]["oneOf"], uri
                                    )
                                )
                            else:
                                typ = self.construct(uri, detail["items"])

                            constraints = copy.copy(detail)
                            constraints["strict"] = kw.get("strict")
                            propdata = {
                                "type": "array",
                                "validator": python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
                                    uri, item_constraint=typ, **constraints
                                ),
                            }

                        except NotImplementedError:
                            typ = detail["items"]
                            constraints = copy.copy(detail)
                            constraints["strict"] = kw.get("strict")
                            propdata = {
                                "type": "array",
                                "validator": python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
                                    uri, item_constraint=typ, **constraints
                                ),
                            }

                    props[prop] = make_property(prop, propdata, typ.__doc__)
                elif "items" in detail:
                    typs = []
                    for i, elem in enumerate(detail["items"]):
                        uri = "{0}/{1}/<anonymous_{2}>".format(nm, prop, i)
                        typ = self.construct(uri, elem)
                        typs.append(typ)

                    props[prop] = make_property(prop, {"type": typs})

            else:
                desc = detail["description"] if "description" in detail else ""
                uri = "{0}/{1}".format(nm, prop)
                typ = self.construct(uri, detail)

                props[prop] = make_property(prop, {"type": typ}, desc)

        props["__extensible__"] = pattern_properties.ExtensibleValidator(
            nm, clsdata, self
        )

        props["__prop_names__"] = name_translation

        props["__propinfo__"] = properties
        required = set.union(*[p.__required__ for p in parents])

        if "required" in clsdata:
            for prop in clsdata["required"]:
                required.add(prop)

        invalid_requires = [req for req in required if req not in props["__propinfo__"]]
        if len(invalid_requires) > 0:
            raise validators.ValidationError(
                "Schema Definition Error: {0} schema requires "
                "'{1}', but properties are not defined".format(nm, invalid_requires)
            )

        props["__required__"] = required
        props["__has_default__"] = defaults
        if required and kw.get("strict"):
            props["__strict__"] = True

        props["__title__"] = clsdata.get("title")
        cls = type(str(nm.split("/")[-1]), tuple(parents), props)
        self.under_construction.remove(nm)

        return cls
Ejemplo n.º 4
0
    def _build_object(self, nm, clsdata, parents):
        logger.debug(util.lazy_format("Building object {0}", nm))

        props = {}

        properties = {}
        for p in parents:
            properties = util.propmerge(properties, p.__propinfo__)

        if 'properties' in clsdata:
            properties = util.propmerge(properties, clsdata['properties'])

        name_translation = {}

        for prop, detail in properties.items():
            properties[prop]['raw_name'] = prop
            name_translation[prop] = prop.replace('@', '')
            prop = name_translation[prop]

            if detail.get('type', None) == 'object':
                uri = "{0}/{1}_{2}".format(nm, prop, "<anonymous>")
                self.resolved[uri] = self.construct(uri, detail,
                                                    (ProtocolBase, ))

                props[prop] = make_property(prop, {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[prop]['type'] = self.resolved[uri]

            elif 'type' not in detail and '$ref' in detail:
                ref = detail['$ref']
                uri = util.resolve_ref_uri(self.resolver.resolution_scope, ref)
                if uri not in self.resolved:
                    with self.resolver.resolving(ref) as resolved:
                        self.resolved[uri] = self.construct(
                            uri, resolved, (ProtocolBase, ))

                props[prop] = make_property(prop, {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[prop]['$ref'] = uri
                properties[prop]['type'] = self.resolved[uri]

            elif 'oneOf' in detail:
                potential = self.resolve_classes(detail['oneOf'])
                logger.debug(
                    util.lazy_format("Designating {0} as oneOf {1}", prop,
                                     potential))
                desc = detail['description'] if 'description' in detail else ""
                props[prop] = make_property(prop, {'type': potential}, desc)

            elif 'type' in detail and detail['type'] == 'array':
                if 'items' in detail and isinstance(detail['items'], dict):
                    if '$ref' in detail['items']:
                        uri = util.resolve_ref_uri(
                            self.resolver.resolution_scope,
                            detail['items']['$ref'])
                        typ = self.construct(uri, detail['items'])
                        propdata = {
                            'type':
                            'array',
                            'validator':
                            validators.ArrayValidator.create(
                                uri, item_constraint=typ)
                        }
                    else:
                        uri = "{0}/{1}_{2}".format(nm, prop,
                                                   "<anonymous_field>")
                        try:
                            if 'oneOf' in detail['items']:
                                typ = TypeProxy([
                                    self.construct(uri + "_%s" % i,
                                                   item_detail) if '$ref'
                                    not in item_detail else self.construct(
                                        util.resolve_ref_uri(
                                            self.resolver.resolution_scope,
                                            item_detail['$ref']), item_detail)
                                    for i, item_detail in enumerate(
                                        detail['items']['oneOf'])
                                ])
                            else:
                                typ = self.construct(uri, detail['items'])
                            propdata = {
                                'type':
                                'array',
                                'validator':
                                validators.ArrayValidator.create(
                                    uri,
                                    item_constraint=typ,
                                    addl_constraints=detail)
                            }
                        except NotImplementedError:
                            typ = detail['items']
                            propdata = {
                                'type':
                                'array',
                                'validator':
                                validators.ArrayValidator.create(
                                    uri,
                                    item_constraint=typ,
                                    addl_constraints=detail)
                            }

                    props[prop] = make_property(prop, propdata, typ.__doc__)
                elif 'items' in detail:
                    typs = []
                    for i, elem in enumerate(detail['items']):
                        uri = "{0}/{1}/<anonymous_{2}>".format(nm, prop, i)
                        typ = self.construct(uri, detail['items'])
                        typs.append(typ)

                    props[prop] = make_property(prop, {
                        'type': 'tuple',
                        'items': typ
                    }, typ.__doc__)

            else:
                desc = detail['description'] if 'description' in detail else ""
                uri = "{0}/{1}".format(nm, prop)
                typ = self.construct(uri, detail)

                props[prop] = make_property(prop, {'type': typ}, desc)
        """ If this object itself has a 'oneOf' designation, then
        make the validation 'type' the list of potential objects.
        """
        if 'oneOf' in clsdata:
            klasses = self.resolve_classes(clsdata['oneOf'])
            # Need a validation to check that it meets one of them
            props['__validation__'] = {'type': klasses}

        props['__extensible__'] = True
        if 'additionalProperties' in clsdata:
            addlProp = clsdata['additionalProperties']

            if addlProp is False:
                props['__extensible__'] = False
            elif addlProp is True:
                props['__extensible__'] = True
            else:
                if '$ref' in addlProp:
                    refs = self.resolve_classes([addlProp])
                else:
                    uri = "{0}/{1}_{2}".format(nm, "<additionalProperties>",
                                               "<anonymous>")
                    self.resolved[uri] = self.construct(
                        uri, addlProp, (ProtocolBase, ))
                    refs = [self.resolved[uri]]

                props['__extensible__'] = refs[0]

        props['__prop_names__'] = name_translation

        props['__propinfo__'] = properties
        required = set.union(*[p.__required__ for p in parents])

        if 'required' in clsdata:
            for prop in clsdata['required']:
                required.add(prop)

        invalid_requires = [
            req for req in required if req not in props['__propinfo__']
        ]
        if len(invalid_requires) > 0:
            raise validators.ValidationError(
                "Schema Definition Error: {0} schema requires "
                "'{1}', but properties are not defined".format(
                    nm, invalid_requires))

        props['__required__'] = required

        cls = type(str(nm.split('/')[-1]), tuple(parents), props)

        return cls
Ejemplo n.º 5
0
    def _build_object(self, nm, clsdata, parents, **kw):
        logger.debug(util.lazy_format("Building object {0}", nm))

        # To support circular references, we tag objects that we're
        # currently building as "under construction"
        self.under_construction.append(nm)

        props = {}
        defaults = set()

        properties = {}
        for p in parents:
            properties = util.propmerge(properties, p.__propinfo__)

        if 'properties' in clsdata:
            properties = util.propmerge(properties, clsdata['properties'])

        name_translation = {}

        for prop, detail in properties.items():
            logger.debug(
                util.lazy_format("Handling property {0}.{1}", nm, prop))
            properties[prop]['raw_name'] = prop
            name_translation[prop] = prop.replace('@', '')
            prop = name_translation[prop]

            if detail.get('default', None) is not None:
                defaults.add(prop)

            if detail.get('type', None) == 'object':
                uri = "{0}/{1}_{2}".format(nm, prop, "<anonymous>")
                self.resolved[uri] = self.construct(uri, detail,
                                                    (ProtocolBase, ))

                props[prop] = make_property(prop, {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[prop]['type'] = self.resolved[uri]

            elif 'type' not in detail and '$ref' in detail:
                ref = detail['$ref']
                uri = util.resolve_ref_uri(self.resolver.resolution_scope, ref)
                logger.debug(
                    util.lazy_format("Resolving reference {0} for {1}.{2}",
                                     ref, nm, prop))
                if uri not in self.resolved:
                    """
                    if $ref is under construction, then we're staring at a
                    circular reference.  We save the information required to
                    construct the property for later.
                    """
                    if uri in self.under_construction:
                        self.pending.add(
                            UnresolvedProperty(uri=nm,
                                               property_name=prop,
                                               refuri=uri,
                                               is_array=False))
                        continue

                    with self.resolver.resolving(ref) as resolved:
                        self.resolved[uri] = self.construct(
                            uri, resolved, (ProtocolBase, ))

                props[prop] = make_property(prop, {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[prop]['$ref'] = uri
                properties[prop]['type'] = self.resolved[uri]

            elif 'oneOf' in detail:
                potential = self.resolve_classes(detail['oneOf'])
                logger.debug(
                    util.lazy_format("Designating {0} as oneOf {1}", prop,
                                     potential))
                desc = detail['description'] if 'description' in detail else ""
                props[prop] = make_property(prop, {'type': potential}, desc)

            elif 'type' in detail and detail['type'] == 'array':
                if 'items' in detail and isinstance(detail['items'], dict):
                    if '$ref' in detail['items']:
                        ref = detail['items']['$ref']
                        uri = util.resolve_ref_uri(
                            self.resolver.resolution_scope, ref)

                        if uri not in self.resolved and uri in self.under_construction:
                            """
                            if $ref is under construction, then we're staring at a
                            circular reference.  We save the information required to
                            construct the property for later.
                            """
                            self.pending.add(
                                UnresolvedProperty(uri=nm,
                                                   property_name=prop,
                                                   refuri=uri,
                                                   is_array=True))
                            continue
                        else:
                            typ = self.construct(uri, detail['items'])
                            propdata = {
                                'type':
                                'array',
                                'validator':
                                python_jsonschema_objects.wrapper_types.
                                ArrayWrapper.create(uri, item_constraint=typ)
                            }
                    else:
                        uri = "{0}/{1}_{2}".format(nm, prop,
                                                   "<anonymous_field>")
                        try:
                            if 'oneOf' in detail['items']:
                                typ = TypeProxy([
                                    self.construct(uri + "_%s" % i,
                                                   item_detail) if '$ref'
                                    not in item_detail else self.construct(
                                        util.resolve_ref_uri(
                                            self.resolver.resolution_scope,
                                            item_detail['$ref']), item_detail)
                                    for i, item_detail in enumerate(
                                        detail['items']['oneOf'])
                                ])
                            else:
                                typ = self.construct(uri, detail['items'])
                            propdata = {
                                'type':
                                'array',
                                'validator':
                                python_jsonschema_objects.wrapper_types.
                                ArrayWrapper.create(uri,
                                                    item_constraint=typ,
                                                    addl_constraints=detail)
                            }
                        except NotImplementedError:
                            typ = detail['items']
                            propdata = {
                                'type':
                                'array',
                                'validator':
                                python_jsonschema_objects.wrapper_types.
                                ArrayWrapper.create(uri,
                                                    item_constraint=typ,
                                                    addl_constraints=detail)
                            }

                    props[prop] = make_property(prop, propdata, typ.__doc__)
                elif 'items' in detail:
                    typs = []
                    for i, elem in enumerate(detail['items']):
                        uri = "{0}/{1}/<anonymous_{2}>".format(nm, prop, i)
                        typ = self.construct(uri, detail['items'])
                        typs.append(typ)

                    props[prop] = make_property(prop, {
                        'type': 'tuple',
                        'items': typ
                    }, typ.__doc__)

            else:
                desc = detail['description'] if 'description' in detail else ""
                uri = "{0}/{1}".format(nm, prop)
                typ = self.construct(uri, detail)

                props[prop] = make_property(prop, {'type': typ}, desc)
        """ If this object itself has a 'oneOf' designation, then
        make the validation 'type' the list of potential objects.
        """
        if 'oneOf' in clsdata:
            klasses = self.resolve_classes(clsdata['oneOf'])
            # Need a validation to check that it meets one of them
            props['__validation__'] = {'type': klasses}

        props['__extensible__'] = pattern_properties.ExtensibleValidator(
            nm, clsdata, self)

        props['__prop_names__'] = name_translation

        props['__propinfo__'] = properties
        required = set.union(*[p.__required__ for p in parents])

        if 'required' in clsdata:
            for prop in clsdata['required']:
                required.add(prop)

        invalid_requires = [
            req for req in required if req not in props['__propinfo__']
        ]
        if len(invalid_requires) > 0:
            raise validators.ValidationError(
                "Schema Definition Error: {0} schema requires "
                "'{1}', but properties are not defined".format(
                    nm, invalid_requires))

        props['__required__'] = required
        props['__has_default__'] = defaults
        if required and kw.get("strict"):
            props['__strict__'] = True
        cls = type(str(nm.split('/')[-1]), tuple(parents), props)
        self.under_construction.remove(nm)

        return cls
Ejemplo n.º 6
0
    def _build_object(self, nm, clsdata, parents, **kw):
        logger.debug(util.lazy_format("Building object {0}", nm))
        clsdata_hash = hash_dict(clsdata)

        props = {}

        properties = {}
        for p in parents:
            properties = util.propmerge(properties, p.__propinfo__)

        if 'properties' in clsdata:
            properties = util.propmerge(properties, clsdata['properties'])

        name_translation = {}

        for prop, detail in properties.items():
            logger.debug(
                util.lazy_format("Handling property {0}.{1}", nm, prop))
            properties[prop]['raw_name'] = prop
            name_translation[prop] = prop.replace('@', '').replace(' ', '_')
            raw_prop = prop
            prop = name_translation[prop]

            if detail.get('type', None) == 'object':
                #~ uri = "{0}/{1}_{2}".format(nm,
                #~ prop, "<anonymous>")
                # Re-use existing submodules if possible
                uri = detail['title']
                # Scrub raw_name since that's a function of this property but not of the substructure.
                detail_clean = dict(detail)
                del detail_clean['raw_name']
                self.resolved[uri] = self.construct(uri, detail_clean,
                                                    (ProtocolBase, ))

                props[prop] = make_property(prop, {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[raw_prop]['type'] = self.resolved[uri]

            elif 'type' not in detail and '$ref' in detail:
                ref = detail['$ref']
                uri = util.resolve_ref_uri(self.resolver.resolution_scope, ref)
                logger.debug(
                    util.lazy_format("Resolving reference {0} for {1}.{2}",
                                     ref, nm, prop))
                if uri not in self.resolved:
                    with self.resolver.resolving(ref) as resolved:
                        self.resolved[uri] = self.construct(
                            uri, resolved, (ProtocolBase, ))

                props[prop] = make_property(prop, {'type': self.resolved[uri]},
                                            self.resolved[uri].__doc__)
                properties[prop]['$ref'] = uri
                properties[prop]['type'] = self.resolved[uri]

            elif 'oneOf' in detail:
                potential = self.resolve_classes(detail['oneOf'])
                logger.debug(
                    util.lazy_format("Designating {0} as oneOf {1}", prop,
                                     potential))
                desc = detail['description'] if 'description' in detail else ""
                props[prop] = make_property(prop, {'type': potential}, desc)

            elif 'type' in detail and detail['type'] == 'array':
                if 'items' in detail and isinstance(detail['items'], dict):
                    if '$ref' in detail['items']:
                        uri = util.resolve_ref_uri(
                            self.resolver.resolution_scope,
                            detail['items']['$ref'])
                        typ = self.construct(uri, detail['items'])
                        propdata = {
                            'type':
                            'array',
                            'validator':
                            python_jsonschema_objects.wrapper_types.
                            ArrayWrapper.create(uri, item_constraint=typ)
                        }
                    else:
                        uri = "{0}/{1}_{2}".format(nm, prop,
                                                   "<anonymous_field>")
                        try:
                            if 'oneOf' in detail['items']:
                                typ = TypeProxy([
                                    self.construct(uri + "_%s" % i,
                                                   item_detail) if '$ref'
                                    not in item_detail else self.construct(
                                        util.resolve_ref_uri(
                                            self.resolver.resolution_scope,
                                            item_detail['$ref']), item_detail)
                                    for i, item_detail in enumerate(
                                        detail['items']['oneOf'])
                                ])
                            else:
                                # Re-use existing submodules if possible
                                uri = detail['items']['title']
                                typ = self.construct(uri, detail['items'])
                            propdata = {
                                'type':
                                'array',
                                'validator':
                                python_jsonschema_objects.wrapper_types.
                                ArrayWrapper.create(uri,
                                                    item_constraint=typ,
                                                    addl_constraints=detail)
                            }
                        except NotImplementedError:
                            typ = detail['items']
                            propdata = {
                                'type':
                                'array',
                                'validator':
                                python_jsonschema_objects.wrapper_types.
                                ArrayWrapper.create(uri,
                                                    item_constraint=typ,
                                                    addl_constraints=detail)
                            }

                    props[prop] = make_property(prop, propdata, typ.__doc__)
                elif 'items' in detail:
                    typs = []
                    for i, elem in enumerate(detail['items']):
                        uri = "{0}/{1}/<anonymous_{2}>".format(nm, prop, i)
                        typ = self.construct(uri, detail['items'])
                        typs.append(typ)

                    props[prop] = make_property(prop, {
                        'type': 'tuple',
                        'items': typ
                    }, typ.__doc__)

            else:
                desc = detail['description'] if 'description' in detail else ""
                uri = "{0}/{1}".format(nm, prop)
                typ = self.construct(uri, detail)

                props[prop] = make_property(prop, {'type': typ}, desc)
        """ If this object itself has a 'oneOf' designation, then
        make the validation 'type' the list of potential objects.
        """
        if 'oneOf' in clsdata:
            klasses = self.resolve_classes(clsdata['oneOf'])
            # Need a validation to check that it meets one of them
            props['__validation__'] = {'type': klasses}

        props['__extensible__'] = pattern_properties.ExtensibleValidator(
            nm, clsdata, self)

        props['__prop_names__'] = name_translation

        props['__propinfo__'] = properties
        required = set.union(*[p.__required__ for p in parents])

        if 'required' in clsdata:
            for prop in clsdata['required']:
                required.add(prop)

        invalid_requires = [
            req for req in required if req not in props['__propinfo__']
        ]
        if len(invalid_requires) > 0:
            raise validators.ValidationError(
                "Schema Definition Error: {0} schema requires "
                "'{1}', but properties are not defined".format(
                    nm, invalid_requires))

        props['__required__'] = required
        props['__clsdata_hash__'] = clsdata_hash
        if required and kw.get("strict"):
            props['__strict__'] = True
        cls = type(str(nm.split('/')[-1]), tuple(parents), props)

        return cls