Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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):
Exemplo n.º 3
0
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(