def uri(self, value: Optional[URI]) -> None: from jschon.catalogue import Catalogue if self._uri != value: if self._uri is not None: Catalogue.del_schema(self._uri) self._uri = value if self._uri is not None: Catalogue.add_schema(self._uri, self)
def __init__( self, value: Union[bool, Mapping[str, AnyJSONCompatible]], *, uri: URI = None, metaschema_uri: URI = None, parent: JSON = None, key: str = None, ): from jschon.catalogue import Catalogue if uri is not None: Catalogue.add_schema(uri, self) self._uri: Optional[URI] = uri self._metaschema_uri: Optional[URI] = metaschema_uri self.keywords: Dict[str, Keyword] = {} # don't call super().__init__ self.value: Union[bool, Mapping[str, AnyJSONCompatible]] self.type: str self.parent: Optional[JSON] = parent self.key: Optional[str] = key if isinstance(value, bool): self.type = "boolean" self.value = value elif isinstance(value, Mapping) and all( isinstance(k, str) for k in value): self.type = "object" self.value = {} if self.parent is None and self.uri is None: self.uri = URI(f'mem:{uuid4()}') self._bootstrap(value) kwclasses = { key: kwclass for key in value if ((kwclass := self.metaschema.kwclasses.get(key)) and # skip bootstrapped keywords key not in self.keywords) } for kwclass in self._resolve_dependencies(kwclasses):
class AnchorKeyword(Keyword): key = "$anchor" def __init__(self, parentschema: JSONSchema, value: str): super().__init__(parentschema, value) if (base_uri := parentschema.base_uri) is not None: uri = URI(f'{base_uri}#{value}') else: raise JSONSchemaError(f'No base URI for "$anchor" value "{value}"') # just add a schema reference to the catalogue, rather than updating # the schema URI itself; this way we keep canonical URIs consistent # for subschemas regardless of anchor usage # parentschema.uri = uri Catalogue.add_schema(uri, parentschema) def can_evaluate(self, instance: JSON) -> bool: return False class DynamicRefKeyword(Keyword): key = "$dynamicRef" def __init__(self, parentschema: JSONSchema, value: str): super().__init__(parentschema, value) # this is not required by the spec, but it doesn't make sense # for a $dynamicRef *not* to end in a plain-name fragment if (fragment := URI(value).fragment) is None or '/' in fragment: raise JSONSchemaError(