diff options
-rw-r--r-- | docs/validate.rst | 2 | ||||
-rw-r--r-- | jsonschema/__init__.py | 2 | ||||
-rw-r--r-- | jsonschema/_format.py | 30 | ||||
-rw-r--r-- | jsonschema/_legacy_validators.py | 18 | ||||
-rw-r--r-- | jsonschema/_types.py | 3 | ||||
-rw-r--r-- | jsonschema/_validators.py | 25 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09.json | 42 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09/applicator.json | 56 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09/content.json | 17 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09/core.json | 57 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09/format.json | 14 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09/hyper-schema.json | 29 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09/meta-data.json | 37 | ||||
-rw-r--r-- | jsonschema/schemas/draft2019-09/validation.json | 98 | ||||
-rw-r--r-- | jsonschema/tests/test_jsonschema_test_suite.py | 38 | ||||
-rw-r--r-- | jsonschema/validators.py | 56 |
16 files changed, 488 insertions, 36 deletions
diff --git a/docs/validate.rst b/docs/validate.rst index b9d62f7..a049bd6 100644 --- a/docs/validate.rst +++ b/docs/validate.rst @@ -237,6 +237,8 @@ which each included validator class implements. .. autoclass:: Draft202012Validator +.. autoclass:: Draft201909Validator + .. autoclass:: Draft7Validator .. autoclass:: Draft6Validator diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index c1cb2e9..c39082c 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -14,6 +14,7 @@ from jsonschema._format import ( draft4_format_checker, draft6_format_checker, draft7_format_checker, + draft201909_format_checker, draft202012_format_checker, ) from jsonschema._types import TypeChecker @@ -29,6 +30,7 @@ from jsonschema.validators import ( Draft4Validator, Draft6Validator, Draft7Validator, + Draft201909Validator, Draft202012Validator, RefResolver, validate, diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 5d610ef..1395a59 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -132,6 +132,7 @@ draft3_format_checker = FormatChecker() draft4_format_checker = FormatChecker() draft6_format_checker = FormatChecker() draft7_format_checker = FormatChecker() +draft201909_format_checker = FormatChecker() draft202012_format_checker = FormatChecker() _draft_checkers = dict( @@ -139,6 +140,7 @@ _draft_checkers = dict( draft4=draft4_format_checker, draft6=draft6_format_checker, draft7=draft7_format_checker, + draft201909=draft201909_format_checker, draft202012=draft202012_format_checker, ) @@ -149,6 +151,7 @@ def _checks_drafts( draft4=None, draft6=None, draft7=None, + draft201909=None, draft202012=None, raises=(), ): @@ -156,6 +159,7 @@ def _checks_drafts( draft4 = draft4 or name draft6 = draft6 or name draft7 = draft7 or name + draft201909 = draft201909 or name draft202012 = draft202012 or name def wrap(func): @@ -167,6 +171,10 @@ def _checks_drafts( func = _draft_checkers["draft6"].checks(draft6, raises)(func) if draft7: func = _draft_checkers["draft7"].checks(draft7, raises)(func) + if draft201909: + func = _draft_checkers["draft201909"].checks(draft201909, raises)( + func, + ) if draft202012: func = _draft_checkers["draft202012"].checks(draft202012, raises)( func, @@ -176,7 +184,8 @@ def _checks_drafts( # deprecation. See https://github.com/Julian/jsonschema/issues/519 # and test_format_checkers_come_with_defaults FormatChecker.cls_checks( - draft202012 or draft7 or draft6 or draft4 or draft3, raises, + draft202012 or draft201909 or draft7 or draft6 or draft4 or draft3, + raises, )(func) return func return wrap @@ -195,6 +204,7 @@ def is_email(instance): draft4="ipv4", draft6="ipv4", draft7="ipv4", + draft201909="ipv4", draft202012="ipv4", raises=ipaddress.AddressValueError, ) @@ -222,6 +232,7 @@ else: draft4="hostname", draft6="hostname", draft7="hostname", + draft201909="hostname", draft202012="hostname", ) def is_host_name(instance): @@ -238,6 +249,7 @@ except ImportError: # pragma: no cover else: @_checks_drafts( draft7="idn-hostname", + draft201909="idn-hostname", draft202012="idn-hostname", raises=(idna.IDNAError, UnicodeError), ) @@ -265,6 +277,7 @@ except ImportError: @_checks_drafts( draft6="uri-reference", draft7="uri-reference", + draft201909="uri-reference", draft202012="uri-reference", raises=ValueError, ) @@ -276,6 +289,7 @@ except ImportError: else: @_checks_drafts( draft7="iri", + draft201909="iri", draft202012="iri", raises=ValueError, ) @@ -286,6 +300,7 @@ else: @_checks_drafts( draft7="iri-reference", + draft201909="iri-reference", draft202012="iri-reference", raises=ValueError, ) @@ -294,10 +309,7 @@ else: return True return rfc3987.parse(instance, rule="IRI_reference") - @_checks_drafts( - name="uri", - raises=ValueError, - ) + @_checks_drafts(name="uri", raises=ValueError) def is_uri(instance): if not isinstance(instance, str): return True @@ -306,6 +318,7 @@ else: @_checks_drafts( draft6="uri-reference", draft7="uri-reference", + draft201909="uri-reference", draft202012="uri-reference", raises=ValueError, ) @@ -332,6 +345,7 @@ if validate_rfc3339: @_checks_drafts( draft7="time", + draft201909="time", draft202012="time", ) def is_time(instance): @@ -357,6 +371,7 @@ else: @_checks_drafts( draft3="date", draft7="date", + draft201909="date", draft202012="date", raises=ValueError, ) @@ -409,6 +424,7 @@ else: @_checks_drafts( draft6="json-pointer", draft7="json-pointer", + draft201909="json-pointer", draft202012="json-pointer", raises=jsonpointer.JsonPointerException, ) @@ -423,6 +439,7 @@ else: # into a new external library. @_checks_drafts( draft7="relative-json-pointer", + draft201909="relative-json-pointer", draft202012="relative-json-pointer", raises=jsonpointer.JsonPointerException, ) @@ -457,6 +474,7 @@ else: @_checks_drafts( draft6="uri-template", draft7="uri-template", + draft201909="uri-template", draft202012="uri-template", ) def is_uri_template(instance): @@ -471,6 +489,7 @@ except ImportError: # pragma: no cover pass else: @_checks_drafts( + draft201909="duration", draft202012="duration", raises=isoduration.DurationParsingException, ) @@ -481,6 +500,7 @@ else: @_checks_drafts( + draft201909="uuid", draft202012="uuid", raises=ValueError, ) diff --git a/jsonschema/_legacy_validators.py b/jsonschema/_legacy_validators.py index 63adf49..88e7c33 100644 --- a/jsonschema/_legacy_validators.py +++ b/jsonschema/_legacy_validators.py @@ -106,7 +106,7 @@ def items_draft3_draft4(validator, items, instance, schema): yield error -def items_draft6_draft7(validator, items, instance, schema): +def items_draft6_draft7_draft201909(validator, items, instance, schema): if not validator.is_type(instance, "array"): return @@ -209,3 +209,19 @@ def contains_draft6_draft7(validator, contains, instance, schema): yield ValidationError( "None of %r are valid under the given schema" % (instance,), ) + + +def recursiveRef(validator, recursiveRef, instance, schema): + scope_stack = validator.resolver.scopes_stack_copy + lookup_url, target = validator.resolver.resolution_scope, validator.schema + + for each in reversed(scope_stack[1:]): + lookup_url, next_target = validator.resolver.resolve(each) + if next_target.get("$recursiveAnchor"): + target = next_target + else: + break + + subschema = validator.resolver.resolve_local(recursiveRef, target) + for error in validator.descend(instance, subschema): + yield error diff --git a/jsonschema/_types.py b/jsonschema/_types.py index 3eab7b0..988fcca 100644 --- a/jsonschema/_types.py +++ b/jsonschema/_types.py @@ -185,4 +185,5 @@ draft6_type_checker = draft4_type_checker.redefine( ), ) draft7_type_checker = draft6_type_checker -draft202012_type_checker = draft7_type_checker +draft201909_type_checker = draft7_type_checker +draft202012_type_checker = draft201909_type_checker diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index 77063fa..d2f699f 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -342,35 +342,18 @@ def dynamicRef(validator, dynamicRef, instance, schema): for url in scope_stack: lookup_url = urljoin(url, dynamicRef) - with validator.resolver.resolving(lookup_url) as lookup_schema: - if ("$dynamicAnchor" in lookup_schema - and fragment == lookup_schema["$dynamicAnchor"]): - subschema = lookup_schema + with validator.resolver.resolving(lookup_url) as subschema: + if ("$dynamicAnchor" in subschema + and fragment == subschema["$dynamicAnchor"]): for error in validator.descend(instance, subschema): yield error break else: - with validator.resolver.resolving(dynamicRef) as lookup_schema: - subschema = lookup_schema + with validator.resolver.resolving(dynamicRef) as subschema: for error in validator.descend(instance, subschema): yield error -def defs(validator, defs, instance, schema): - if not validator.is_type(instance, "object"): - return - - if '$defs' in instance: - for definition, subschema in instance['$defs'].items(): - for error in validator.descend( - subschema, - schema, - path=definition, - schema_path=definition, - ): - yield error - - def type(validator, types, instance, schema): types = ensure_list(types) diff --git a/jsonschema/schemas/draft2019-09.json b/jsonschema/schemas/draft2019-09.json new file mode 100644 index 0000000..2248a0c --- /dev/null +++ b/jsonschema/schemas/draft2019-09.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/schema", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/core": true, + "https://json-schema.org/draft/2019-09/vocab/applicator": true, + "https://json-schema.org/draft/2019-09/vocab/validation": true, + "https://json-schema.org/draft/2019-09/vocab/meta-data": true, + "https://json-schema.org/draft/2019-09/vocab/format": false, + "https://json-schema.org/draft/2019-09/vocab/content": true + }, + "$recursiveAnchor": true, + + "title": "Core and Validation specifications meta-schema", + "allOf": [ + {"$ref": "meta/core"}, + {"$ref": "meta/applicator"}, + {"$ref": "meta/validation"}, + {"$ref": "meta/meta-data"}, + {"$ref": "meta/format"}, + {"$ref": "meta/content"} + ], + "type": ["object", "boolean"], + "properties": { + "definitions": { + "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.", + "type": "object", + "additionalProperties": { "$recursiveRef": "#" }, + "default": {} + }, + "dependencies": { + "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"", + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$recursiveRef": "#" }, + { "$ref": "meta/validation#/$defs/stringArray" } + ] + } + } + } +} diff --git a/jsonschema/schemas/draft2019-09/applicator.json b/jsonschema/schemas/draft2019-09/applicator.json new file mode 100644 index 0000000..24a1cc4 --- /dev/null +++ b/jsonschema/schemas/draft2019-09/applicator.json @@ -0,0 +1,56 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/applicator", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/applicator": true + }, + "$recursiveAnchor": true, + + "title": "Applicator vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "additionalItems": { "$recursiveRef": "#" }, + "unevaluatedItems": { "$recursiveRef": "#" }, + "items": { + "anyOf": [ + { "$recursiveRef": "#" }, + { "$ref": "#/$defs/schemaArray" } + ] + }, + "contains": { "$recursiveRef": "#" }, + "additionalProperties": { "$recursiveRef": "#" }, + "unevaluatedProperties": { "$recursiveRef": "#" }, + "properties": { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" }, + "propertyNames": { "format": "regex" }, + "default": {} + }, + "dependentSchemas": { + "type": "object", + "additionalProperties": { + "$recursiveRef": "#" + } + }, + "propertyNames": { "$recursiveRef": "#" }, + "if": { "$recursiveRef": "#" }, + "then": { "$recursiveRef": "#" }, + "else": { "$recursiveRef": "#" }, + "allOf": { "$ref": "#/$defs/schemaArray" }, + "anyOf": { "$ref": "#/$defs/schemaArray" }, + "oneOf": { "$ref": "#/$defs/schemaArray" }, + "not": { "$recursiveRef": "#" } + }, + "$defs": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { "$recursiveRef": "#" } + } + } +} diff --git a/jsonschema/schemas/draft2019-09/content.json b/jsonschema/schemas/draft2019-09/content.json new file mode 100644 index 0000000..f6752a8 --- /dev/null +++ b/jsonschema/schemas/draft2019-09/content.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/content", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/content": true + }, + "$recursiveAnchor": true, + + "title": "Content vocabulary meta-schema", + + "type": ["object", "boolean"], + "properties": { + "contentMediaType": { "type": "string" }, + "contentEncoding": { "type": "string" }, + "contentSchema": { "$recursiveRef": "#" } + } +} diff --git a/jsonschema/schemas/draft2019-09/core.json b/jsonschema/schemas/draft2019-09/core.json new file mode 100644 index 0000000..eb708a5 --- /dev/null +++ b/jsonschema/schemas/draft2019-09/core.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/core", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/core": true + }, + "$recursiveAnchor": true, + + "title": "Core vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference", + "$comment": "Non-empty fragments not allowed.", + "pattern": "^[^#]*#?$" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$anchor": { + "type": "string", + "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "$recursiveRef": { + "type": "string", + "format": "uri-reference" + }, + "$recursiveAnchor": { + "type": "boolean", + "default": false + }, + "$vocabulary": { + "type": "object", + "propertyNames": { + "type": "string", + "format": "uri" + }, + "additionalProperties": { + "type": "boolean" + } + }, + "$comment": { + "type": "string" + }, + "$defs": { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" }, + "default": {} + } + } +} diff --git a/jsonschema/schemas/draft2019-09/format.json b/jsonschema/schemas/draft2019-09/format.json new file mode 100644 index 0000000..09bbfdd --- /dev/null +++ b/jsonschema/schemas/draft2019-09/format.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/format", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/format": true + }, + "$recursiveAnchor": true, + + "title": "Format vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "format": { "type": "string" } + } +} diff --git a/jsonschema/schemas/draft2019-09/hyper-schema.json b/jsonschema/schemas/draft2019-09/hyper-schema.json new file mode 100644 index 0000000..3d23058 --- /dev/null +++ b/jsonschema/schemas/draft2019-09/hyper-schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", + "$id": "https://json-schema.org/draft/2019-09/meta/hyper-schema", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/hyper-schema": true + }, + "$recursiveAnchor": true, + + "title": "JSON Hyper-Schema Vocabulary Schema", + "type": ["object", "boolean"], + "properties": { + "base": { + "type": "string", + "format": "uri-template" + }, + "links": { + "type": "array", + "items": { + "$ref": "https://json-schema.org/draft/2019-09/links" + } + } + }, + "links": [ + { + "rel": "self", + "href": "{+%24id}" + } + ] +} diff --git a/jsonschema/schemas/draft2019-09/meta-data.json b/jsonschema/schemas/draft2019-09/meta-data.json new file mode 100644 index 0000000..da04cff --- /dev/null +++ b/jsonschema/schemas/draft2019-09/meta-data.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/meta-data", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/meta-data": true + }, + "$recursiveAnchor": true, + + "title": "Meta-data vocabulary meta-schema", + + "type": ["object", "boolean"], + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": true, + "deprecated": { + "type": "boolean", + "default": false + }, + "readOnly": { + "type": "boolean", + "default": false + }, + "writeOnly": { + "type": "boolean", + "default": false + }, + "examples": { + "type": "array", + "items": true + } + } +} diff --git a/jsonschema/schemas/draft2019-09/validation.json b/jsonschema/schemas/draft2019-09/validation.json new file mode 100644 index 0000000..9f59677 --- /dev/null +++ b/jsonschema/schemas/draft2019-09/validation.json @@ -0,0 +1,98 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/validation", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/validation": true + }, + "$recursiveAnchor": true, + + "title": "Validation vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": { "$ref": "#/$defs/nonNegativeInteger" }, + "minLength": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, + "pattern": { + "type": "string", + "format": "regex" + }, + "maxItems": { "$ref": "#/$defs/nonNegativeInteger" }, + "minItems": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, + "minContains": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 1 + }, + "maxProperties": { "$ref": "#/$defs/nonNegativeInteger" }, + "minProperties": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, + "required": { "$ref": "#/$defs/stringArray" }, + "dependentRequired": { + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/stringArray" + } + }, + "const": true, + "enum": { + "type": "array", + "items": true + }, + "type": { + "anyOf": [ + { "$ref": "#/$defs/simpleTypes" }, + { + "type": "array", + "items": { "$ref": "#/$defs/simpleTypes" }, + "minItems": 1, + "uniqueItems": true + } + ] + } + }, + "$defs": { + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 0 + }, + "simpleTypes": { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" + ] + }, + "stringArray": { + "type": "array", + "items": { "type": "string" }, + "uniqueItems": true, + "default": [] + } + } +} diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index c0ddddd..22dab75 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -13,11 +13,13 @@ from jsonschema import ( Draft4Validator, Draft6Validator, Draft7Validator, + Draft201909Validator, Draft202012Validator, draft3_format_checker, draft4_format_checker, draft6_format_checker, draft7_format_checker, + draft201909_format_checker, draft202012_format_checker, ) from jsonschema.tests._helpers import bug @@ -28,6 +30,7 @@ DRAFT3 = SUITE.version(name="draft3") DRAFT4 = SUITE.version(name="draft4") DRAFT6 = SUITE.version(name="draft6") DRAFT7 = SUITE.version(name="draft7") +DRAFT201909 = SUITE.version(name="draft2019-09") DRAFT202012 = SUITE.version(name="draft2020-12") @@ -403,6 +406,41 @@ TestDraft7 = DRAFT7.to_unittest_testcase( ) +TestDraft201909 = DRAFT201909.to_unittest_testcase( + DRAFT201909.tests(), + DRAFT201909.optional_tests_of(name="bignum"), + DRAFT201909.optional_tests_of(name="float-overflow"), + DRAFT201909.optional_tests_of(name="non-bmp-regex"), + DRAFT201909.optional_tests_of(name="refOfUnknownKeyword"), + Validator=Draft201909Validator, + skip=lambda test: ( + skip( + message="unevaluatedItems is different in 2019-09 (needs work).", + subject="unevaluatedItems", + )(test) + or skip( + message="dynamicRef support isn't working yet.", + subject="recursiveRef", + )(test) + ), +) + + +TestDraft201909Format = DRAFT201909.to_unittest_testcase( + DRAFT201909.format_tests(), + Validator=Draft201909Validator, + format_checker=draft201909_format_checker, + skip=lambda test: ( + complex_email_validation(test) + or missing_date_fromisoformat(test) + or allowed_leading_zeros(test) + or leap_second(test) + or missing_format(draft201909_format_checker)(test) + or complex_email_validation(test) + ), +) + + TestDraft202012 = DRAFT202012.to_unittest_testcase( DRAFT202012.tests(), DRAFT202012.optional_tests_of(name="bignum"), diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 3c28b8d..295cf6f 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -145,12 +145,7 @@ def create( TYPE_CHECKER = type_checker ID_OF = staticmethod(id_of) - def __init__( - self, - schema, - resolver=None, - format_checker=None, - ): + def __init__(self, schema, resolver=None, format_checker=None): if resolver is None: resolver = RefResolver.from_schema(schema, id_of=id_of) @@ -385,7 +380,7 @@ Draft6Validator = create( "exclusiveMaximum": _validators.exclusiveMaximum, "exclusiveMinimum": _validators.exclusiveMinimum, "format": _validators.format, - "items": _legacy_validators.items_draft6_draft7, + "items": _legacy_validators.items_draft6_draft7_draft201909, "maxItems": _validators.maxItems, "maxLength": _validators.maxLength, "maxProperties": _validators.maxProperties, @@ -426,7 +421,7 @@ Draft7Validator = create( "exclusiveMinimum": _validators.exclusiveMinimum, "format": _validators.format, "if": _validators.if_, - "items": _legacy_validators.items_draft6_draft7, + "items": _legacy_validators.items_draft6_draft7_draft201909, "maxItems": _validators.maxItems, "maxLength": _validators.maxLength, "maxProperties": _validators.maxProperties, @@ -451,6 +446,51 @@ Draft7Validator = create( applicable_validators=_legacy_validators.ignore_ref_siblings, ) +Draft201909Validator = create( + meta_schema=_utils.load_schema("draft2019-09"), + vocabulary_schemas=_utils.load_vocabulary("draft2019-09"), + validators={ + "$ref": _validators.ref, + "$recursiveRef": _legacy_validators.recursiveRef, + "additionalItems": _validators.additionalItems, + "additionalProperties": _validators.additionalProperties, + "allOf": _validators.allOf, + "anyOf": _validators.anyOf, + "const": _validators.const, + "contains": _validators.contains, + "dependentRequired": _validators.dependentRequired, + "dependentSchemas": _validators.dependentSchemas, + "enum": _validators.enum, + "exclusiveMaximum": _validators.exclusiveMaximum, + "exclusiveMinimum": _validators.exclusiveMinimum, + "format": _validators.format, + "if": _validators.if_, + "items": _legacy_validators.items_draft6_draft7_draft201909, + "maxItems": _validators.maxItems, + "maxLength": _validators.maxLength, + "maxProperties": _validators.maxProperties, + "maximum": _validators.maximum, + "minItems": _validators.minItems, + "minLength": _validators.minLength, + "minProperties": _validators.minProperties, + "minimum": _validators.minimum, + "multipleOf": _validators.multipleOf, + "not": _validators.not_, + "oneOf": _validators.oneOf, + "pattern": _validators.pattern, + "patternProperties": _validators.patternProperties, + "properties": _validators.properties, + "propertyNames": _validators.propertyNames, + "required": _validators.required, + "type": _validators.type, + "unevaluatedItems": _validators.unevaluatedItems, + "unevaluatedProperties": _validators.unevaluatedProperties, + "uniqueItems": _validators.uniqueItems, + }, + type_checker=_types.draft201909_type_checker, + version="draft2019-09", +) + Draft202012Validator = create( meta_schema=_utils.load_schema("draft2020-12"), vocabulary_schemas=_utils.load_vocabulary("draft2020-12"), |