jsonschema

    A faithful MoonBit port of python-jsonschema: JSON Schema validation.

    json
    jsonschema
    validation
    Download zip
    Author
    Version
    0.1.0
    License
    MIT
    Last updated
    yesterday
    Downloads
    2

    Dependencies

    #bobzhang/jsonschema

    A faithful MoonBit port of python-jsonschema: JSON Schema validation for drafts 3, 4, 6, 7, 2019-09 and 2020-12, with the same keyword semantics, error messages, error paths, best_match heuristics and format checks as upstream (running with its format-nongpl extras installed). $ref, $dynamicRef and $recursiveRef are resolved by bobzhang/referencing.

    The whole official JSON-Schema-Test-Suite runs in suite/, held to upstream's recorded outcome for every test (including the handful of cases where upstream itself disagrees with the suite).

    #Validating

    ///|
    test "validate" {
    let schema : Json = {
    "type": "object",
    "properties": { "price": { "type": "number", "minimum": 0 } },
    "required": ["name"],
    }
    @jsonschema.validate({ "name": "Eggs", "price": 34.99 }, schema)
    try @jsonschema.validate({ "name": "Eggs", "price": -1 }, schema) catch {
    @jsonschema.ValidationError(error) => {
    inspect(error.message, content="-1 is less than the minimum of 0")
    inspect(
    error,
    content=(
    #|-1 is less than the minimum of 0
    #|
    #|Failed validating 'minimum' in schema['properties']['price']:
    #| {'type': 'number', 'minimum': 0}
    #|
    #|On instance['price']:
    #| -1
    ),
    )
    }
    _ => fail("expected a ValidationError")
    } noraise {
    _ => fail("expected a ValidationError")
    }
    }

    validate checks the schema against its meta-schema first (raising SchemaError), picks the validator class from $schema (defaulting to the latest draft) and raises the best_match of the errors.

    #Validators and lazy errors

    A ValidatorClass (draft7_validator, draft202012_validator, ...) plays the role of upstream's validator classes; cls.new(schema) creates a Validator. iter_errors returns Errors, a lazy sequence: like upstream's generators, nothing runs until it is consumed, and is_valid / first stop at the first error.

    ///|
    test "iter_errors" {
    let validator = @jsonschema.draft202012_validator.new({
    "items": { "type": "integer" },
    "maxItems": 2,
    })
    let errors = validator.iter_errors([1, "two", 3.5]).to_array()
    inspect(
    errors.map(e => "\{e.json_path()}: \{e.message}").join("\n"),
    content=(
    #|$[1]: 'two' is not of type 'integer'
    #|$[2]: 3.5 is not of type 'integer'
    #|$: [1, 'two', 3.5] is too long
    ),
    )
    inspect(validator.is_valid([1, 2]), content="true")
    let best = @jsonschema.best_match(errors.iter()).unwrap()
    inspect(best.message, content="[1, 'two', 3.5] is too long")
    }

    #Formats

    Format validation is off unless a FormatChecker is given; each class's format_checker holds the checks for its draft.

    ///|
    test "formats" {
    let cls = @jsonschema.draft202012_validator
    let validator = cls.new(
    { "format": "ipv4" },
    format_checker=cls.format_checker,
    )
    inspect(validator.is_valid("127.0.0.1"), content="true")
    inspect(validator.is_valid("127.0.0.01"), content="false")
    inspect(cls.new({ "format": "ipv4" }).is_valid("nope"), content="true")
    }

    #Python numbers

    MoonBit's Json stores every number as a Double. Python distinguishes 1 from 1.0 (drafts 3 and 4 do not consider 1.0 an integer, and error messages print 1.0), so @jsonschema.loads parses JSON exactly like Python's json.loads, recording the spelling of float-like numbers in Json::Number's repr~:

    ///|
    test "loads" {
    let one_point_zero = @jsonschema.loads("1.0")
    inspect(
    @jsonschema.draft4_validator
    .new({ "type": "integer" })
    .is_valid(one_point_zero),
    content="false",
    )
    inspect(
    @jsonschema.draft7_validator
    .new({ "type": "integer" })
    .is_valid(one_point_zero),
    content="true",
    )
    inspect(
    @jsonschema.py_repr(@jsonschema.loads("[1.0, 1e400, 7]")),
    content="[1.0, inf, 7]",
    )
    }

    Numbers without a recorded spelling count as ints when they are whole.

    #Extending

    ///|
    test "extend" {
    let even : @jsonschema.KeywordFn = (_, value, instance, _) => {
    @jsonschema.Errors::new(yield_ => {
    if value is True && instance is Number(n, ..) && n % 2.0 != 0.0 {
    return yield_(
    @jsonschema.ValidationError::new(
    "\{@jsonschema.py_repr(instance)} is odd",
    ),
    )
    }
    true
    })
    }
    let cls = @jsonschema.draft202012_validator.extend_with(validators=[
    ("even", even),
    ])
    let errors = cls.new({ "even": true }).iter_errors(3).to_array()
    inspect(errors[0].message, content="3 is odd")
    debug_inspect(errors[0].schema_path, content="[Key(\"even\")]")
    }

    #Packages

    packageupstream
    bobzhang/jsonschemajsonschema (validators, _keywords, _legacy_keywords, _types, _format, _utils, exceptions)
    bobzhang/jsonschema/specificationsjsonschema-specifications (meta-schemas, parsed lazily)
    bobzhang/jsonschema/internal/pycompatjson.loads, repr, pprint.pformat, reprlib, textwrap, Python numerics
    bobzhang/jsonschema/internal/regexre: a port of CPython's parser, run on MoonBit core's @string.Regex or, for constructs it lacks, a backtracking matcher following sre
    bobzhang/jsonschema/internal/formatsipaddress, fqdn, idna, rfc3986-validator, rfc3987-syntax, rfc3339-validator, isoduration, jsonpointer, uri-template, webcolors
    bobzhang/jsonschema/internal/unicodedatathe unicodedata / idna tables these need

    #Licenses

    The module is MIT-licensed, except internal/formats/fqdn.mbt, a port of fqdn, which stays under the MPL-2.0. See NOTICE for the third-party works (python-jsonschema, CPython, the Unicode data, the format-checking libraries, the JSON-Schema-Test-Suite, ...) this module derives from.

    scripts/ regenerates the embedded data (gen_unicodedata.py, gen_format_data.py, gen_specifications.py) and the suite tests (suite_oracle.py records upstream's outcomes, gen_suite.py writes suite/gen_*_test.mbt).

    #Deviations from upstream

    • Format checks follow upstream's format-nongpl configuration: uri / uri-reference use rfc3986-validator and iri / iri-reference use rfc3987-syntax (not the GPL rfc3987 package).

    • Draft 3 / 4 integer: needs loads (or Json::number(x, repr="1.0")) to tell 1.0 from 1; whole numbers without a spelling are ints.
    • Regular expressions: \N{...} escapes are rejected (no Unicode name table). Everything else -- including lookaround, atomic groups, possessive quantifiers, conditionals, backreferences, Unicode \b and CPython's case-insensitive equivalences -- follows CPython 3.13's re (differentially tested against it). Lone surrogates in subjects are never matched by character classes.
    • No network access: the default registry holds the meta-schemas only (upstream fetches unknown remote $refs with a deprecation warning).
    • Unresolvable references raise bobzhang/referencing errors directly (@referencing.is_unresolvable), not upstream's _WrappedReferencingError.
    • No deprecation warnings (e.g. for unknown $schemas); the deprecated RefResolver API is not ported.
    • extend is ValidatorClass::extend_with (extend is reserved in MoonBit); validator classes are values (draft7_validator), not types.
    • Built-in format checks raise the public FormatCause errors (AddressValueError, IDNAError, ... named after upstream's exception classes), available as ValidationError::cause.
    • Python-level crashes upstream would hit (e.g. OverflowError in multipleOf for ints too large for a float) are raised as PythonError.
    • Values Python allows but JSON cannot hold (non-string keys, tuples, Decimal) are out of scope.

    ApplicableValidators

    type ApplicableValidators = (Json) -> Array[(String, Json)]

    Which keywords of a schema apply (upstream's applicable_validators).

    FormatCheckFn

    type FormatCheckFn = (Json) -> Bool raise

    A format-checking function: whether the instance conforms. It may raise to signal non-conformance (see FormatChecker::checks's raises).

    KeywordFn

    type KeywordFn = (Validator, Json, Json, Json) -> Errors

    A keyword implementation (upstream's SchemaKeywordValidator): given the validator, the keyword's value, the instance and the (sub)schema containing the keyword, the (lazy) errors.

    TypeCheckFn

    type TypeCheckFn = (TypeChecker, Json) -> Bool raise

    A type-checking function: given the checker doing the checking and an instance, whether the instance is of the type.

    FormatCause

    pub(all) suberror FormatCause {
    AddressValueError(String)
    IDNAError(String)
    JsonPointerException(String)
    DurationParsingException(String)
    PatternError(String)
    ValueError(String)
    }

    The errors the built-in format checks raise to signal an invalid instance (they become FormatError / ValidationError causes). Named after the Python exception classes upstream's checks raise.
    impl Show for FormatCause

    FormatCause::class_name

    fn FormatCause::class_name(self : FormatCause) -> String

    The Python class name of the error, e.g. AddressValueError.

    FormatCause::is_value_error

    fn FormatCause::is_value_error(self : FormatCause) -> Bool

    isinstance(error, ValueError) (Python's hierarchy: address, IDNA and duration errors are ValueErrors).

    FormatError

    pub suberror FormatError {
    FormatError(message~ : String, cause~ : Error?)
    }

    Raised by FormatChecker::check when an instance does not conform (jsonschema.exceptions.FormatError).
    impl Show for FormatError

    JSONDecodeError

    pub suberror JSONDecodeError {
    JSONDecodeError(msg~ : String, pos~ : Int, lineno~ : Int, colno~ : Int)
    }

    Raised by loads for malformed documents (Python's json.JSONDecodeError); Show gives Python's message, e.g. Expecting value: line 1 column 1 (char 0).

    JsonSchemaError

    pub(all) suberror JsonSchemaError {
    ValidationError(ValidationError)
    SchemaError(ValidationError)
    }

    Raised by validation: carries the ValidationError data.

    LookupError

    pub suberror LookupError {
    KeyError(String)
    IndexError(Int)
    TypeError(String)
    } derive(
    Debug
    )

    Raised when indexing an ErrorTree at an index its instance lacks (Python's KeyError / IndexError / TypeError).

    PythonError

    pub suberror PythonError {
    PythonError(String)
    } derive(
    Debug
    )

    Raised where upstream would crash with a Python-level error (e.g. a TypeError from len(True) on a malformed schema).
    impl Show for PythonError

    UndefinedTypeCheck

    pub suberror UndefinedTypeCheck {
    UndefinedTypeCheck(String)
    }

    Raised by TypeChecker::is_type / remove for unknown types (jsonschema.exceptions.UndefinedTypeCheck).

    UnknownFormat

    pub suberror UnknownFormat {
    UnknownFormat(String)
    } derive(
    Debug
    )

    Raised by FormatChecker::new for unknown formats (upstream: KeyError).

    UnknownType

    pub suberror UnknownType {
    UnknownType(type_~ : Json, instance~ : Json, schema~ : Json)
    }

    Raised when a validator is asked to validate against an unknown type (jsonschema.exceptions.UnknownType).
    impl Show for UnknownType

    ErrorKind

    pub(all) enum ErrorKind {
    Validation
    Schema
    } derive(Eq,
    Debug
    )

    Which upstream exception class an error stands for.

    ErrorTree

    pub struct ErrorTree {
    errors : Map[String, ValidationError]
    // private fields
    }

    ErrorTrees make it easier to check which validations failed (jsonschema.exceptions.ErrorTree).

    errors maps each failed keyword at this level of the instance to its error (keyed by the keyword name, or by its Python repr for non-string validators).
    impl Show for ErrorTree

    ErrorTree::at

    fn ErrorTree::at(self : ErrorTree, index : PathItem) -> ErrorTree raise LookupError

    Retrieve the child tree one level down at the given index.

    If the index is not in the instance that this tree corresponds to and is not known by this tree, the error indexing the instance would produce is raised.

    ErrorTree::contains

    fn ErrorTree::contains(self : ErrorTree, index : PathItem) -> Bool

    Check whether instance[index] has any errors.

    ErrorTree::iter

    fn ErrorTree::iter(self : ErrorTree) -> Iter[PathItem]

    Iterate (non-recursively) over the indices in the instance with errors.

    ErrorTree::length

    fn ErrorTree::length(self : ErrorTree) -> Int

    len(tree): the total_errors.

    ErrorTree::new

    fn ErrorTree::new(errors? : ArrayView[ValidationError], instance? : Json) -> ErrorTree

    Build a tree from errors; instance, if known, enables indexing the tree at indices not present in it to raise the same error that indexing the instance itself would.

    ErrorTree::total_errors

    fn ErrorTree::total_errors(self : ErrorTree) -> Int

    The total number of errors in the entire tree, including children.

    Errors

    pub struct Errors {
    // private fields
    }

    A lazily produced sequence of validation errors: the counterpart of the generators upstream's keyword functions and iter_errors return.

    Nothing is computed until the sequence is consumed, and consumers that stop early (first, is_empty, a for-style loop that breaks) stop the validation work right there, exactly like advancing a Python generator only as far as needed. Errors that are not validation errors (unknown types, unresolvable references, ...) are raised while consuming.

    Each consumption re-runs the computation.

    Errors::each

    fn Errors::each(self : Errors, f : (ValidationError) -> Unit raise) -> Unit raise

    Call f on each error.

    Errors::empty

    fn Errors::empty() -> Errors

    No errors.

    Errors::first

    fn Errors::first(self : Errors) -> ValidationError? raise

    The first error, if any (Python's next(errors, None)); stops the computation right after it.

    Errors::is_empty

    fn Errors::is_empty(self : Errors) -> Bool raise

    Whether there are no errors (stops at the first one).

    Errors::map

    fn Errors::map(self : Errors, f : (ValidationError) -> ValidationError raise) -> Errors

    Transform each error as it passes through.

    Errors::new

    fn Errors::new(run : ((ValidationError) -> Bool raise) -> Bool raise) -> Errors

    A sequence produced by run, which must pass each error to its argument (a "yield" callback returning whether to go on), stopping and returning false as soon as that returns false; run returns true once it has produced all its errors.

    Errors::run

    fn Errors::run(self : Errors, yield_ : (ValidationError) -> Bool raise) -> Bool raise

    Feed the errors to yield_, stopping early when it returns false. Returns whether all errors were consumed.

    Errors::single

    fn Errors::single(error : ValidationError) -> Errors

    A single error.

    Errors::to_array

    fn Errors::to_array(self : Errors) -> Array[ValidationError] raise

    All the errors (Python's list(errors)).

    FormatCheck

    pub struct FormatCheck {
    func : (Json) -> Bool raise
    raises : (Error) -> Bool
    }

    A registered format check: the function, and which errors it raises to signal an invalid instance (upstream's raises exception types).

    FormatChecker

    pub struct FormatChecker {
    checkers : Map[String, FormatCheck]
    }

    A format property checker (jsonschema.FormatChecker).

    JSON Schema does not mandate that the format property actually do any validation. If validation is desired however, instances of this type can be hooked into validators to enable format validation.

    FormatCheckers always return true when asked about formats that they do not know how to validate.

    FormatChecker::check

    fn FormatChecker::check(self : FormatChecker, instance : Json, format : String) -> Unit raise

    Check whether the instance conforms to the given format.

    Raises FormatError if it does not; errors raised by the check that are not covered by its raises propagate unchanged.

    FormatChecker::checks

    fn FormatChecker::checks(self : FormatChecker, format : String, func : (Json) -> Bool raise, raises? : (Error) -> Bool) -> Unit

    Register func as validating a new format.

    raises decides which errors raised by func signal an invalid instance; such an error becomes the cause of the resulting FormatError (and thereby of the ValidationError).

    FormatChecker::cls_checks

    fn FormatChecker::cls_checks(format : String, func : (Json) -> Bool raise, raises? : (Error) -> Bool) -> Unit

    Upstream's deprecated FormatChecker.cls_checks: register a check in the class-level registry copied by future FormatChecker::new() calls.

    FormatChecker::conforms

    fn FormatChecker::conforms(self : FormatChecker, instance : Json, format : String) -> Bool raise

    Whether the instance conforms to the given format.

    FormatChecker::new

    fn FormatChecker::new(formats? : ArrayView[String]) -> FormatChecker raise UnknownFormat

    FormatChecker(formats): a checker for the given formats, taken from the class-level registry (all of them when formats is omitted).

    Raises UnknownFormat (upstream: KeyError) for formats not in the registry.

    PathItem

    pub(all) enum PathItem {
    Key(String)
    Index(Int)
    } derive(Eq, Hash,
    Debug
    )

    An element of an error's (instance or schema) path: an object key or an array index, like the str | int items of upstream's path deques.
    impl Compare for PathItem
    impl Show for PathItem

    PathItem::repr

    fn PathItem::repr(self : PathItem) -> String

    repr(item): 'key' or 3.

    PathItem::to_json

    fn PathItem::to_json(self : PathItem) -> Json

    The item as a JSON value ("key" or 3).

    Relevance

    pub(all) struct Relevance {
    neg_path_length : Int
    not_weak : Bool
    strong : Bool
    not_matching_type : Bool
    } derive(Compare, Eq,
    Debug
    )

    The relevance of an error: upstream's tuple (-len(error.path), validator not in weak, validator in strong,not error._matches_type()), compared lexicographically (higher is more relevant).

    TypeChecker

    pub struct TypeChecker {
    // private fields
    }

    A type property checker (jsonschema.TypeChecker).

    A TypeChecker performs type checking for a validator, converting between the defined JSON Schema types and JSON values. It is immutable: redefine, redefine_many and remove each return a new checker.
    impl Eq for TypeChecker
    impl Show for TypeChecker

    TypeChecker::is_type

    fn TypeChecker::is_type(self : TypeChecker, instance : Json, type_ : String) -> Bool raise

    Check if the instance is of the appropriate type.

    Raises UndefinedTypeCheck if type_ is unknown to this object.

    TypeChecker::new

    fn TypeChecker::new(type_checkers? : ArrayView[(String, (TypeChecker, Json) -> Bool raise)]) -> TypeChecker

    TypeChecker(type_checkers).

    TypeChecker::redefine

    fn TypeChecker::redefine(self : TypeChecker, type_ : String, f : (TypeChecker, Json) -> Bool raise) -> TypeChecker

    Produce a new checker with the given type redefined.

    TypeChecker::redefine_many

    fn TypeChecker::redefine_many(self : TypeChecker, definitions : ArrayView[(String, (TypeChecker, Json) -> Bool raise)]) -> TypeChecker

    Produce a new checker with the given types redefined.

    TypeChecker::remove

    fn TypeChecker::remove(self : TypeChecker, types : ArrayView[String]) -> TypeChecker raise UndefinedTypeCheck

    Produce a new checker with the given types forgotten.

    Raises UndefinedTypeCheck if any given type is unknown to this object.

    TypeChecker::types

    fn TypeChecker::types(self : TypeChecker) -> Array[String]

    The names of the types known to this checker, in definition order.

    ValidationError

    pub struct ValidationError {
    kind : ErrorKind
    message : String
    path : Array[PathItem]
    schema_path : Array[PathItem]
    context : Array[ValidationError]
    cause : Error?
    validator : Json?
    validator_value : Json?
    instance : Json?
    schema : Json?
    parent : ValidationError?
    // private fields
    }

    A validation error (upstream's _Error, i.e. ValidationError or SchemaError depending on kind).

    Errors are mutable, like upstream's: validators fill in details (validator, validator_value, instance, schema) as errors bubble up and prepend to the relative paths.

    The validator, validator_value, instance and schema fields are None while unset (upstream's _unset); a Python None is represented as Some(Json::null()) (e.g. validator is Some(null) for errors produced by a false schema).

    ValidationError::absolute_path

    fn ValidationError::absolute_path(self : ValidationError) -> Array[PathItem]

    The path to the offending element within the instance, from the root of the instance.

    ValidationError::absolute_schema_path

    fn ValidationError::absolute_schema_path(self : ValidationError) -> Array[PathItem]

    The path to the failing keyword within the schema, from the root schema.

    ValidationError::class_name

    fn ValidationError::class_name(self : ValidationError) -> String

    Upstream's class name for this error.

    ValidationError::create_from

    fn ValidationError::create_from(other : ValidationError, kind? : ErrorKind) -> ValidationError

    SchemaError.create_from(other): a copy of other's contents as a SchemaError (kind=Schema; the type checker is not copied).

    ValidationError::json_path

    fn ValidationError::json_path(self : ValidationError) -> String

    A JSONPath expression for the offending element (e.g. $.foo[0]).

    ValidationError::keyword

    fn ValidationError::keyword(self : ValidationError) -> String?

    The failed keyword, when it is a string.

    ValidationError::new

    fn ValidationError::new(message : String, validator? : Json, path? : ArrayView[PathItem], cause? : Error, context? : ArrayView[ValidationError], validator_value? : Json, instance? : Json, schema? : Json, schema_path? : ArrayView[PathItem], parent? : ValidationError, type_checker? : TypeChecker, kind? : ErrorKind) -> ValidationError

    Construct an error (ValidationError(message, ...) upstream).

    ValidationError::relative_path

    fn ValidationError::relative_path(self : ValidationError) -> Array[PathItem]

    relative_path: same as path.

    ValidationError::relative_schema_path

    fn ValidationError::relative_schema_path(self : ValidationError) -> Array[PathItem]

    relative_schema_path: same as schema_path.

    ValidationError::repr

    fn ValidationError::repr(self : ValidationError) -> String

    repr(error): <ValidationError: 'message'>.

    ValidationError::to_error

    The error as something that can be raised.

    Validator

    pub struct Validator {
    cls : ValidatorClass
    schema : Json
    format_checker : FormatChecker?
    // private fields
    }

    A validator for a particular schema (an instance of a validator class).
    impl Show for Validator

    Validator::descend

    fn Validator::descend(self : Validator, instance : Json, schema : Json, path? : PathItem, schema_path? : PathItem, resolver? :
    Resolver
    ) -> Errors

    Validate instance against a subschema, prefixing the errors' paths (upstream's descend).

    Validator::evolve

    fn Validator::evolve(self : Validator, schema? : Json, format_checker? : FormatChecker?, resolver? :
    Resolver
    ) -> Validator

    A copy of this validator with some attributes changed (upstream's evolve). When the schema changes, the validator class is re-selected with validator_for(schema, default=self.cls).

    Validator::is_type

    fn Validator::is_type(self : Validator, instance : Json, type_ : String) -> Bool raise

    Check if the instance is of the given (JSON Schema) type, raising UnknownType for types the type checker does not know.

    Validator::is_valid

    fn Validator::is_valid(self : Validator, instance : Json) -> Bool raise

    Whether the instance is valid under the current schema (stops at the first error).

    Validator::iter_errors

    fn Validator::iter_errors(self : Validator, instance : Json) -> Errors

    Lazily yield each of the errors in the given instance (upstream's iter_errors).

    Validator::resolver

    The resolver used for $refs in the current schema.

    Validator::validate

    fn Validator::validate(self : Validator, instance : Json) -> Unit raise

    Check if the instance is valid under the current schema, raising the first error otherwise (upstream's validate method).

    ValidatorClass

    pub struct ValidatorClass {
    name : String
    validators : Map[String, (Validator, Json, Json, Json) -> Errors]
    meta_schema : Json
    type_checker : TypeChecker
    format_checker : FormatChecker
    id_of : (Json) -> String?
    applicable_validators : (Json) -> Array[(String, Json)]
    // private fields
    }

    A validator class (upstream: the class returned by create, e.g. Draft202012Validator): the keyword implementations, meta-schema, type checker and format checker of a JSON Schema dialect.

    Create validators for a schema with ValidatorClass::new.

    ValidatorClass::check_schema

    fn ValidatorClass::check_schema(self : ValidatorClass, schema : Json, format_checker? : FormatChecker?) -> Unit raise

    Validate schema against its class's meta-schema (upstream's check_schema), raising SchemaError for the first problem found.

    Format validation of the schema uses the meta-schema's validator class's FORMAT_CHECKER unless format_checker is given.

    ValidatorClass::extend_with

    fn ValidatorClass::extend_with(cls : ValidatorClass, validators? : ArrayView[(String, (Validator, Json, Json, Json) -> Errors)], version? : String, type_checker? : TypeChecker, format_checker? : FormatChecker) -> ValidatorClass

    Create a new validator class by extending an existing one (upstream's extend; renamed as extend is reserved in MoonBit). Keyword implementations in validators replace any existing ones with the same name.

    ValidatorClass::new

    fn ValidatorClass::new(self : ValidatorClass, schema : Json, format_checker? : FormatChecker, registry? :
    Registry
    ) -> Validator raise

    Create a validator for schema (upstream: calling the class).

    registry holds the resources $refs may refer to (it is combined with specifications_registry()); format_checker enables format validation.

    best_match

    fn best_match(errors : Iter[ValidationError], key? : (ValidationError) -> Relevance) -> ValidationError?

    Try to find an error that appears to be the best match among given errors.

    In general, errors that are higher up in the instance (i.e. for which path is shorter) are considered better matches, since they indicate "more" is wrong with the instance.

    If the resulting match is either oneOf or anyOf, the opposite assumption is made -- i.e. the deepest error is picked among the most relevant errors in each separate subschema (preferring subschemas which produced fewer errors when tied).

    Returns None if there were no errors.

    by_relevance

    fn by_relevance(weak? : ArrayView[String], strong? : ArrayView[String]) -> ((ValidationError) -> Relevance)

    Create a key function that can be used to sort errors by relevance.

    weak keywords are superseded by other same-level errors; strong keywords take priority.

    create

    fn create(meta_schema~ : Json, validators? : ArrayView[(String, (Validator, Json, Json, Json) -> Errors)], version? : String, type_checker? : TypeChecker, format_checker? : FormatChecker, id_of? : (Json) -> String?, applicable_validators? : (Json) -> Array[(String, Json)]) -> ValidatorClass

    Create a new validator class (upstream's create).

    validators maps keyword names to their implementations. When a version is given, the class is named after it (version.title() minus spaces and dashes, plus Validator) and registered with validates.

    draft201909_format_checker

    let draft201909_format_checker : FormatChecker

    The format checker for draft 2019-09.

    draft201909_type_checker

    let draft201909_type_checker : TypeChecker

    The type checker for draft 2019-09.

    draft201909_validator

    let draft201909_validator : ValidatorClass

    Draft201909Validator.

    draft202012_format_checker

    let draft202012_format_checker : FormatChecker

    The format checker for draft 2020-12.

    draft202012_type_checker

    let draft202012_type_checker : TypeChecker

    The type checker for draft 2020-12.

    draft202012_validator

    let draft202012_validator : ValidatorClass

    Draft202012Validator.

    draft3_format_checker

    let draft3_format_checker : FormatChecker

    The format checker for draft 3.

    draft3_type_checker

    let draft3_type_checker : TypeChecker

    The type checker for draft 3.

    Note: like upstream, integer means a Python int, so a JSON 1.0 is not an integer under drafts 3 and 4 (see loads for how the distinction is kept).

    draft3_validator

    let draft3_validator : ValidatorClass

    Draft3Validator.

    draft4_format_checker

    let draft4_format_checker : FormatChecker

    The format checker for draft 4.

    draft4_type_checker

    let draft4_type_checker : TypeChecker

    The type checker for draft 4.

    draft4_validator

    let draft4_validator : ValidatorClass

    Draft4Validator.

    draft6_format_checker

    let draft6_format_checker : FormatChecker

    The format checker for draft 6.

    draft6_type_checker

    let draft6_type_checker : TypeChecker

    The type checker for draft 6.

    draft6_validator

    let draft6_validator : ValidatorClass

    Draft6Validator.

    draft7_format_checker

    let draft7_format_checker : FormatChecker

    The format checker for draft 7.

    draft7_type_checker

    let draft7_type_checker : TypeChecker

    The type checker for draft 7.

    draft7_validator

    let draft7_validator : ValidatorClass

    Draft7Validator.

    equal

    fn equal(one : Json, two : Json) -> Bool

    Check if two JSON values are equal with Python semantics: bool is not a number (True != 1), ints and floats compare numerically (1 == 1.0), arrays compare element-wise and objects compare irrespective of order.

    ignore_ref_siblings

    fn ignore_ref_siblings(schema : Json) -> Array[(String, Json)]

    Ignore siblings of $ref if it is present; otherwise return all keywords (upstream's ignore_ref_siblings, for create's applicable_validators).

    latest_version

    fn latest_version() -> ValidatorClass

    _LATEST_VERSION: the validator class used for schemas without a (known) $schema.

    loads

    fn loads(s : String) -> Json raise JSONDecodeError

    Parse a JSON document exactly like Python's json.loads, keeping the int / float distinction: float-like tokens (1.0, 1e3, NaN, Infinity) and integers too large for a double keep their spelling in Json::Number's repr~. Use this to load schemas and instances when the draft 3 / 4 notion of integer, or Python-exact error messages, matter.

    py_repr

    fn py_repr(value : Json) -> String

    Python's repr(x) of the value a JSON document stands for, e.g. {'a': [1, 2.5, None, True]}.

    registered_validators

    fn registered_validators() -> Map[String, ValidatorClass]

    The registered validator classes (upstream's _VALIDATORS), keyed by version name.

    relevance

    fn relevance(error : ValidationError) -> Relevance

    A key function (e.g. to sort with) which sorts errors by relevance.

    specifications_registry

    fn specifications_registry() ->
    Registry

    jsonschema_specifications.REGISTRY: all meta-schemas and vocabularies.

    strong_matches

    let strong_matches : Array[String]

    Keywords whose errors are considered strong matches by default.

    validate

    fn validate(instance : Json, schema : Json, cls? : ValidatorClass, format_checker? : FormatChecker, registry? :
    Registry
    ) -> Unit raise

    Validate an instance under the given schema (upstream's jsonschema.validate): the schema is checked first (raising SchemaError), then the best match among the instance's errors is raised as a ValidationError.

    Without cls, the validator class is chosen from the schema's $schema (see validator_for).

    validates

    fn validates(cls : ValidatorClass, version : String) -> ValidatorClass

    Register a validator class for a version of the specification (upstream's validates decorator): it is then considered when looking up $schema URIs.

    validator_for

    fn validator_for(schema : Json, default? : ValidatorClass) -> ValidatorClass

    Retrieve the validator class appropriate for validating the given schema, from its $schema keyword (upstream's validator_for).

    Schemas without (a known) $schema get default, or the latest supported draft.

    weak_matches

    let weak_matches : Array[String]

    Keywords whose errors are considered weak matches by default.