示例#1
0
 def _validate(self, value, resolve=True, **opts):
     String.validate(value, **opts)
     if resolve:
         try:
             resolve_uri(value)
             return True
         except Exception as er:
             return False
示例#2
0
 def _is_subclass(class_id):
     if class_id == scls_id:
         return True
     for e in resolve_uri(class_id).get('extends', []):
         if _is_subclass(e):
             return True
     return False
示例#3
0
 def _get_cname_id_cached(self, cname, current_ns):
     #ns = ChainMap(self._registry, NamespaceManager.builder_namespaces(), NamespaceManager.available_namespaces())
     # iterate on namespace sorted from the longest to get the most qualified
     #ns_names = sorted([k for k, uri in ns.items() if cname.startswith(k+'.') or k == cname], reverse=True)
     #ns_name = ns_names[0] if ns_names else ''
     #ns_uri = ns[ns_name]
     ns_name, ns_uri = self._find_ns_by_cname(cname)
     fragment_cname = cname[len(ns_name):] if ns_name else cname
     cns = fragment_cname.split('.')
     if cns and not cns[0]:
         cns = cns[1:]
     fragment_parts = []
     if fragment_cname:
         if ns_uri in UriResolver._doc_store:
             import dpath.util
             doc = resolve_uri(ns_uri)
             glob = ''.join(['/*/' + c for c in cns])
             glob = glob.strip('/')
             for x in dpath.util.search(doc, glob, yielded=True):
                 return ns_uri + ('#/' if '#' not in ns_uri else '/') + x[0]
             # not found: if namespace uri corresponds to local namespace, compute a path
             #if ns_uri != ns.get(''):
             #    raise InvalidValue(f"impossible to find '{cname}' in {ns_uri}.")
         for c in cns[:-1]:
             fragment_parts += ['$defs', c]
         fragment_parts += (['properties', cns[-1]]
                            if len(cns) > 2 and cns[-2][0].isupper()
                            and cns[-1][0].islower() else
                            ['$defs', cns[-1]])
     ns_uri = ns_uri or self._find_ns_by_cname(current_ns)[1]
     return '/'.join([ns_uri + ('#' if '#' not in ns_uri else '')] +
                     fragment_parts)
示例#4
0
    def build(self, id, schema=None, bases=(), attrs=None):
        from .namespace_manager import NamespaceManager
        from ..protocols import TypeProtocol, ObjectProtocol, ArrayProtocol, TypeProxy
        from ..types.constants import _True, _False

        if self.contains(id):
            return self.get(id)
        if id in self._on_construction:
            return TypeProxy.build(id)
            #return TypeProxy.build(id)()
        if schema is None:
            schema = resolve_uri(id)
        if schema is True:
            return _True()
        if schema is False:
            return _False()
        attrs = attrs or {}
        self._on_construction[id] = (schema, bases, attrs)
        if '$ref' in schema:
            schema = schema.copy()
            ref = schema.pop('$ref')
            cls = self.load(scope(ref, id))
            if schema:
                cls = cls.extend_type(id, **schema)
        elif 'object' in schema.get('type', ''):
            cls = ObjectProtocol.build(id, schema, bases, attrs)
        elif 'array' in schema.get('type', ''):
            cls = ArrayProtocol.build(id, schema, bases, attrs)
        else:
            cls = TypeProtocol.build(id, schema, bases, attrs)()
        self._on_construction.pop(id)
        self._registry[id] = cls
        NamespaceManager.register_ns(id)
        return cls
示例#5
0
 def _schema_mro(id, sch):
     for e in sch.get('extends', []):
         i = scope(e, id)
         s = resolve_uri(i)
         yield i, s
         for m in _schema_mro(i, s):
             yield m
示例#6
0
 def get_cname_definitions(self, cname):
     ns_uri = self.get_id_cname(cname)
     doc = resolve_uri(ns_uri)
     defs = {}
     for tag in ['$defs', 'definitions']:
         for k, v in doc.get(tag, {}).items():
             defs[f'{cname}.{k}'] = f'{ns_uri}/{tag}/{k}'
     return defs
示例#7
0
    def schema_mro(id, schema=None):
        schema = schema or resolve_uri(id)

        def _schema_mro(id, sch):
            for e in sch.get('extends', []):
                i = scope(e, id)
                s = resolve_uri(i)
                yield i, s
                for m in _schema_mro(i, s):
                    yield m

        return OrderedDict(_schema_mro(id, schema))
示例#8
0
 def __new__(cls, clsname, bases, attrs):
     from ..managers.type_builder import type_builder
     schema = attrs.get('_schema', {})
     id = attrs.get('_id')
     if not schema and id:
         schema = resolve_uri(id)
     elif bases:
         schema['extends'] = [b._id for b in bases if hasattr(b, '_id')]
     schema.setdefault('type', 'object')
     id = id or clsname
     # remove previous entry in registry
     if id in type_builder._registry:
         del type_builder._registry[id]
     attrs['_clsname'] = clsname
     return type_builder.build(id, schema, bases, attrs=attrs)
示例#9
0
    def expand(self, id, schema=None):
        def scope_refs(id, schema):
            def _scope_refs(coll, key, level):
                if isinstance(coll, Mapping):
                    v = coll[key]
                    if isinstance(v, Mapping) and '$ref' in v:
                        v['$ref'] = scope(v['$ref'], id)

            apply_through_collection(schema, _scope_refs)

        schema = copy.deepcopy(schema or resolve_uri(id))
        mro = self.schema_mro(id, schema)
        scope_refs(id, schema)
        for i, s in mro.items():
            scope_refs(i, s)
        extends = list(mro.keys())
        required = list(schema.get('required', [])) + sum(
            [list(s.get('required', [])) for s in mro.values()], [])
        read_only = list(schema.get('readOnly', [])) + sum(
            [list(s.get('readOnly', [])) for s in mro.values()], [])
        not_serialized = list(schema.get('notSerialized', [])) + sum(
            [list(s.get('notSerialized', [])) for s in mro.values()], [])
        properties = ReadOnlyChainMap(
            schema.get('properties', {}),
            *[s.get('properties', {}) for i, s in mro.items()])
        pattern_properties = ReadOnlyChainMap(
            schema.get('patternProperties', {}),
            *[s.get('patternProperties', {}) for s in mro.values()])
        if extends:
            schema['extends'] = extends
        if required:
            schema['required'] = set(required)
        if read_only:
            schema['readOnly'] = set(read_only)
        if not_serialized:
            schema['notSerialized'] = set(not_serialized)
        if properties:
            schema['properties'] = properties
        if pattern_properties:
            schema['patternProperties'] = pattern_properties
        return schema
示例#10
0
 def _resolve(self, value):
     return resolve_uri(value)