summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.coveragerc10
-rw-r--r--.flake810
-rw-r--r--.github/CODEOWNERS (renamed from json/.github/CODEOWNERS)0
-rw-r--r--.github/FUNDING.yml4
-rw-r--r--.github/SECURITY.md21
-rw-r--r--.github/workflows/ci.yml227
-rw-r--r--.github/workflows/coverage.yml25
-rw-r--r--.github/workflows/fuzz.yml30
-rw-r--r--.gitignore17
-rw-r--r--.pre-commit-config.yaml22
-rw-r--r--.pre-commit-hooks.yaml6
-rw-r--r--.readthedocs.yml15
-rw-r--r--CHANGELOG.rst369
-rw-r--r--CONTRIBUTING.rst60
-rw-r--r--COPYING19
-rw-r--r--LICENSE (renamed from json/LICENSE)0
-rw-r--r--README.md (renamed from json/README.md)0
-rw-r--r--README.rst148
-rwxr-xr-xbin/jsonschema_suite (renamed from json/bin/jsonschema_suite)136
-rw-r--r--codecov.yml5
-rw-r--r--docs/Makefile227
-rw-r--r--docs/conf.py254
-rw-r--r--docs/creating.rst34
-rw-r--r--docs/errors.rst406
-rw-r--r--docs/faq.rst291
-rw-r--r--docs/index.rst22
-rw-r--r--docs/jsonschema_role.py146
-rw-r--r--docs/make.bat190
-rw-r--r--docs/references.rst13
-rw-r--r--docs/requirements.in6
-rw-r--r--docs/requirements.txt81
-rw-r--r--docs/spelling-wordlist.txt45
-rw-r--r--docs/validate.rst288
-rw-r--r--json/.github/workflows/ci.yml25
-rw-r--r--json/.gitignore160
-rw-r--r--json/tests/draft3/optional/bignum.json107
-rw-r--r--json/tests/draft6/optional/format/date-time.json133
-rw-r--r--json/tests/draft6/optional/format/ipv4.json84
-rw-r--r--json/tests/draft6/optional/format/ipv6.json208
-rw-r--r--json/tests/draft7/anyOf.json215
-rw-r--r--json/tests/draft7/optional/bignum.json93
-rw-r--r--json/tests/draft7/optional/format/date-time.json133
-rw-r--r--json/tests/draft7/optional/format/ipv4.json84
-rw-r--r--json/tests/draft7/optional/format/ipv6.json208
-rw-r--r--json/tox.ini9
-rw-r--r--jsonschema/__init__.py58
-rw-r--r--jsonschema/__main__.py3
-rw-r--r--jsonschema/_format.py498
-rw-r--r--jsonschema/_legacy_validators.py228
-rw-r--r--jsonschema/_types.py217
-rw-r--r--jsonschema/_utils.py348
-rw-r--r--jsonschema/_validators.py467
-rw-r--r--jsonschema/benchmarks/__init__.py5
-rw-r--r--jsonschema/benchmarks/issue232.py25
-rw-r--r--jsonschema/benchmarks/issue232/issue.json2653
-rw-r--r--jsonschema/benchmarks/json_schema_test_suite.py12
-rw-r--r--jsonschema/cli.py288
-rw-r--r--jsonschema/exceptions.py393
-rw-r--r--jsonschema/protocols.py171
-rw-r--r--jsonschema/schemas/draft2019-09.json42
-rw-r--r--jsonschema/schemas/draft2020-12.json58
-rw-r--r--jsonschema/schemas/draft3.json177
-rw-r--r--jsonschema/schemas/draft4.json149
-rw-r--r--jsonschema/schemas/draft6.json153
-rw-r--r--jsonschema/schemas/draft7.json166
-rw-r--r--jsonschema/schemas/vocabularies.json1
-rw-r--r--jsonschema/tests/__init__.py0
-rw-r--r--jsonschema/tests/_helpers.py5
-rw-r--r--jsonschema/tests/_suite.py231
-rw-r--r--jsonschema/tests/fuzz_validate.py50
-rw-r--r--jsonschema/tests/test_cli.py911
-rw-r--r--jsonschema/tests/test_deprecations.py123
-rw-r--r--jsonschema/tests/test_exceptions.py588
-rw-r--r--jsonschema/tests/test_format.py107
-rw-r--r--jsonschema/tests/test_jsonschema_test_suite.py446
-rw-r--r--jsonschema/tests/test_types.py217
-rw-r--r--jsonschema/tests/test_utils.py124
-rw-r--r--jsonschema/tests/test_validators.py2183
-rw-r--r--jsonschema/validators.py1099
-rw-r--r--package.json (renamed from json/package.json)0
-rw-r--r--pyproject.toml99
-rw-r--r--remotes/baseUriChange/folderInteger.json (renamed from json/remotes/baseUriChange/folderInteger.json)0
-rw-r--r--remotes/baseUriChangeFolder/folderInteger.json (renamed from json/remotes/baseUriChangeFolder/folderInteger.json)0
-rw-r--r--remotes/baseUriChangeFolderInSubschema/folderInteger.json (renamed from json/remotes/baseUriChangeFolderInSubschema/folderInteger.json)0
-rw-r--r--remotes/draft-next/format-assertion-false.json (renamed from json/remotes/draft-next/format-assertion-false.json)0
-rw-r--r--remotes/draft-next/format-assertion-true.json (renamed from json/remotes/draft-next/format-assertion-true.json)0
-rw-r--r--remotes/draft-next/metaschema-no-validation.json (renamed from json/remotes/draft-next/metaschema-no-validation.json)0
-rw-r--r--remotes/draft2019-09/metaschema-no-validation.json (renamed from json/remotes/draft2019-09/metaschema-no-validation.json)0
-rw-r--r--remotes/draft2020-12/format-assertion-false.json (renamed from json/remotes/draft2020-12/format-assertion-false.json)0
-rw-r--r--remotes/draft2020-12/format-assertion-true.json (renamed from json/remotes/draft2020-12/format-assertion-true.json)0
-rw-r--r--remotes/draft2020-12/metaschema-no-validation.json (renamed from json/remotes/draft2020-12/metaschema-no-validation.json)0
-rw-r--r--remotes/extendible-dynamic-ref.json (renamed from json/remotes/extendible-dynamic-ref.json)0
-rw-r--r--remotes/integer.json (renamed from json/remotes/integer.json)0
-rw-r--r--remotes/locationIndependentIdentifier.json (renamed from json/remotes/locationIndependentIdentifier.json)0
-rw-r--r--remotes/locationIndependentIdentifierDraft4.json (renamed from json/remotes/locationIndependentIdentifierDraft4.json)0
-rw-r--r--remotes/locationIndependentIdentifierPre2019.json (renamed from json/remotes/locationIndependentIdentifierPre2019.json)0
-rw-r--r--remotes/name-defs.json (renamed from json/remotes/name-defs.json)0
-rw-r--r--remotes/name.json (renamed from json/remotes/name.json)0
-rw-r--r--remotes/nested/foo-ref-string.json (renamed from json/remotes/nested/foo-ref-string.json)0
-rw-r--r--remotes/nested/string.json (renamed from json/remotes/nested/string.json)0
-rw-r--r--remotes/ref-and-definitions.json (renamed from json/remotes/ref-and-definitions.json)0
-rw-r--r--remotes/ref-and-defs.json (renamed from json/remotes/ref-and-defs.json)0
-rw-r--r--remotes/subSchemas-defs.json (renamed from json/remotes/subSchemas-defs.json)0
-rw-r--r--remotes/subSchemas.json (renamed from json/remotes/subSchemas.json)0
-rw-r--r--remotes/tree.json (renamed from json/remotes/tree.json)0
-rw-r--r--test-schema.json (renamed from json/test-schema.json)0
-rw-r--r--tests/draft-next/additionalProperties.json (renamed from json/tests/draft-next/additionalProperties.json)0
-rw-r--r--tests/draft-next/allOf.json (renamed from json/tests/draft-next/allOf.json)0
-rw-r--r--tests/draft-next/anchor.json (renamed from json/tests/draft-next/anchor.json)4
-rw-r--r--tests/draft-next/anyOf.json (renamed from json/tests/draft-next/anyOf.json)0
-rw-r--r--tests/draft-next/boolean_schema.json (renamed from json/tests/draft-next/boolean_schema.json)0
-rw-r--r--tests/draft-next/const.json (renamed from json/tests/draft-next/const.json)0
-rw-r--r--tests/draft-next/contains.json (renamed from json/tests/draft-next/contains.json)0
-rw-r--r--tests/draft-next/content.json (renamed from json/tests/draft-next/content.json)0
-rw-r--r--tests/draft-next/default.json (renamed from json/tests/draft-next/default.json)0
-rw-r--r--tests/draft-next/defs.json (renamed from json/tests/draft-next/defs.json)0
-rw-r--r--tests/draft-next/dependentRequired.json (renamed from json/tests/draft-next/dependentRequired.json)0
-rw-r--r--tests/draft-next/dependentSchemas.json (renamed from json/tests/draft-next/dependentSchemas.json)0
-rw-r--r--tests/draft-next/dynamicRef.json (renamed from json/tests/draft-next/dynamicRef.json)4
-rw-r--r--tests/draft-next/enum.json (renamed from json/tests/draft-next/enum.json)0
-rw-r--r--tests/draft-next/exclusiveMaximum.json (renamed from json/tests/draft-next/exclusiveMaximum.json)0
-rw-r--r--tests/draft-next/exclusiveMinimum.json (renamed from json/tests/draft-next/exclusiveMinimum.json)0
-rw-r--r--tests/draft-next/format.json (renamed from json/tests/draft-next/format.json)0
-rw-r--r--tests/draft-next/id.json (renamed from json/tests/draft-next/id.json)0
-rw-r--r--tests/draft-next/if-then-else.json (renamed from json/tests/draft-next/if-then-else.json)0
-rw-r--r--tests/draft-next/infinite-loop-detection.json (renamed from json/tests/draft-next/infinite-loop-detection.json)0
-rw-r--r--tests/draft-next/items.json (renamed from json/tests/draft-next/items.json)10
-rw-r--r--tests/draft-next/maxContains.json (renamed from json/tests/draft-next/maxContains.json)0
-rw-r--r--tests/draft-next/maxItems.json (renamed from json/tests/draft-next/maxItems.json)0
-rw-r--r--tests/draft-next/maxLength.json (renamed from json/tests/draft-next/maxLength.json)0
-rw-r--r--tests/draft-next/maxProperties.json (renamed from json/tests/draft-next/maxProperties.json)0
-rw-r--r--tests/draft-next/maximum.json (renamed from json/tests/draft-next/maximum.json)0
-rw-r--r--tests/draft-next/minContains.json (renamed from json/tests/draft-next/minContains.json)0
-rw-r--r--tests/draft-next/minItems.json (renamed from json/tests/draft-next/minItems.json)0
-rw-r--r--tests/draft-next/minLength.json (renamed from json/tests/draft-next/minLength.json)0
-rw-r--r--tests/draft-next/minProperties.json (renamed from json/tests/draft-next/minProperties.json)0
-rw-r--r--tests/draft-next/minimum.json (renamed from json/tests/draft-next/minimum.json)0
-rw-r--r--tests/draft-next/multipleOf.json (renamed from json/tests/draft-next/multipleOf.json)0
-rw-r--r--tests/draft-next/not.json (renamed from json/tests/draft-next/not.json)0
-rw-r--r--tests/draft-next/oneOf.json (renamed from json/tests/draft-next/oneOf.json)0
-rw-r--r--tests/draft-next/optional/bignum.json (renamed from json/tests/draft2020-12/optional/bignum.json)4
-rw-r--r--tests/draft-next/optional/dependencies-compatibility.json (renamed from json/tests/draft-next/optional/dependencies-compatibility.json)0
-rw-r--r--tests/draft-next/optional/ecmascript-regex.json (renamed from json/tests/draft-next/optional/ecmascript-regex.json)12
-rw-r--r--tests/draft-next/optional/float-overflow.json (renamed from json/tests/draft-next/optional/float-overflow.json)0
-rw-r--r--tests/draft-next/optional/format-assertion.json (renamed from json/tests/draft-next/optional/format-assertion.json)0
-rw-r--r--tests/draft-next/optional/format/date-time.json (renamed from json/tests/draft2020-12/optional/format/date-time.json)4
-rw-r--r--tests/draft-next/optional/format/date.json (renamed from json/tests/draft2019-09/optional/format/date.json)2
-rw-r--r--tests/draft-next/optional/format/duration.json (renamed from json/tests/draft2019-09/optional/format/duration.json)2
-rw-r--r--tests/draft-next/optional/format/email.json (renamed from json/tests/draft-next/optional/format/email.json)0
-rw-r--r--tests/draft-next/optional/format/hostname.json (renamed from json/tests/draft-next/optional/format/hostname.json)0
-rw-r--r--tests/draft-next/optional/format/idn-email.json (renamed from json/tests/draft-next/optional/format/idn-email.json)0
-rw-r--r--tests/draft-next/optional/format/idn-hostname.json (renamed from json/tests/draft-next/optional/format/idn-hostname.json)0
-rw-r--r--tests/draft-next/optional/format/ipv4.json (renamed from json/tests/draft2019-09/optional/format/ipv4.json)4
-rw-r--r--tests/draft-next/optional/format/ipv6.json (renamed from json/tests/draft-next/optional/format/ipv6.json)4
-rw-r--r--tests/draft-next/optional/format/iri-reference.json (renamed from json/tests/draft-next/optional/format/iri-reference.json)0
-rw-r--r--tests/draft-next/optional/format/iri.json (renamed from json/tests/draft-next/optional/format/iri.json)0
-rw-r--r--tests/draft-next/optional/format/json-pointer.json (renamed from json/tests/draft-next/optional/format/json-pointer.json)0
-rw-r--r--tests/draft-next/optional/format/regex.json (renamed from json/tests/draft-next/optional/format/regex.json)0
-rw-r--r--tests/draft-next/optional/format/relative-json-pointer.json (renamed from json/tests/draft-next/optional/format/relative-json-pointer.json)0
-rw-r--r--tests/draft-next/optional/format/time.json (renamed from json/tests/draft2020-12/optional/format/time.json)2
-rw-r--r--tests/draft-next/optional/format/uri-reference.json (renamed from json/tests/draft-next/optional/format/uri-reference.json)0
-rw-r--r--tests/draft-next/optional/format/uri-template.json (renamed from json/tests/draft-next/optional/format/uri-template.json)0
-rw-r--r--tests/draft-next/optional/format/uri.json (renamed from json/tests/draft-next/optional/format/uri.json)0
-rw-r--r--tests/draft-next/optional/format/uuid.json (renamed from json/tests/draft-next/optional/format/uuid.json)0
-rw-r--r--tests/draft-next/optional/non-bmp-regex.json (renamed from json/tests/draft-next/optional/non-bmp-regex.json)0
-rw-r--r--tests/draft-next/optional/refOfUnknownKeyword.json (renamed from json/tests/draft-next/optional/refOfUnknownKeyword.json)0
-rw-r--r--tests/draft-next/pattern.json (renamed from json/tests/draft-next/pattern.json)0
-rw-r--r--tests/draft-next/patternProperties.json (renamed from json/tests/draft-next/patternProperties.json)0
-rw-r--r--tests/draft-next/prefixItems.json (renamed from json/tests/draft2020-12/prefixItems.json)2
-rw-r--r--tests/draft-next/properties.json (renamed from json/tests/draft-next/properties.json)0
-rw-r--r--tests/draft-next/propertyNames.json (renamed from json/tests/draft-next/propertyNames.json)0
-rw-r--r--tests/draft-next/ref.json (renamed from json/tests/draft-next/ref.json)4
-rw-r--r--tests/draft-next/refRemote.json (renamed from json/tests/draft-next/refRemote.json)0
-rw-r--r--tests/draft-next/required.json (renamed from json/tests/draft-next/required.json)0
-rw-r--r--tests/draft-next/type.json (renamed from json/tests/draft-next/type.json)0
-rw-r--r--tests/draft-next/unevaluatedItems.json (renamed from json/tests/draft-next/unevaluatedItems.json)0
-rw-r--r--tests/draft-next/unevaluatedProperties.json (renamed from json/tests/draft-next/unevaluatedProperties.json)0
-rw-r--r--tests/draft-next/uniqueItems.json (renamed from json/tests/draft-next/uniqueItems.json)0
-rw-r--r--tests/draft-next/unknownKeyword.json (renamed from json/tests/draft-next/unknownKeyword.json)0
-rw-r--r--tests/draft-next/vocabulary.json (renamed from json/tests/draft-next/vocabulary.json)0
-rw-r--r--tests/draft2019-09/additionalItems.json (renamed from json/tests/draft2019-09/additionalItems.json)0
-rw-r--r--tests/draft2019-09/additionalProperties.json (renamed from json/tests/draft2019-09/additionalProperties.json)0
-rw-r--r--tests/draft2019-09/allOf.json (renamed from json/tests/draft2019-09/allOf.json)0
-rw-r--r--tests/draft2019-09/anchor.json (renamed from json/tests/draft2019-09/anchor.json)4
-rw-r--r--tests/draft2019-09/anyOf.json (renamed from json/tests/draft2019-09/anyOf.json)0
-rw-r--r--tests/draft2019-09/boolean_schema.json (renamed from json/tests/draft2019-09/boolean_schema.json)0
-rw-r--r--tests/draft2019-09/const.json (renamed from json/tests/draft2019-09/const.json)0
-rw-r--r--tests/draft2019-09/contains.json (renamed from json/tests/draft2019-09/contains.json)0
-rw-r--r--tests/draft2019-09/content.json (renamed from json/tests/draft2019-09/content.json)0
-rw-r--r--tests/draft2019-09/default.json (renamed from json/tests/draft2019-09/default.json)0
-rw-r--r--tests/draft2019-09/defs.json (renamed from json/tests/draft2019-09/defs.json)0
-rw-r--r--tests/draft2019-09/dependentRequired.json (renamed from json/tests/draft2019-09/dependentRequired.json)0
-rw-r--r--tests/draft2019-09/dependentSchemas.json (renamed from json/tests/draft2019-09/dependentSchemas.json)0
-rw-r--r--tests/draft2019-09/enum.json (renamed from json/tests/draft2019-09/enum.json)0
-rw-r--r--tests/draft2019-09/exclusiveMaximum.json (renamed from json/tests/draft2019-09/exclusiveMaximum.json)0
-rw-r--r--tests/draft2019-09/exclusiveMinimum.json (renamed from json/tests/draft2019-09/exclusiveMinimum.json)0
-rw-r--r--tests/draft2019-09/format.json (renamed from json/tests/draft2019-09/format.json)0
-rw-r--r--tests/draft2019-09/id.json (renamed from json/tests/draft2019-09/id.json)0
-rw-r--r--tests/draft2019-09/if-then-else.json (renamed from json/tests/draft2019-09/if-then-else.json)0
-rw-r--r--tests/draft2019-09/infinite-loop-detection.json (renamed from json/tests/draft2019-09/infinite-loop-detection.json)0
-rw-r--r--tests/draft2019-09/items.json (renamed from json/tests/draft2019-09/items.json)4
-rw-r--r--tests/draft2019-09/maxContains.json (renamed from json/tests/draft2019-09/maxContains.json)0
-rw-r--r--tests/draft2019-09/maxItems.json (renamed from json/tests/draft2019-09/maxItems.json)0
-rw-r--r--tests/draft2019-09/maxLength.json (renamed from json/tests/draft2019-09/maxLength.json)0
-rw-r--r--tests/draft2019-09/maxProperties.json (renamed from json/tests/draft2019-09/maxProperties.json)0
-rw-r--r--tests/draft2019-09/maximum.json (renamed from json/tests/draft2019-09/maximum.json)0
-rw-r--r--tests/draft2019-09/minContains.json (renamed from json/tests/draft2019-09/minContains.json)0
-rw-r--r--tests/draft2019-09/minItems.json (renamed from json/tests/draft2019-09/minItems.json)0
-rw-r--r--tests/draft2019-09/minLength.json (renamed from json/tests/draft2019-09/minLength.json)0
-rw-r--r--tests/draft2019-09/minProperties.json (renamed from json/tests/draft2019-09/minProperties.json)0
-rw-r--r--tests/draft2019-09/minimum.json (renamed from json/tests/draft2019-09/minimum.json)0
-rw-r--r--tests/draft2019-09/multipleOf.json (renamed from json/tests/draft2019-09/multipleOf.json)0
-rw-r--r--tests/draft2019-09/not.json (renamed from json/tests/draft2019-09/not.json)0
-rw-r--r--tests/draft2019-09/oneOf.json (renamed from json/tests/draft2019-09/oneOf.json)0
-rw-r--r--tests/draft2019-09/optional/bignum.json (renamed from json/tests/draft2019-09/optional/bignum.json)4
-rw-r--r--tests/draft2019-09/optional/dependencies-compatibility.json (renamed from json/tests/draft2019-09/optional/dependencies-compatibility.json)0
-rw-r--r--tests/draft2019-09/optional/ecmascript-regex.json (renamed from json/tests/draft2019-09/optional/ecmascript-regex.json)12
-rw-r--r--tests/draft2019-09/optional/float-overflow.json (renamed from json/tests/draft2019-09/optional/float-overflow.json)0
-rw-r--r--tests/draft2019-09/optional/format/date-time.json (renamed from json/tests/draft2019-09/optional/format/date-time.json)4
-rw-r--r--tests/draft2019-09/optional/format/date.json (renamed from json/tests/draft2020-12/optional/format/date.json)2
-rw-r--r--tests/draft2019-09/optional/format/duration.json (renamed from json/tests/draft2020-12/optional/format/duration.json)2
-rw-r--r--tests/draft2019-09/optional/format/email.json (renamed from json/tests/draft2019-09/optional/format/email.json)0
-rw-r--r--tests/draft2019-09/optional/format/hostname.json (renamed from json/tests/draft2019-09/optional/format/hostname.json)0
-rw-r--r--tests/draft2019-09/optional/format/idn-email.json (renamed from json/tests/draft2019-09/optional/format/idn-email.json)0
-rw-r--r--tests/draft2019-09/optional/format/idn-hostname.json (renamed from json/tests/draft2019-09/optional/format/idn-hostname.json)0
-rw-r--r--tests/draft2019-09/optional/format/ipv4.json (renamed from json/tests/draft2020-12/optional/format/ipv4.json)4
-rw-r--r--tests/draft2019-09/optional/format/ipv6.json (renamed from json/tests/draft2020-12/optional/format/ipv6.json)4
-rw-r--r--tests/draft2019-09/optional/format/iri-reference.json (renamed from json/tests/draft2019-09/optional/format/iri-reference.json)0
-rw-r--r--tests/draft2019-09/optional/format/iri.json (renamed from json/tests/draft2019-09/optional/format/iri.json)0
-rw-r--r--tests/draft2019-09/optional/format/json-pointer.json (renamed from json/tests/draft2019-09/optional/format/json-pointer.json)0
-rw-r--r--tests/draft2019-09/optional/format/regex.json (renamed from json/tests/draft2019-09/optional/format/regex.json)0
-rw-r--r--tests/draft2019-09/optional/format/relative-json-pointer.json (renamed from json/tests/draft2019-09/optional/format/relative-json-pointer.json)0
-rw-r--r--tests/draft2019-09/optional/format/time.json (renamed from json/tests/draft7/optional/format/time.json)2
-rw-r--r--tests/draft2019-09/optional/format/unknown.json (renamed from json/tests/draft2019-09/optional/format/unknown.json)0
-rw-r--r--tests/draft2019-09/optional/format/uri-reference.json (renamed from json/tests/draft2019-09/optional/format/uri-reference.json)0
-rw-r--r--tests/draft2019-09/optional/format/uri-template.json (renamed from json/tests/draft2019-09/optional/format/uri-template.json)0
-rw-r--r--tests/draft2019-09/optional/format/uri.json (renamed from json/tests/draft2019-09/optional/format/uri.json)0
-rw-r--r--tests/draft2019-09/optional/format/uuid.json (renamed from json/tests/draft2019-09/optional/format/uuid.json)0
-rw-r--r--tests/draft2019-09/optional/non-bmp-regex.json (renamed from json/tests/draft2019-09/optional/non-bmp-regex.json)0
-rw-r--r--tests/draft2019-09/optional/refOfUnknownKeyword.json (renamed from json/tests/draft2019-09/optional/refOfUnknownKeyword.json)0
-rw-r--r--tests/draft2019-09/pattern.json (renamed from json/tests/draft2019-09/pattern.json)0
-rw-r--r--tests/draft2019-09/patternProperties.json (renamed from json/tests/draft2019-09/patternProperties.json)0
-rw-r--r--tests/draft2019-09/properties.json (renamed from json/tests/draft2019-09/properties.json)0
-rw-r--r--tests/draft2019-09/propertyNames.json (renamed from json/tests/draft2019-09/propertyNames.json)0
-rw-r--r--tests/draft2019-09/recursiveRef.json (renamed from json/tests/draft2019-09/recursiveRef.json)0
-rw-r--r--tests/draft2019-09/ref.json (renamed from json/tests/draft2019-09/ref.json)4
-rw-r--r--tests/draft2019-09/refRemote.json (renamed from json/tests/draft2019-09/refRemote.json)0
-rw-r--r--tests/draft2019-09/required.json (renamed from json/tests/draft2019-09/required.json)0
-rw-r--r--tests/draft2019-09/type.json (renamed from json/tests/draft2019-09/type.json)0
-rw-r--r--tests/draft2019-09/unevaluatedItems.json (renamed from json/tests/draft2019-09/unevaluatedItems.json)0
-rw-r--r--tests/draft2019-09/unevaluatedProperties.json (renamed from json/tests/draft2019-09/unevaluatedProperties.json)0
-rw-r--r--tests/draft2019-09/uniqueItems.json (renamed from json/tests/draft2019-09/uniqueItems.json)0
-rw-r--r--tests/draft2019-09/unknownKeyword.json (renamed from json/tests/draft2019-09/unknownKeyword.json)0
-rw-r--r--tests/draft2019-09/vocabulary.json (renamed from json/tests/draft2019-09/vocabulary.json)0
-rw-r--r--tests/draft2020-12/additionalProperties.json (renamed from json/tests/draft2020-12/additionalProperties.json)0
-rw-r--r--tests/draft2020-12/allOf.json (renamed from json/tests/draft2020-12/allOf.json)0
-rw-r--r--tests/draft2020-12/anchor.json (renamed from json/tests/draft2020-12/anchor.json)4
-rw-r--r--tests/draft2020-12/anyOf.json (renamed from json/tests/draft2020-12/anyOf.json)0
-rw-r--r--tests/draft2020-12/boolean_schema.json (renamed from json/tests/draft2020-12/boolean_schema.json)0
-rw-r--r--tests/draft2020-12/const.json (renamed from json/tests/draft2020-12/const.json)0
-rw-r--r--tests/draft2020-12/contains.json (renamed from json/tests/draft2020-12/contains.json)0
-rw-r--r--tests/draft2020-12/content.json (renamed from json/tests/draft2020-12/content.json)0
-rw-r--r--tests/draft2020-12/default.json (renamed from json/tests/draft2020-12/default.json)0
-rw-r--r--tests/draft2020-12/defs.json (renamed from json/tests/draft2020-12/defs.json)0
-rw-r--r--tests/draft2020-12/dependentRequired.json (renamed from json/tests/draft2020-12/dependentRequired.json)0
-rw-r--r--tests/draft2020-12/dependentSchemas.json (renamed from json/tests/draft2020-12/dependentSchemas.json)0
-rw-r--r--tests/draft2020-12/dynamicRef.json (renamed from json/tests/draft2020-12/dynamicRef.json)4
-rw-r--r--tests/draft2020-12/enum.json (renamed from json/tests/draft2020-12/enum.json)0
-rw-r--r--tests/draft2020-12/exclusiveMaximum.json (renamed from json/tests/draft2020-12/exclusiveMaximum.json)0
-rw-r--r--tests/draft2020-12/exclusiveMinimum.json (renamed from json/tests/draft2020-12/exclusiveMinimum.json)0
-rw-r--r--tests/draft2020-12/format.json (renamed from json/tests/draft2020-12/format.json)0
-rw-r--r--tests/draft2020-12/id.json (renamed from json/tests/draft2020-12/id.json)0
-rw-r--r--tests/draft2020-12/if-then-else.json (renamed from json/tests/draft2020-12/if-then-else.json)0
-rw-r--r--tests/draft2020-12/infinite-loop-detection.json (renamed from json/tests/draft2020-12/infinite-loop-detection.json)0
-rw-r--r--tests/draft2020-12/items.json (renamed from json/tests/draft2020-12/items.json)10
-rw-r--r--tests/draft2020-12/maxContains.json (renamed from json/tests/draft2020-12/maxContains.json)0
-rw-r--r--tests/draft2020-12/maxItems.json (renamed from json/tests/draft2020-12/maxItems.json)0
-rw-r--r--tests/draft2020-12/maxLength.json (renamed from json/tests/draft2020-12/maxLength.json)0
-rw-r--r--tests/draft2020-12/maxProperties.json (renamed from json/tests/draft2020-12/maxProperties.json)0
-rw-r--r--tests/draft2020-12/maximum.json (renamed from json/tests/draft2020-12/maximum.json)0
-rw-r--r--tests/draft2020-12/minContains.json (renamed from json/tests/draft2020-12/minContains.json)0
-rw-r--r--tests/draft2020-12/minItems.json (renamed from json/tests/draft2020-12/minItems.json)0
-rw-r--r--tests/draft2020-12/minLength.json (renamed from json/tests/draft2020-12/minLength.json)0
-rw-r--r--tests/draft2020-12/minProperties.json (renamed from json/tests/draft2020-12/minProperties.json)0
-rw-r--r--tests/draft2020-12/minimum.json (renamed from json/tests/draft2020-12/minimum.json)0
-rw-r--r--tests/draft2020-12/multipleOf.json (renamed from json/tests/draft2020-12/multipleOf.json)0
-rw-r--r--tests/draft2020-12/not.json (renamed from json/tests/draft2020-12/not.json)0
-rw-r--r--tests/draft2020-12/oneOf.json (renamed from json/tests/draft2020-12/oneOf.json)0
-rw-r--r--tests/draft2020-12/optional/bignum.json (renamed from json/tests/draft6/optional/bignum.json)4
-rw-r--r--tests/draft2020-12/optional/dependencies-compatibility.json (renamed from json/tests/draft2020-12/optional/dependencies-compatibility.json)0
-rw-r--r--tests/draft2020-12/optional/ecmascript-regex.json (renamed from json/tests/draft2020-12/optional/ecmascript-regex.json)12
-rw-r--r--tests/draft2020-12/optional/float-overflow.json (renamed from json/tests/draft2020-12/optional/float-overflow.json)0
-rw-r--r--tests/draft2020-12/optional/format-assertion.json (renamed from json/tests/draft2020-12/optional/format-assertion.json)0
-rw-r--r--tests/draft2020-12/optional/format/date-time.json (renamed from json/tests/draft-next/optional/format/date-time.json)4
-rw-r--r--tests/draft2020-12/optional/format/date.json (renamed from json/tests/draft7/optional/format/date.json)2
-rw-r--r--tests/draft2020-12/optional/format/duration.json (renamed from json/tests/draft-next/optional/format/duration.json)2
-rw-r--r--tests/draft2020-12/optional/format/email.json (renamed from json/tests/draft2020-12/optional/format/email.json)0
-rw-r--r--tests/draft2020-12/optional/format/hostname.json (renamed from json/tests/draft2020-12/optional/format/hostname.json)0
-rw-r--r--tests/draft2020-12/optional/format/idn-email.json (renamed from json/tests/draft2020-12/optional/format/idn-email.json)0
-rw-r--r--tests/draft2020-12/optional/format/idn-hostname.json (renamed from json/tests/draft2020-12/optional/format/idn-hostname.json)0
-rw-r--r--tests/draft2020-12/optional/format/ipv4.json (renamed from json/tests/draft4/optional/format/ipv4.json)4
-rw-r--r--tests/draft2020-12/optional/format/ipv6.json (renamed from json/tests/draft2019-09/optional/format/ipv6.json)4
-rw-r--r--tests/draft2020-12/optional/format/iri-reference.json (renamed from json/tests/draft2020-12/optional/format/iri-reference.json)0
-rw-r--r--tests/draft2020-12/optional/format/iri.json (renamed from json/tests/draft2020-12/optional/format/iri.json)0
-rw-r--r--tests/draft2020-12/optional/format/json-pointer.json (renamed from json/tests/draft2020-12/optional/format/json-pointer.json)0
-rw-r--r--tests/draft2020-12/optional/format/regex.json (renamed from json/tests/draft2020-12/optional/format/regex.json)0
-rw-r--r--tests/draft2020-12/optional/format/relative-json-pointer.json (renamed from json/tests/draft2020-12/optional/format/relative-json-pointer.json)0
-rw-r--r--tests/draft2020-12/optional/format/time.json (renamed from json/tests/draft2019-09/optional/format/time.json)2
-rw-r--r--tests/draft2020-12/optional/format/unknown.json (renamed from json/tests/draft2020-12/optional/format/unknown.json)0
-rw-r--r--tests/draft2020-12/optional/format/uri-reference.json (renamed from json/tests/draft2020-12/optional/format/uri-reference.json)0
-rw-r--r--tests/draft2020-12/optional/format/uri-template.json (renamed from json/tests/draft2020-12/optional/format/uri-template.json)0
-rw-r--r--tests/draft2020-12/optional/format/uri.json (renamed from json/tests/draft2020-12/optional/format/uri.json)0
-rw-r--r--tests/draft2020-12/optional/format/uuid.json (renamed from json/tests/draft2020-12/optional/format/uuid.json)0
-rw-r--r--tests/draft2020-12/optional/non-bmp-regex.json (renamed from json/tests/draft2020-12/optional/non-bmp-regex.json)0
-rw-r--r--tests/draft2020-12/optional/refOfUnknownKeyword.json (renamed from json/tests/draft2020-12/optional/refOfUnknownKeyword.json)0
-rw-r--r--tests/draft2020-12/pattern.json (renamed from json/tests/draft2020-12/pattern.json)0
-rw-r--r--tests/draft2020-12/patternProperties.json (renamed from json/tests/draft2020-12/patternProperties.json)0
-rw-r--r--tests/draft2020-12/prefixItems.json (renamed from json/tests/draft-next/prefixItems.json)0
-rw-r--r--tests/draft2020-12/properties.json (renamed from json/tests/draft2020-12/properties.json)0
-rw-r--r--tests/draft2020-12/propertyNames.json (renamed from json/tests/draft2020-12/propertyNames.json)0
-rw-r--r--tests/draft2020-12/ref.json (renamed from json/tests/draft2020-12/ref.json)4
-rw-r--r--tests/draft2020-12/refRemote.json (renamed from json/tests/draft2020-12/refRemote.json)0
-rw-r--r--tests/draft2020-12/required.json (renamed from json/tests/draft2020-12/required.json)0
-rw-r--r--tests/draft2020-12/type.json (renamed from json/tests/draft2020-12/type.json)0
-rw-r--r--tests/draft2020-12/unevaluatedItems.json (renamed from json/tests/draft2020-12/unevaluatedItems.json)0
-rw-r--r--tests/draft2020-12/unevaluatedProperties.json (renamed from json/tests/draft2020-12/unevaluatedProperties.json)0
-rw-r--r--tests/draft2020-12/uniqueItems.json (renamed from json/tests/draft2020-12/uniqueItems.json)0
-rw-r--r--tests/draft2020-12/unknownKeyword.json (renamed from json/tests/draft2020-12/unknownKeyword.json)0
-rw-r--r--tests/draft2020-12/vocabulary.json (renamed from json/tests/draft2020-12/vocabulary.json)0
-rw-r--r--tests/draft3/additionalItems.json (renamed from json/tests/draft3/additionalItems.json)0
-rw-r--r--tests/draft3/additionalProperties.json (renamed from json/tests/draft3/additionalProperties.json)0
-rw-r--r--tests/draft3/default.json (renamed from json/tests/draft3/default.json)0
-rw-r--r--tests/draft3/dependencies.json (renamed from json/tests/draft3/dependencies.json)0
-rw-r--r--tests/draft3/disallow.json (renamed from json/tests/draft3/disallow.json)0
-rw-r--r--tests/draft3/divisibleBy.json (renamed from json/tests/draft3/divisibleBy.json)0
-rw-r--r--tests/draft3/enum.json (renamed from json/tests/draft3/enum.json)0
-rw-r--r--tests/draft3/extends.json (renamed from json/tests/draft3/extends.json)0
-rw-r--r--tests/draft3/format.json (renamed from json/tests/draft3/format.json)0
-rw-r--r--tests/draft3/infinite-loop-detection.json (renamed from json/tests/draft3/infinite-loop-detection.json)0
-rw-r--r--tests/draft3/items.json (renamed from json/tests/draft3/items.json)0
-rw-r--r--tests/draft3/maxItems.json (renamed from json/tests/draft3/maxItems.json)0
-rw-r--r--tests/draft3/maxLength.json (renamed from json/tests/draft3/maxLength.json)0
-rw-r--r--tests/draft3/maximum.json (renamed from json/tests/draft3/maximum.json)0
-rw-r--r--tests/draft3/minItems.json (renamed from json/tests/draft3/minItems.json)0
-rw-r--r--tests/draft3/minLength.json (renamed from json/tests/draft3/minLength.json)0
-rw-r--r--tests/draft3/minimum.json (renamed from json/tests/draft3/minimum.json)0
-rw-r--r--tests/draft3/optional/bignum.json (renamed from json/tests/draft4/optional/bignum.json)4
-rw-r--r--tests/draft3/optional/ecmascript-regex.json (renamed from json/tests/draft3/optional/ecmascript-regex.json)0
-rw-r--r--tests/draft3/optional/format/color.json (renamed from json/tests/draft3/optional/format/color.json)0
-rw-r--r--tests/draft3/optional/format/date-time.json (renamed from json/tests/draft3/optional/format/date-time.json)0
-rw-r--r--tests/draft3/optional/format/date.json (renamed from json/tests/draft3/optional/format/date.json)0
-rw-r--r--tests/draft3/optional/format/email.json (renamed from json/tests/draft3/optional/format/email.json)0
-rw-r--r--tests/draft3/optional/format/host-name.json (renamed from json/tests/draft3/optional/format/host-name.json)0
-rw-r--r--tests/draft3/optional/format/ip-address.json (renamed from json/tests/draft3/optional/format/ip-address.json)0
-rw-r--r--tests/draft3/optional/format/ipv6.json (renamed from json/tests/draft3/optional/format/ipv6.json)0
-rw-r--r--tests/draft3/optional/format/regex.json (renamed from json/tests/draft3/optional/format/regex.json)0
-rw-r--r--tests/draft3/optional/format/time.json (renamed from json/tests/draft3/optional/format/time.json)0
-rw-r--r--tests/draft3/optional/format/uri.json (renamed from json/tests/draft3/optional/format/uri.json)0
-rw-r--r--tests/draft3/optional/non-bmp-regex.json (renamed from json/tests/draft3/optional/non-bmp-regex.json)0
-rw-r--r--tests/draft3/optional/zeroTerminatedFloats.json (renamed from json/tests/draft3/optional/zeroTerminatedFloats.json)0
-rw-r--r--tests/draft3/pattern.json (renamed from json/tests/draft3/pattern.json)0
-rw-r--r--tests/draft3/patternProperties.json (renamed from json/tests/draft3/patternProperties.json)0
-rw-r--r--tests/draft3/properties.json (renamed from json/tests/draft3/properties.json)0
-rw-r--r--tests/draft3/ref.json (renamed from json/tests/draft3/ref.json)0
-rw-r--r--tests/draft3/refRemote.json (renamed from json/tests/draft3/refRemote.json)0
-rw-r--r--tests/draft3/required.json (renamed from json/tests/draft3/required.json)0
-rw-r--r--tests/draft3/type.json (renamed from json/tests/draft3/type.json)0
-rw-r--r--tests/draft3/uniqueItems.json (renamed from json/tests/draft3/uniqueItems.json)0
-rw-r--r--tests/draft4/additionalItems.json (renamed from json/tests/draft4/additionalItems.json)0
-rw-r--r--tests/draft4/additionalProperties.json (renamed from json/tests/draft4/additionalProperties.json)0
-rw-r--r--tests/draft4/allOf.json (renamed from json/tests/draft4/allOf.json)0
-rw-r--r--tests/draft4/anyOf.json (renamed from json/tests/draft4/anyOf.json)26
-rw-r--r--tests/draft4/default.json (renamed from json/tests/draft4/default.json)0
-rw-r--r--tests/draft4/definitions.json (renamed from json/tests/draft4/definitions.json)0
-rw-r--r--tests/draft4/dependencies.json (renamed from json/tests/draft4/dependencies.json)0
-rw-r--r--tests/draft4/enum.json (renamed from json/tests/draft4/enum.json)0
-rw-r--r--tests/draft4/format.json (renamed from json/tests/draft4/format.json)0
-rw-r--r--tests/draft4/id.json (renamed from json/tests/draft4/id.json)0
-rw-r--r--tests/draft4/infinite-loop-detection.json (renamed from json/tests/draft4/infinite-loop-detection.json)0
-rw-r--r--tests/draft4/items.json (renamed from json/tests/draft4/items.json)0
-rw-r--r--tests/draft4/maxItems.json (renamed from json/tests/draft4/maxItems.json)0
-rw-r--r--tests/draft4/maxLength.json (renamed from json/tests/draft4/maxLength.json)0
-rw-r--r--tests/draft4/maxProperties.json (renamed from json/tests/draft4/maxProperties.json)0
-rw-r--r--tests/draft4/maximum.json (renamed from json/tests/draft4/maximum.json)0
-rw-r--r--tests/draft4/minItems.json (renamed from json/tests/draft4/minItems.json)0
-rw-r--r--tests/draft4/minLength.json (renamed from json/tests/draft4/minLength.json)0
-rw-r--r--tests/draft4/minProperties.json (renamed from json/tests/draft4/minProperties.json)0
-rw-r--r--tests/draft4/minimum.json (renamed from json/tests/draft4/minimum.json)0
-rw-r--r--tests/draft4/multipleOf.json (renamed from json/tests/draft4/multipleOf.json)0
-rw-r--r--tests/draft4/not.json (renamed from json/tests/draft4/not.json)0
-rw-r--r--tests/draft4/oneOf.json (renamed from json/tests/draft4/oneOf.json)0
-rw-r--r--tests/draft4/optional/bignum.json95
-rw-r--r--tests/draft4/optional/ecmascript-regex.json (renamed from json/tests/draft4/optional/ecmascript-regex.json)12
-rw-r--r--tests/draft4/optional/float-overflow.json (renamed from json/tests/draft4/optional/float-overflow.json)0
-rw-r--r--tests/draft4/optional/format/date-time.json (renamed from json/tests/draft4/optional/format/date-time.json)4
-rw-r--r--tests/draft4/optional/format/email.json (renamed from json/tests/draft4/optional/format/email.json)0
-rw-r--r--tests/draft4/optional/format/hostname.json (renamed from json/tests/draft4/optional/format/hostname.json)0
-rw-r--r--tests/draft4/optional/format/ipv4.json (renamed from json/tests/draft-next/optional/format/ipv4.json)4
-rw-r--r--tests/draft4/optional/format/ipv6.json (renamed from json/tests/draft4/optional/format/ipv6.json)4
-rw-r--r--tests/draft4/optional/format/unknown.json (renamed from json/tests/draft4/optional/format/unknown.json)0
-rw-r--r--tests/draft4/optional/format/uri.json (renamed from json/tests/draft4/optional/format/uri.json)0
-rw-r--r--tests/draft4/optional/non-bmp-regex.json (renamed from json/tests/draft4/optional/non-bmp-regex.json)0
-rw-r--r--tests/draft4/optional/zeroTerminatedFloats.json (renamed from json/tests/draft4/optional/zeroTerminatedFloats.json)0
-rw-r--r--tests/draft4/pattern.json (renamed from json/tests/draft4/pattern.json)0
-rw-r--r--tests/draft4/patternProperties.json (renamed from json/tests/draft4/patternProperties.json)0
-rw-r--r--tests/draft4/properties.json (renamed from json/tests/draft4/properties.json)0
-rw-r--r--tests/draft4/ref.json (renamed from json/tests/draft4/ref.json)4
-rw-r--r--tests/draft4/refRemote.json (renamed from json/tests/draft4/refRemote.json)0
-rw-r--r--tests/draft4/required.json (renamed from json/tests/draft4/required.json)0
-rw-r--r--tests/draft4/type.json (renamed from json/tests/draft4/type.json)0
-rw-r--r--tests/draft4/uniqueItems.json (renamed from json/tests/draft4/uniqueItems.json)0
-rw-r--r--tests/draft6/additionalItems.json (renamed from json/tests/draft6/additionalItems.json)0
-rw-r--r--tests/draft6/additionalProperties.json (renamed from json/tests/draft6/additionalProperties.json)0
-rw-r--r--tests/draft6/allOf.json (renamed from json/tests/draft6/allOf.json)0
-rw-r--r--tests/draft6/anyOf.json (renamed from json/tests/draft6/anyOf.json)26
-rw-r--r--tests/draft6/boolean_schema.json (renamed from json/tests/draft6/boolean_schema.json)0
-rw-r--r--tests/draft6/const.json (renamed from json/tests/draft6/const.json)0
-rw-r--r--tests/draft6/contains.json (renamed from json/tests/draft6/contains.json)0
-rw-r--r--tests/draft6/default.json (renamed from json/tests/draft6/default.json)0
-rw-r--r--tests/draft6/definitions.json (renamed from json/tests/draft6/definitions.json)0
-rw-r--r--tests/draft6/dependencies.json (renamed from json/tests/draft6/dependencies.json)0
-rw-r--r--tests/draft6/enum.json (renamed from json/tests/draft6/enum.json)0
-rw-r--r--tests/draft6/exclusiveMaximum.json (renamed from json/tests/draft6/exclusiveMaximum.json)0
-rw-r--r--tests/draft6/exclusiveMinimum.json (renamed from json/tests/draft6/exclusiveMinimum.json)0
-rw-r--r--tests/draft6/format.json (renamed from json/tests/draft6/format.json)0
-rw-r--r--tests/draft6/id.json (renamed from json/tests/draft6/id.json)0
-rw-r--r--tests/draft6/infinite-loop-detection.json (renamed from json/tests/draft6/infinite-loop-detection.json)0
-rw-r--r--tests/draft6/items.json (renamed from json/tests/draft6/items.json)0
-rw-r--r--tests/draft6/maxItems.json (renamed from json/tests/draft6/maxItems.json)0
-rw-r--r--tests/draft6/maxLength.json (renamed from json/tests/draft6/maxLength.json)0
-rw-r--r--tests/draft6/maxProperties.json (renamed from json/tests/draft6/maxProperties.json)0
-rw-r--r--tests/draft6/maximum.json (renamed from json/tests/draft6/maximum.json)0
-rw-r--r--tests/draft6/minItems.json (renamed from json/tests/draft6/minItems.json)0
-rw-r--r--tests/draft6/minLength.json (renamed from json/tests/draft6/minLength.json)0
-rw-r--r--tests/draft6/minProperties.json (renamed from json/tests/draft6/minProperties.json)0
-rw-r--r--tests/draft6/minimum.json (renamed from json/tests/draft6/minimum.json)0
-rw-r--r--tests/draft6/multipleOf.json (renamed from json/tests/draft6/multipleOf.json)0
-rw-r--r--tests/draft6/not.json (renamed from json/tests/draft6/not.json)0
-rw-r--r--tests/draft6/oneOf.json (renamed from json/tests/draft6/oneOf.json)0
-rw-r--r--tests/draft6/optional/bignum.json (renamed from json/tests/draft-next/optional/bignum.json)4
-rw-r--r--tests/draft6/optional/ecmascript-regex.json (renamed from json/tests/draft7/optional/ecmascript-regex.json)12
-rw-r--r--tests/draft6/optional/float-overflow.json (renamed from json/tests/draft6/optional/float-overflow.json)0
-rw-r--r--tests/draft6/optional/format/date-time.json133
-rw-r--r--tests/draft6/optional/format/email.json (renamed from json/tests/draft6/optional/format/email.json)0
-rw-r--r--tests/draft6/optional/format/hostname.json (renamed from json/tests/draft6/optional/format/hostname.json)0
-rw-r--r--tests/draft6/optional/format/ipv4.json84
-rw-r--r--tests/draft6/optional/format/ipv6.json208
-rw-r--r--tests/draft6/optional/format/json-pointer.json (renamed from json/tests/draft6/optional/format/json-pointer.json)0
-rw-r--r--tests/draft6/optional/format/unknown.json (renamed from json/tests/draft6/optional/format/unknown.json)0
-rw-r--r--tests/draft6/optional/format/uri-reference.json (renamed from json/tests/draft6/optional/format/uri-reference.json)0
-rw-r--r--tests/draft6/optional/format/uri-template.json (renamed from json/tests/draft6/optional/format/uri-template.json)0
-rw-r--r--tests/draft6/optional/format/uri.json (renamed from json/tests/draft6/optional/format/uri.json)0
-rw-r--r--tests/draft6/optional/non-bmp-regex.json (renamed from json/tests/draft6/optional/non-bmp-regex.json)0
-rw-r--r--tests/draft6/pattern.json (renamed from json/tests/draft6/pattern.json)0
-rw-r--r--tests/draft6/patternProperties.json (renamed from json/tests/draft6/patternProperties.json)0
-rw-r--r--tests/draft6/properties.json (renamed from json/tests/draft6/properties.json)0
-rw-r--r--tests/draft6/propertyNames.json (renamed from json/tests/draft6/propertyNames.json)0
-rw-r--r--tests/draft6/ref.json (renamed from json/tests/draft6/ref.json)0
-rw-r--r--tests/draft6/refRemote.json (renamed from json/tests/draft6/refRemote.json)0
-rw-r--r--tests/draft6/required.json (renamed from json/tests/draft6/required.json)0
-rw-r--r--tests/draft6/type.json (renamed from json/tests/draft6/type.json)0
-rw-r--r--tests/draft6/uniqueItems.json (renamed from json/tests/draft6/uniqueItems.json)0
-rw-r--r--tests/draft6/unknownKeyword.json (renamed from json/tests/draft6/unknownKeyword.json)0
-rw-r--r--tests/draft7/additionalItems.json (renamed from json/tests/draft7/additionalItems.json)0
-rw-r--r--tests/draft7/additionalProperties.json (renamed from json/tests/draft7/additionalProperties.json)0
-rw-r--r--tests/draft7/allOf.json (renamed from json/tests/draft7/allOf.json)0
-rw-r--r--tests/draft7/anyOf.json189
-rw-r--r--tests/draft7/boolean_schema.json (renamed from json/tests/draft7/boolean_schema.json)0
-rw-r--r--tests/draft7/const.json (renamed from json/tests/draft7/const.json)0
-rw-r--r--tests/draft7/contains.json (renamed from json/tests/draft7/contains.json)0
-rw-r--r--tests/draft7/default.json (renamed from json/tests/draft7/default.json)0
-rw-r--r--tests/draft7/definitions.json (renamed from json/tests/draft7/definitions.json)0
-rw-r--r--tests/draft7/dependencies.json (renamed from json/tests/draft7/dependencies.json)0
-rw-r--r--tests/draft7/enum.json (renamed from json/tests/draft7/enum.json)0
-rw-r--r--tests/draft7/exclusiveMaximum.json (renamed from json/tests/draft7/exclusiveMaximum.json)0
-rw-r--r--tests/draft7/exclusiveMinimum.json (renamed from json/tests/draft7/exclusiveMinimum.json)0
-rw-r--r--tests/draft7/format.json (renamed from json/tests/draft7/format.json)0
-rw-r--r--tests/draft7/id.json (renamed from json/tests/draft7/id.json)0
-rw-r--r--tests/draft7/if-then-else.json (renamed from json/tests/draft7/if-then-else.json)0
-rw-r--r--tests/draft7/infinite-loop-detection.json (renamed from json/tests/draft7/infinite-loop-detection.json)0
-rw-r--r--tests/draft7/items.json (renamed from json/tests/draft7/items.json)0
-rw-r--r--tests/draft7/maxItems.json (renamed from json/tests/draft7/maxItems.json)0
-rw-r--r--tests/draft7/maxLength.json (renamed from json/tests/draft7/maxLength.json)0
-rw-r--r--tests/draft7/maxProperties.json (renamed from json/tests/draft7/maxProperties.json)0
-rw-r--r--tests/draft7/maximum.json (renamed from json/tests/draft7/maximum.json)0
-rw-r--r--tests/draft7/minItems.json (renamed from json/tests/draft7/minItems.json)0
-rw-r--r--tests/draft7/minLength.json (renamed from json/tests/draft7/minLength.json)0
-rw-r--r--tests/draft7/minProperties.json (renamed from json/tests/draft7/minProperties.json)0
-rw-r--r--tests/draft7/minimum.json (renamed from json/tests/draft7/minimum.json)0
-rw-r--r--tests/draft7/multipleOf.json (renamed from json/tests/draft7/multipleOf.json)0
-rw-r--r--tests/draft7/not.json (renamed from json/tests/draft7/not.json)0
-rw-r--r--tests/draft7/oneOf.json (renamed from json/tests/draft7/oneOf.json)0
-rw-r--r--tests/draft7/optional/bignum.json93
-rw-r--r--tests/draft7/optional/content.json (renamed from json/tests/draft7/optional/content.json)0
-rw-r--r--tests/draft7/optional/ecmascript-regex.json (renamed from json/tests/draft6/optional/ecmascript-regex.json)12
-rw-r--r--tests/draft7/optional/float-overflow.json (renamed from json/tests/draft7/optional/float-overflow.json)0
-rw-r--r--tests/draft7/optional/format/date-time.json133
-rw-r--r--tests/draft7/optional/format/date.json (renamed from json/tests/draft-next/optional/format/date.json)2
-rw-r--r--tests/draft7/optional/format/email.json (renamed from json/tests/draft7/optional/format/email.json)0
-rw-r--r--tests/draft7/optional/format/hostname.json (renamed from json/tests/draft7/optional/format/hostname.json)0
-rw-r--r--tests/draft7/optional/format/idn-email.json (renamed from json/tests/draft7/optional/format/idn-email.json)0
-rw-r--r--tests/draft7/optional/format/idn-hostname.json (renamed from json/tests/draft7/optional/format/idn-hostname.json)0
-rw-r--r--tests/draft7/optional/format/ipv4.json84
-rw-r--r--tests/draft7/optional/format/ipv6.json208
-rw-r--r--tests/draft7/optional/format/iri-reference.json (renamed from json/tests/draft7/optional/format/iri-reference.json)0
-rw-r--r--tests/draft7/optional/format/iri.json (renamed from json/tests/draft7/optional/format/iri.json)0
-rw-r--r--tests/draft7/optional/format/json-pointer.json (renamed from json/tests/draft7/optional/format/json-pointer.json)0
-rw-r--r--tests/draft7/optional/format/regex.json (renamed from json/tests/draft7/optional/format/regex.json)0
-rw-r--r--tests/draft7/optional/format/relative-json-pointer.json (renamed from json/tests/draft7/optional/format/relative-json-pointer.json)0
-rw-r--r--tests/draft7/optional/format/time.json (renamed from json/tests/draft-next/optional/format/time.json)2
-rw-r--r--tests/draft7/optional/format/unknown.json (renamed from json/tests/draft7/optional/format/unknown.json)0
-rw-r--r--tests/draft7/optional/format/uri-reference.json (renamed from json/tests/draft7/optional/format/uri-reference.json)0
-rw-r--r--tests/draft7/optional/format/uri-template.json (renamed from json/tests/draft7/optional/format/uri-template.json)0
-rw-r--r--tests/draft7/optional/format/uri.json (renamed from json/tests/draft7/optional/format/uri.json)0
-rw-r--r--tests/draft7/optional/non-bmp-regex.json (renamed from json/tests/draft7/optional/non-bmp-regex.json)0
-rw-r--r--tests/draft7/pattern.json (renamed from json/tests/draft7/pattern.json)0
-rw-r--r--tests/draft7/patternProperties.json (renamed from json/tests/draft7/patternProperties.json)0
-rw-r--r--tests/draft7/properties.json (renamed from json/tests/draft7/properties.json)0
-rw-r--r--tests/draft7/propertyNames.json (renamed from json/tests/draft7/propertyNames.json)0
-rw-r--r--tests/draft7/ref.json (renamed from json/tests/draft7/ref.json)4
-rw-r--r--tests/draft7/refRemote.json (renamed from json/tests/draft7/refRemote.json)0
-rw-r--r--tests/draft7/required.json (renamed from json/tests/draft7/required.json)0
-rw-r--r--tests/draft7/type.json (renamed from json/tests/draft7/type.json)0
-rw-r--r--tests/draft7/uniqueItems.json (renamed from json/tests/draft7/uniqueItems.json)0
-rw-r--r--tests/draft7/unknownKeyword.json (renamed from json/tests/draft7/unknownKeyword.json)0
l---------tests/latest (renamed from json/tests/latest)0
-rw-r--r--tox.ini121
527 files changed, 1467 insertions, 17042 deletions
diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index 5c6eb7e..0000000
--- a/.coveragerc
+++ /dev/null
@@ -1,10 +0,0 @@
-# vim: filetype=dosini:
-[run]
-branch = True
-source = jsonschema
-omit = */jsonschema/_reflect.py,*/jsonschema/__main__.py,*/jsonschema/benchmarks/*,*/jsonschema/tests/fuzz_validate.py
-
-[report]
-exclude_lines =
- pragma: no cover
- if TYPE_CHECKING:
diff --git a/.flake8 b/.flake8
deleted file mode 100644
index 6a6b5cf..0000000
--- a/.flake8
+++ /dev/null
@@ -1,10 +0,0 @@
-[flake8]
-ban-relative-imports = true
-inline-quotes = "
-exclude =
- jsonschema/__init__.py
- jsonschema/_reflect.py
-ignore =
- B008, # Barring function calls in default args. Ha, no.
- B306, # See https://github.com/PyCQA/flake8-bugbear/issues/131
- W503, # (flake8 default) old PEP8 boolean operator line breaks
diff --git a/json/.github/CODEOWNERS b/.github/CODEOWNERS
index 15f4a2d..15f4a2d 100644
--- a/json/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 39a1618..0000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-# These are supported funding model platforms
-
-github: "Julian"
-tidelift: "pypi/jsonschema"
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
deleted file mode 100644
index fd524e9..0000000
--- a/.github/SECURITY.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Security Policy
-
-## Supported Versions
-
-In general, only the latest released ``jsonschema`` version is supported
-and will receive updates.
-
-## Reporting a Vulnerability
-
-To report a security vulnerability, please send an email to
-``Julian+Security@GrayVines.com`` with subject line ``SECURITY
-(jsonschema)``.
-
-I will do my best to respond within 48 hours to acknowledge the message
-and discuss further steps.
-
-If the vulnerability is accepted, an advisory will be sent out via
-GitHub's security advisory functionality.
-
-For non-sensitive discussion related to this policy itself, feel free to
-open an issue on the issue tracker.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e77123f..a826069 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-name: CI
+name: Test Suite Sanity Checking
on:
push:
@@ -6,229 +6,20 @@ on:
release:
types: [published]
schedule:
- # Daily at 3:21
- - cron: '21 3 * * *'
+ # Daily at 6:42, arbitrarily as a time that's possibly non-busy
+ - cron: '42 6 * * *'
jobs:
- pre-commit:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v3
- - uses: pre-commit/action@v2.0.3
-
ci:
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os: [macos-latest, ubuntu-latest, windows-latest]
- python-version:
- - name: pypy-3.8
- toxenv: pypy3-noextra-build
- - name: pypy-3.8
- toxenv: pypy3-noextra-tests
- - name: pypy-3.8
- toxenv: pypy3-format-build
- - name: pypy-3.8
- toxenv: pypy3-format-tests
- - name: pypy-3.8
- toxenv: pypy3-formatnongpl-build
- - name: pypy-3.8
- toxenv: pypy3-formatnongpl-tests
- - name: 3.7
- toxenv: py37-noextra-build
- - name: 3.7
- toxenv: py37-noextra-tests
- - name: 3.7
- toxenv: py37-format-build
- - name: 3.7
- toxenv: py37-format-tests
- - name: 3.7
- toxenv: py37-formatnongpl-build
- - name: 3.7
- toxenv: py37-formatnongpl-tests
- - name: 3.8
- toxenv: py38-noextra-build
- - name: 3.8
- toxenv: py38-noextra-tests
- - name: 3.8
- toxenv: py38-format-build
- - name: 3.8
- toxenv: py38-format-tests
- - name: 3.8
- toxenv: py38-formatnongpl-build
- - name: 3.8
- toxenv: py38-formatnongpl-tests
- - name: 3.9
- toxenv: py39-noextra-build
- - name: 3.9
- toxenv: py39-noextra-tests
- - name: 3.9
- toxenv: py39-format-build
- - name: 3.9
- toxenv: py39-format-tests
- - name: 3.9
- toxenv: py39-formatnongpl-build
- - name: 3.9
- toxenv: py39-formatnongpl-tests
- - name: "3.10"
- toxenv: py310-noextra-build
- - name: "3.10"
- toxenv: py310-noextra-tests
- - name: "3.10"
- toxenv: py310-format-build
- - name: "3.10"
- toxenv: py310-format-tests
- - name: "3.10"
- toxenv: py310-formatnongpl-build
- - name: "3.10"
- toxenv: py310-formatnongpl-tests
- - name: "3.11.0-beta - 3.11.0"
- toxenv: py311-noextra-build
- - name: "3.11.0-beta - 3.11.0"
- toxenv: py311-noextra-tests
- - name: "3.11.0-beta - 3.11.0"
- toxenv: py311-format-build
- - name: "3.11.0-beta - 3.11.0"
- toxenv: py311-format-tests
- - name: "3.11.0-beta - 3.11.0"
- toxenv: py311-formatnongpl-build
- - name: "3.11.0-beta - 3.11.0"
- toxenv: py311-formatnongpl-tests
- - name: "3.10"
- toxenv: docs-dirhtml
- - name: "3.10"
- toxenv: docs-doctest
- - name: "3.10"
- toxenv: docs-linkcheck
- - name: "3.10"
- toxenv: docs-spelling
- - name: "3.10"
- toxenv: docs-style
- - name: "3.10"
- toxenv: readme
- - name: "3.10"
- toxenv: safety
- - name: "3.10"
- toxenv: secrets
- - name: "3.10"
- toxenv: style
- - name: "3.10"
- toxenv: typing
- exclude:
- - os: windows-latest
- python-version:
- name: pypy-3.8
- toxenv: pypy3-noextra-build
- - os: windows-latest
- python-version:
- name: pypy-3.8
- toxenv: pypy3-noextra-tests
- - os: windows-latest
- python-version:
- name: pypy-3.8
- toxenv: pypy3-format-build
- - os: windows-latest
- python-version:
- name: pypy-3.8
- toxenv: pypy3-format-tests
- - os: windows-latest
- python-version:
- name: pypy-3.8
- toxenv: pypy3-formatnongpl-build
- - os: windows-latest
- python-version:
- name: pypy-3.8
- toxenv: pypy3-formatnongpl-tests
- - os: windows-latest
- python-version:
- name: "3.10"
- toxenv: py310-noextra-tests
- - os: windows-latest
- python-version:
- name: "3.10"
- toxenv: py310-format-tests
- - os: windows-latest
- python-version:
- name: "3.10"
- toxenv: py310-formatnongpl-tests
- - os: windows-latest
- python-version:
- name: "3.11.0-alpha - 3.11.0"
- toxenv: py311-noextra-tests
- - os: windows-latest
- python-version:
- name: "3.11.0-alpha - 3.11.0"
- toxenv: py311-format-tests
- - os: windows-latest
- python-version:
- name: "3.11.0-alpha - 3.11.0"
- toxenv: py311-formatnongpl-tests
- - os: windows-latest
- python-version:
- name: "3.10"
- toxenv: readme
- - os: windows-latest
- python-version:
- name: "3.10"
- toxenv: docs-linkcheck
- - os: windows-latest
- python-version:
- name: "3.10"
- toxenv: docs-style
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- - name: Set up Python ${{ matrix.python-version.name }}
- uses: actions/setup-python@v3
+ - name: Set up Python
+ uses: actions/setup-python@v4
with:
- python-version: ${{ matrix.python-version.name }}
- - name: Install dependencies
- run: >
- sudo apt-get update &&
- sudo apt-get install -y libenchant-dev libxml2-dev libxslt-dev
- if: runner.os == 'Linux' && startsWith(matrix.python-version.toxenv, 'docs-')
- - name: Install dependencies
- run: brew install enchant
- if: runner.os == 'macOS' && startsWith(matrix.python-version.toxenv, 'docs-')
+ python-version: '3.x'
- name: Install tox
run: python -m pip install tox
- - name: Run tox
- run: python -m tox -e "${{ matrix.python-version.toxenv }}"
-
- packaging:
- needs: ci
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0
- - uses: actions/setup-python@v3
- with:
- python-version: "3.10"
- - name: Install dependencies
- run: python -m pip install build
- - name: Create packages
- run: python -m build .
- - uses: actions/upload-artifact@v3
- with:
- name: dist
- path: dist
- - name: Publish package
- if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
- uses: pypa/gh-action-pypi-publish@master
- with:
- user: __token__
- password: ${{ secrets.pypi_password }}
- - name: Create Release Notes
- if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
- uses: actions/github-script@v6
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
- script: |
- await github.request(`POST /repos/${{ github.repository }}/releases`, {
- tag_name: "${{ github.ref }}",
- generate_release_notes: true
- });
+ - name: Run the sanity checks
+ run: python -m tox
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
deleted file mode 100644
index 3edc627..0000000
--- a/.github/workflows/coverage.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: Coverage
-
-on:
- push:
- pull_request:
- release:
- types: [published]
-
-jobs:
- coverage:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Set up Python
- uses: actions/setup-python@v3
- with:
- python-version: "3.10"
- - name: Install tox
- run: python -m pip install tox
- - name: Collect & Upload Coverage
- # codecov.io is too flaky to fail for this right now
- continue-on-error: true
- run: python -m tox -e py39-format-codecov
- env:
- CODECOV_TOKEN: 2b38dae1-41c4-4435-a29d-79a1299e5617
diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml
deleted file mode 100644
index dcc49a3..0000000
--- a/.github/workflows/fuzz.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: CIFuzz
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- Fuzzing:
- runs-on: ubuntu-latest
- steps:
- - name: Build Fuzzers
- id: build
- uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
- with:
- oss-fuzz-project-name: 'jsonschema'
- language: python
- continue-on-error: true
- - name: Run Fuzzers
- if: steps.build.outcome == 'success'
- uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
- with:
- oss-fuzz-project-name: 'jsonschema'
- fuzz-seconds: 30
- - name: Upload Crash
- uses: actions/upload-artifact@v3
- if: failure() && steps.build.outcome == 'success'
- with:
- name: artifacts
- path: ./out/artifacts
diff --git a/.gitignore b/.gitignore
index ec41496..68bc17f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -101,7 +101,15 @@ ipython_config.py
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
-# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
@@ -145,13 +153,8 @@ dmypy.json
cython_debug/
# PyCharm
-# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
-
-# User defined
-_cache
-_static
-_templates
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index 5cec24c..0000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-exclude: json/
-
-repos:
- - repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.3.0
- hooks:
- - id: check-ast
- - id: check-docstring-first
- - id: check-json
- - id: check-toml
- - id: check-vcs-permalinks
- - id: check-yaml
- - id: debug-statements
- exclude: '^jsonschema/tests/_suite.py$'
- - id: end-of-file-fixer
- - id: mixed-line-ending
- args: [--fix, lf]
- - id: trailing-whitespace
- - repo: https://github.com/PyCQA/isort
- rev: 5.10.1
- hooks:
- - id: isort
diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
deleted file mode 100644
index f806715..0000000
--- a/.pre-commit-hooks.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-- id: jsonschema
- name: jsonschema
- description: json schema validation
- language: python
- pass_filenames: false
- entry: jsonschema
diff --git a/.readthedocs.yml b/.readthedocs.yml
deleted file mode 100644
index 5750166..0000000
--- a/.readthedocs.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-version: 2
-
-sphinx:
- builder: dirhtml
- configuration: docs/conf.py
- fail_on_warning: true
-
-formats: all
-
-python:
- version: 3.8
- install:
- - requirements: docs/requirements.txt
- - method: pip
- path: .
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
deleted file mode 100644
index 986c0f4..0000000
--- a/CHANGELOG.rst
+++ /dev/null
@@ -1,369 +0,0 @@
-v4.9.1
-------
-
-* Update some documentation examples to use newer validator releases in their
- sample code.
-
-v4.9.0
-------
-
-* Fix relative ``$ref`` resolution when the base URI is a URN or other scheme
- (#544).
-* ``pkgutil.resolve_name`` is now used to retrieve validators
- provided on the command line. This function is only available on
- 3.9+, so 3.7 and 3.8 (which are still supported) now rely on the
- `pkgutil_resolve_name <https://pypi.org/project/pkgutil_resolve_name/>`_
- backport package. Note however that the CLI itself is due
- to be deprecated shortly in favor of `check-jsonschema
- <https://github.com/python-jsonschema/check-jsonschema>`_.
-
-v4.8.0
-------
-
-* ``best_match`` no longer traverses into ``anyOf`` and ``oneOf`` when all of
- the errors within them seem equally applicable. This should lead to clearer
- error messages in some cases where no branches were matched.
-
-v4.7.2
-------
-
-* Also have ``best_match`` handle cases where the ``type`` validator is an
- array.
-
-v4.7.1
-------
-
-* Minor tweak of the PyPI hyperlink names
-
-v4.7.0
-------
-
-* Enhance ``best_match`` to prefer errors from branches of the schema which
- match the instance's type (#728)
-
-v4.6.2
-------
-
-* Fix a number of minor typos in docstrings, mostly private ones (#969)
-
-v4.6.1
-------
-
-* Gut the (incomplete) implementation of ``recursiveRef`` on draft 2019. It
- needs completing, but for now can lead to recursion errors (e.g. #847).
-
-v4.6.0
-------
-
-* Fix ``unevaluatedProperties`` and ``unevaluatedItems`` for types they should
- ignore (#949)
-* ``jsonschema`` now uses `hatch <https://hatch.pypa.io/>`_ for its build
- process. This should be completely transparent to end-users (and only matters
- to contributors).
-
-v4.5.1
-------
-
-* Revert changes to ``$dynamicRef`` which caused a performance regression
- in v4.5.0
-
-v4.5.0
-------
-
-* Validator classes for each version now maintain references to the correct
- corresponding format checker (#905)
-* Development has moved to a `GitHub organization
- <https://github.com/python-jsonschema/>`_.
- No functional behavior changes are expected from the change.
-
-v4.4.0
-------
-
-* Add ``mypy`` support (#892)
-* Add support for Python 3.11
-
-v4.3.3
-------
-
-* Properly report deprecation warnings at the right stack level (#899)
-
-v4.3.2
-------
-
-* Additional performance improvements for resolving refs (#896)
-
-v4.3.1
-------
-
-* Resolving refs has had performance improvements (#893)
-
-v4.3.0
-------
-
-* Fix undesired fallback to brute force container uniqueness check on
- certain input types (#893)
-* Implement a PEP544 Protocol for validator classes (#890)
-
-v4.2.1
-------
-
-* Pin ``importlib.resources`` from below (#877)
-
-v4.2.0
-------
-
-* Use ``importlib.resources`` to load schemas (#873)
-* Ensure all elements of arrays are verified for uniqueness by ``uniqueItems``
- (#866)
-
-v4.1.2
-------
-
-* Fix ``dependentSchemas`` to properly consider non-object instances to be
- valid (#850)
-
-v4.1.1
-------
-
-* Fix ``prefixItems`` not indicating which item was invalid within the instance
- path (#862)
-
-v4.1.0
-------
-
-* Add Python 3.10 to the list of supported Python versions
-
-v4.0.1
-------
-
-* Fix the declaration of minimum supported Python version (#846)
-
-v4.0.0
-------
-
-* Partial support for Draft 2020-12 (as well as 2019-09).
- Thanks to Thomas Schmidt and Harald Nezbeda.
-* ``False`` and ``0`` are now properly considered non-equal even
- recursively within a container (#686). As part of this change,
- ``uniqueItems`` validation may be *slower* in some cases. Please feel
- free to report any significant performance regressions, though in
- some cases they may be difficult to address given the specification
- requirement.
-* The CLI has been improved, and in particular now supports a ``--output``
- option (with ``plain`` (default) or ``pretty`` arguments) to control the
- output format. Future work may add additional machine-parsable output
- formats.
-* Code surrounding ``DEFAULT_TYPES`` and the legacy mechanism for
- specifying types to validators have been removed, as per the deprecation
- policy. Validators should use the ``TypeChecker`` object to customize
- the set of Python types corresponding to JSON Schema types.
-* Validation errors now have a ``json_path`` attribute, describing their
- location in JSON path format
-* Support for the IP address and domain name formats has been improved
-* Support for Python 2 and 3.6 has been dropped, with ``python_requires``
- properly set.
-* ``multipleOf`` could overflow when given sufficiently large numbers. Now,
- when an overflow occurs, ``jsonschema`` will fall back to using fraction
- division (#746).
-* ``jsonschema.__version__``, ``jsonschema.validators.validators``,
- ``jsonschema.validators.meta_schemas`` and
- ``jsonschema.RefResolver.in_scope`` have been deprecated, as has
- passing a second-argument schema to ``Validator.iter_errors`` and
- ``Validator.is_valid``.
-
-v3.2.0
-------
-
-* Added a ``format_nongpl`` setuptools extra, which installs only ``format``
- dependencies that are non-GPL (#619).
-
-v3.1.1
-------
-
-* Temporarily revert the switch to ``js-regex`` until #611 and #612 are
- resolved.
-
-v3.1.0
-------
-
-* Regular expressions throughout schemas now respect the ECMA 262 dialect, as
- recommended by the specification (#609).
-
-v3.0.2
-------
-
-* Fixed a bug where ``0`` and ``False`` were considered equal by
- ``const`` and ``enum`` (#575).
-
-v3.0.1
-------
-
-* Fixed a bug where extending validators did not preserve their notion
- of which validator property contains ``$id`` information.
-
-v3.0.0
-------
-
-* Support for Draft 6 and Draft 7
-* Draft 7 is now the default
-* New ``TypeChecker`` object for more complex type definitions (and overrides)
-* Falling back to isodate for the date-time format checker is no longer
- attempted, in accordance with the specification
-
-v2.6.0
-------
-
-* Support for Python 2.6 has been dropped.
-* Improve a few error messages for ``uniqueItems`` (#224) and
- ``additionalProperties`` (#317)
-* Fixed an issue with ``ErrorTree``'s handling of multiple errors (#288)
-
-v2.5.0
-------
-
-* Improved performance on CPython by adding caching around ref resolution
- (#203)
-
-v2.4.0
-------
-
-* Added a CLI (#134)
-* Added absolute path and absolute schema path to errors (#120)
-* Added ``relevance``
-* Meta-schemas are now loaded via ``pkgutil``
-
-v2.3.0
-------
-
-* Added ``by_relevance`` and ``best_match`` (#91)
-* Fixed ``format`` to allow adding formats for non-strings (#125)
-* Fixed the ``uri`` format to reject URI references (#131)
-
-v2.2.0
-------
-
-* Compile the host name regex (#127)
-* Allow arbitrary objects to be types (#129)
-
-v2.1.0
-------
-
-* Support RFC 3339 datetimes in conformance with the spec
-* Fixed error paths for additionalItems + items (#122)
-* Fixed wording for min / maxProperties (#117)
-
-
-v2.0.0
-------
-
-* Added ``create`` and ``extend`` to ``jsonschema.validators``
-* Removed ``ValidatorMixin``
-* Fixed array indices ref resolution (#95)
-* Fixed unknown scheme defragmenting and handling (#102)
-
-
-v1.3.0
-------
-
-* Better error tracebacks (#83)
-* Raise exceptions in ``ErrorTree``\s for keys not in the instance (#92)
-* __cause__ (#93)
-
-
-v1.2.0
-------
-
-* More attributes for ValidationError (#86)
-* Added ``ValidatorMixin.descend``
-* Fixed bad ``RefResolutionError`` message (#82)
-
-
-v1.1.0
-------
-
-* Canonicalize URIs (#70)
-* Allow attaching exceptions to ``format`` errors (#77)
-
-
-v1.0.0
-------
-
-* Support for Draft 4
-* Support for format
-* Longs are ints too!
-* Fixed a number of issues with ``$ref`` support (#66)
-* Draft4Validator is now the default
-* ``ValidationError.path`` is now in sequential order
-* Added ``ValidatorMixin``
-
-
-v0.8.0
-------
-
-* Full support for JSON References
-* ``validates`` for registering new validators
-* Documentation
-* Bugfixes
-
- * uniqueItems not so unique (#34)
- * Improper any (#47)
-
-
-v0.7
-----
-
-* Partial support for (JSON Pointer) ``$ref``
-* Deprecations
-
- * ``Validator`` is replaced by ``Draft3Validator`` with a slightly different
- interface
- * ``validator(meta_validate=False)``
-
-
-v0.6
-----
-
-* Bugfixes
-
- * Issue #30 - Wrong behavior for the dependencies property validation
- * Fixed a miswritten test
-
-
-v0.5
-----
-
-* Bugfixes
-
- * Issue #17 - require path for error objects
- * Issue #18 - multiple type validation for non-objects
-
-
-v0.4
-----
-
-* Preliminary support for programmatic access to error details (Issue #5).
- There are certainly some corner cases that don't do the right thing yet, but
- this works mostly.
-
- In order to make this happen (and also to clean things up a bit), a number
- of deprecations are necessary:
-
- * ``stop_on_error`` is deprecated in ``Validator.__init__``. Use
- ``Validator.iter_errors()`` instead.
- * ``number_types`` and ``string_types`` are deprecated there as well.
- Use ``types={"number" : ..., "string" : ...}`` instead.
- * ``meta_validate`` is also deprecated, and instead is now accepted as
- an argument to ``validate``, ``iter_errors`` and ``is_valid``.
-
-* A bugfix or two
-
-
-v0.3
-----
-
-* Default for unknown types and properties is now to *not* error (consistent
- with the schema).
-* Python 3 support
-* Removed dependency on SecureTypes now that the hash bug has been resolved.
-* "Numerous bug fixes" -- most notably, a divisibleBy error for floats and a
- bunch of missing typechecks for irrelevant properties.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
deleted file mode 100644
index c051d56..0000000
--- a/CONTRIBUTING.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-============================
-Contributing to `jsonschema`
-============================
-
-Found a bug?
-------------
-
-If you suspect you may have found a security-related vulnerability, please follow the instructions in `the security policy <https://github.com/python-jsonschema/jsonschema/blob/main/.github/SECURITY.md>`_.
-
-Otherwise, it is extremely helpful if you first search to see whether your bug has been `previously reported on the Issues tab <https://github.com/python-jsonschema/jsonschema/issues?q=is%3Aissue+is%3Aopen+label%3ABug>`_.
-
-If it doesn't appear to be a known issue, please `file a new one <https://github.com/python-jsonschema/jsonschema/issues/new>`_, and include a **title and clear description**, along with as much relevant information as possible.
-Including a *minimal*, *self-sufficient* bit of code (often an instance and schema) is the fastest way to get attention, along with a description of the behavior you expect, and if you're able, a link to where in the specification contains the behavior you're noticing is incorrect.
-
-Pull requests to fix your issue are of course very welcome.
-
-
-Fixing a Bug?
--------------
-
-Please open a new GitHub pull request with the change, along with new tests.
-
-Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
-
-Continuous integration via GitHub actions should run to indicate whether your change passes both the test suite as well as linters.
-Please ensure it passes, or indicate in a comment if you believe it fails spuriously.
-
-
-Adding New Functionality?
--------------------------
-
-Please discuss any larger changes ahead of time for the sake of your own time!
-
-Improvements are very welcome, but large pull requests, disruptive ones, or backwards incompatible ones, can lead to long back and forth discussions.
-
-You're welcome to suggest a change in an issue and thereby get some initial feedback before embarking on an effort that may not get merged.
-
-
-Improving the Documentation?
-----------------------------
-
-Writing good documentation is challenging both to prioritize and to do well.
-
-Any help you may have would be great, especially if you're a beginner who's struggled to understand a part of the library.
-
-Documentation is written in `Sphinx-flavored reStructuredText <https://www.sphinx-doc.org>`_, so you'll want to familiarize yourself a bit with Sphinx.
-
-Feel free to file issues or pull requests.
-
-
-Have a Question?
-----------------
-
-Please do not use the issue tracker for questions, it's reserved for things believed to be bugs, or new functionality.
-
-There is a `discussions tab <https://github.com/python-jsonschema/jsonschema/discussions>`_ where general questions can be asked.
-
-Answers on it are best-effort.
-
-Any help you can offer to answer others' questions is of course very welcome as well.
diff --git a/COPYING b/COPYING
deleted file mode 100644
index af9cfbd..0000000
--- a/COPYING
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2013 Julian Berman
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/json/LICENSE b/LICENSE
index c28adba..c28adba 100644
--- a/json/LICENSE
+++ b/LICENSE
diff --git a/json/README.md b/README.md
index d9cc165..d9cc165 100644
--- a/json/README.md
+++ b/README.md
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 0003c50..0000000
--- a/README.rst
+++ /dev/null
@@ -1,148 +0,0 @@
-==========
-jsonschema
-==========
-
-|PyPI| |Pythons| |CI| |ReadTheDocs| |Precommit| |Zenodo|
-
-.. |PyPI| image:: https://img.shields.io/pypi/v/jsonschema.svg
- :alt: PyPI version
- :target: https://pypi.org/project/jsonschema/
-
-.. |Pythons| image:: https://img.shields.io/pypi/pyversions/jsonschema.svg
- :alt: Supported Python versions
- :target: https://pypi.org/project/jsonschema/
-
-.. |CI| image:: https://github.com/python-jsonschema/jsonschema/workflows/CI/badge.svg
- :alt: Build status
- :target: https://github.com/python-jsonschema/jsonschema/actions?query=workflow%3ACI
-
-.. |ReadTheDocs| image:: https://readthedocs.org/projects/python-jsonschema/badge/?version=stable&style=flat
- :alt: ReadTheDocs status
- :target: https://python-jsonschema.readthedocs.io/en/stable/
-
-.. |Precommit| image:: https://results.pre-commit.ci/badge/github/python-jsonschema/jsonschema/main.svg
- :alt: pre-commit.ci status
- :target: https://results.pre-commit.ci/latest/github/python-jsonschema/jsonschema/main
-
-.. |Zenodo| image:: https://zenodo.org/badge/3072629.svg
- :target: https://zenodo.org/badge/latestdoi/3072629
-
-
-``jsonschema`` is an implementation of the `JSON Schema
-<https://json-schema.org>`_ specification for Python.
-
-.. code-block:: python
-
- >>> from jsonschema import validate
-
- >>> # A sample schema, like what we'd get from json.load()
- >>> schema = {
- ... "type" : "object",
- ... "properties" : {
- ... "price" : {"type" : "number"},
- ... "name" : {"type" : "string"},
- ... },
- ... }
-
- >>> # If no exception is raised by validate(), the instance is valid.
- >>> validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
-
- >>> validate(
- ... instance={"name" : "Eggs", "price" : "Invalid"}, schema=schema,
- ... ) # doctest: +IGNORE_EXCEPTION_DETAIL
- Traceback (most recent call last):
- ...
- ValidationError: 'Invalid' is not of type 'number'
-
-It can also be used from console:
-
-.. code-block:: bash
-
- $ jsonschema --instance sample.json sample.schema
-
-Features
---------
-
-* Partial support for
- `Draft 2020-12 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft202012Validator>`_ and
- `Draft 2019-09 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft201909Validator>`_,
- except for ``dynamicRef`` / ``recursiveRef`` and ``$vocabulary`` (in-progress).
- Full support for
- `Draft 7 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft7Validator>`_,
- `Draft 6 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft6Validator>`_,
- `Draft 4 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft4Validator>`_
- and
- `Draft 3 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft3Validator>`_
-
-* `Lazy validation <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.protocols.Validator.iter_errors>`_
- that can iteratively report *all* validation errors.
-
-* `Programmatic querying <https://python-jsonschema.readthedocs.io/en/latest/errors/>`_
- of which properties or items failed validation.
-
-
-Installation
-------------
-
-``jsonschema`` is available on `PyPI <https://pypi.org/project/jsonschema/>`_. You can install using `pip <https://pip.pypa.io/en/stable/>`_:
-
-.. code-block:: bash
-
- $ pip install jsonschema
-
-
-Running the Test Suite
-----------------------
-
-If you have ``tox`` installed (perhaps via ``pip install tox`` or your
-package manager), running ``tox`` in the directory of your source
-checkout will run ``jsonschema``'s test suite on all of the versions
-of Python ``jsonschema`` supports. If you don't have all of the
-versions that ``jsonschema`` is tested under, you'll likely want to run
-using ``tox``'s ``--skip-missing-interpreters`` option.
-
-Of course you're also free to just run the tests on a single version with your
-favorite test runner. The tests live in the ``jsonschema.tests`` package.
-
-
-Benchmarks
-----------
-
-``jsonschema``'s benchmarks make use of `pyperf
-<https://pyperf.readthedocs.io>`_. Running them can be done via::
-
- $ tox -e perf
-
-
-Community
----------
-
-The JSON Schema specification has `a Slack
-<https://json-schema.slack.com>`_, with an `invite link on its home page
-<https://json-schema.org/>`_. Many folks knowledgeable on authoring
-schemas can be found there.
-
-Otherwise, asking questions on Stack Overflow is another means of
-getting help if you're stuck.
-
-
-About
------
-
-I'm Julian Berman.
-
-``jsonschema`` is on `GitHub <https://github.com/python-jsonschema/jsonschema>`_.
-
-Get in touch, via GitHub or otherwise, if you've got something to contribute,
-it'd be most welcome!
-
-You can also generally find me on Libera (nick: ``Julian``) in various
-channels, including ``#python``.
-
-If you feel overwhelmingly grateful, you can also `sponsor me
-<https://github.com/sponsors/Julian/>`_.
-
-And for companies who appreciate ``jsonschema`` and its continued support
-and growth, ``jsonschema`` is also now supportable via `TideLift
-<https://tidelift.com/subscription/pkg/pypi-jsonschema?utm_source=pypi-j
-sonschema&utm_medium=referral&utm_campaign=readme>`_.
diff --git a/json/bin/jsonschema_suite b/bin/jsonschema_suite
index a859dcf..bd77ee4 100755
--- a/json/bin/jsonschema_suite
+++ b/bin/jsonschema_suite
@@ -40,14 +40,14 @@ def files(paths):
Each test file in the provided paths, as an array of test cases.
"""
for path in paths:
- yield json.loads(path.read_text())
+ yield path, json.loads(path.read_text())
def cases(paths):
"""
Each test case within each file in the provided paths.
"""
- for test_file in files(paths):
+ for _, test_file in files(paths):
yield from test_file
@@ -82,52 +82,115 @@ class SanityTests(unittest.TestCase):
assert cls.remote_files, "Didn't find the remote files!"
print(f"Found {len(cls.remote_files)} remote files")
+ def assertUnique(self, iterable):
+ """
+ Assert that the elements of an iterable are unique.
+ """
+
+ seen, duplicated = set(), set()
+ for each in iterable:
+ if each in seen:
+ duplicated.add(each)
+ seen.add(each)
+ self.assertFalse(duplicated, "Elements are not unique.")
+
def test_all_test_files_are_valid_json(self):
"""
All test files contain valid JSON.
"""
for path in self.test_files:
- try:
- json.loads(path.read_text())
- except ValueError as error:
- self.fail(f"{path} contains invalid JSON ({error})")
+ with self.subTest(path=path):
+ try:
+ json.loads(path.read_text())
+ except ValueError as error:
+ self.fail(f"{path} contains invalid JSON ({error})")
def test_all_remote_files_are_valid_json(self):
"""
All remote files contain valid JSON.
"""
for path in self.remote_files:
- try:
- json.loads(path.read_text())
- except ValueError as error:
- self.fail(f"{path} contains invalid JSON ({error})")
+ with self.subTest(path=path):
+ try:
+ json.loads(path.read_text())
+ except ValueError as error:
+ self.fail(f"{path} contains invalid JSON ({error})")
- def test_all_descriptions_have_reasonable_length(self):
+ def test_all_case_descriptions_have_reasonable_length(self):
+ """
+ All cases have reasonably long descriptions.
+ """
+ for case in cases(self.test_files):
+ with self.subTest(description=case["description"]):
+ self.assertLess(
+ len(case["description"]),
+ 150,
+ "Description is too long (keep it to less than 150 chars)."
+ )
+
+ def test_all_test_descriptions_have_reasonable_length(self):
"""
All tests have reasonably long descriptions.
"""
for count, test in enumerate(tests(self.test_files)):
- description = test["description"]
- self.assertLess(
- len(description),
- 70,
- f"{description!r} is too long! (keep it to less than 70 chars)"
- )
+ with self.subTest(description=test["description"]):
+ self.assertLess(
+ len(test["description"]),
+ 70,
+ "Description is too long (keep it to less than 70 chars)."
+ )
print(f"Found {count} tests.")
- def test_all_descriptions_are_unique(self):
+ def test_all_case_descriptions_are_unique(self):
+ """
+ All cases have unique descriptions in their files.
+ """
+ for path, cases in files(self.test_files):
+ with self.subTest(path=path):
+ self.assertUnique(case["description"] for case in cases)
+
+ def test_all_test_descriptions_are_unique(self):
"""
All test cases have unique test descriptions in their tests.
"""
for count, case in enumerate(cases(self.test_files)):
- descriptions = set(test["description"] for test in case["tests"])
- self.assertEqual(
- len(descriptions),
- len(case["tests"]),
- f"{case!r} contains a duplicate description",
- )
+ with self.subTest(description=case["description"]):
+ self.assertUnique(
+ test["description"] for test in case["tests"]
+ )
print(f"Found {count} test cases.")
+ def test_descriptions_do_not_use_modal_verbs(self):
+ """
+ Instead of saying "test that X frobs" or "X should frob" use "X frobs".
+
+ See e.g. https://jml.io/pages/test-docstrings.html
+
+ This test isn't comprehensive (it doesn't catch all the extra
+ verbiage there), but it's just to catch whatever it manages to
+ cover.
+ """
+
+ message = (
+ "In descriptions, don't say 'Test that X frobs' or 'X should "
+ "frob' or 'X should be valid'. Just say 'X frobs' or 'X is "
+ "valid'. It's shorter, and the test suite is entirely about "
+ "what *should* be already. "
+ "See https://jml.io/pages/test-docstrings.html for help."
+ )
+ for test in tests(self.test_files):
+ with self.subTest(description=test["description"]):
+ self.assertNotRegex(
+ test["description"],
+ r"\bshould\b",
+ message,
+ )
+ self.assertNotRegex(
+ test["description"],
+ r"(?i)\btest(s)? that\b",
+ message,
+ )
+
@unittest.skipIf(jsonschema is None, "Validation library not present!")
def test_all_schemas_are_valid(self):
"""
@@ -141,12 +204,14 @@ class SanityTests(unittest.TestCase):
if Validator is not None:
test_files = collect(version)
for case in cases(test_files):
- try:
- Validator.check_schema(case["schema"])
- except jsonschema.SchemaError as error:
- self.fail(
- f"{case} contains an invalid schema ({error})",
- )
+ with self.subTest(case=case):
+ try:
+ Validator.check_schema(case["schema"])
+ except jsonschema.SchemaError:
+ self.fail(
+ "Found an invalid schema."
+ "See the traceback for details on why."
+ )
else:
warnings.warn(f"No schema validator for {version.name}")
@@ -157,11 +222,12 @@ class SanityTests(unittest.TestCase):
"""
Validator = jsonschema.validators.validator_for(TESTSUITE_SCHEMA)
validator = Validator(TESTSUITE_SCHEMA)
- for tests in files(self.test_files):
- try:
- validator.validate(tests)
- except jsonschema.ValidationError as error:
- self.fail(str(error))
+ for path, cases in files(self.test_files):
+ with self.subTest(path=path):
+ try:
+ validator.validate(cases)
+ except jsonschema.ValidationError as error:
+ self.fail(str(error))
def main(arguments):
diff --git a/codecov.yml b/codecov.yml
deleted file mode 100644
index 640bd89..0000000
--- a/codecov.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-coverage:
- status:
- patch:
- default:
- target: 100%
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index f6315df..0000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,227 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-PYTHON = python
-PAPER =
-BUILDDIR = _build
-SOURCEDIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCEDIR)
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " applehelp to make an Apple Help Book"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " epub3 to make an epub3"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " xml to make Docutils-native XML files"
- @echo " pseudoxml to make pseudoxml-XML files for display purposes"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation"
- @echo " coverage to run coverage check of the documentation (if enabled)"
- @echo " spelling to run a spell check of the documentation"
- @echo " dummy to check syntax errors of document sources"
-
-.PHONY: clean
-clean:
- rm -rf $(BUILDDIR)/*
-
-.PHONY: html
-html:
- $(PYTHON) -m sphinx -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-.PHONY: dirhtml
-dirhtml:
- $(PYTHON) -m sphinx -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-.PHONY: singlehtml
-singlehtml:
- $(PYTHON) -m sphinx -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-.PHONY: json
-json:
- $(PYTHON) -m sphinx -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-.PHONY: htmlhelp
-htmlhelp:
- $(PYTHON) -m sphinx -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-.PHONY: qthelp
-qthelp:
- $(PYTHON) -m sphinx -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/jsonschema.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/jsonschema.qhc"
-
-.PHONY: applehelp
-applehelp:
- $(PYTHON) -m sphinx -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
- @echo
- @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
- @echo "N.B. You won't be able to view it unless you put it in" \
- "~/Library/Documentation/Help or install it in your application" \
- "bundle."
-
-.PHONY: devhelp
-devhelp:
- $(PYTHON) -m sphinx -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/jsonschema"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/jsonschema"
- @echo "# devhelp"
-
-.PHONY: epub
-epub:
- $(PYTHON) -m sphinx -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-.PHONY: epub3
-epub3:
- $(PYTHON) -m sphinx -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
- @echo
- @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
-
-.PHONY: latex
-latex:
- $(PYTHON) -m sphinx -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-.PHONY: latexpdf
-latexpdf:
- $(PYTHON) -m sphinx -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-.PHONY: latexpdfja
-latexpdfja:
- $(PYTHON) -m sphinx -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through platex and dvipdfmx..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-.PHONY: text
-text:
- $(PYTHON) -m sphinx -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-.PHONY: man
-man:
- $(PYTHON) -m sphinx -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-.PHONY: texinfo
-texinfo:
- $(PYTHON) -m sphinx -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-.PHONY: info
-info:
- $(PYTHON) -m sphinx -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-.PHONY: gettext
-gettext:
- $(PYTHON) -m sphinx -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-.PHONY: changes
-changes:
- $(PYTHON) -m sphinx -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-.PHONY: linkcheck
-linkcheck:
- $(PYTHON) -m sphinx -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-.PHONY: doctest
-doctest:
- $(PYTHON) -m sphinx -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
-
-.PHONY: coverage
-coverage:
- $(PYTHON) -m sphinx -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
- @echo "Testing of coverage in the sources finished, look at the " \
- "results in $(BUILDDIR)/coverage/python.txt."
-
-.PHONY: xml
-xml:
- $(PYTHON) -m sphinx -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
- @echo
- @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
-
-.PHONY: pseudoxml
-pseudoxml:
- $(PYTHON) -m sphinx -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
- @echo
- @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
-
-.PHONY: spelling
-spelling:
- $(PYTHON) -m sphinx -b spelling $(ALLSPHINXOPTS) $(BUILDDIR)/spelling
- @echo
- @echo "Build finished. The spelling files are in $(BUILDDIR)/spelling."
-
-.PHONY: dummy
-dummy:
- $(PYTHON) -m sphinx -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
- @echo
- @echo "Build finished. Dummy builder generates no files."
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index f595f16..0000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,254 +0,0 @@
-from importlib import metadata
-import os
-import re
-import sys
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-ext_paths = [os.path.abspath(os.path.pardir), os.path.dirname(__file__)]
-sys.path = ext_paths + sys.path
-
-# -- General configuration -------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-# needs_sphinx = "1.0"
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named "sphinx.ext.*") or your custom
-# ones.
-extensions = [
- "sphinx.ext.autodoc",
- "sphinx.ext.autosectionlabel",
- "sphinx.ext.coverage",
- "sphinx.ext.doctest",
- "sphinx.ext.intersphinx",
- "sphinx.ext.napoleon",
- "sphinx.ext.viewcode",
- "sphinx_autodoc_typehints",
- "sphinxcontrib.spelling",
- "jsonschema_role",
-]
-
-cache_path = "_cache"
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ["_templates"]
-
-# The suffix of source filenames.
-source_suffix = ".rst"
-
-# The encoding of source files.
-# source_encoding = "utf-8-sig"
-
-# The master toctree document.
-master_doc = "index"
-
-# General information about the project.
-project = "jsonschema"
-author = "Julian Berman"
-copyright = "2013, " + author
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# version: The short X.Y version
-# release: The full version, including alpha/beta/rc tags.
-release = metadata.version("jsonschema")
-version = release.partition("-")[0]
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-# today = ""
-# Else, today_fmt is used as the format for a strftime call.
-# today_fmt = "%B %d, %Y"
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ["_build", "_cache", "_static", "_templates"]
-
-# The reST default role (used for this markup: `text`) to use for all documents
-default_role = "any"
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = "sphinx"
-
-# A list of ignored prefixes for module index sorting.
-# modindex_common_prefix = []
-
-doctest_global_setup = """
-from jsonschema import *
-"""
-
-intersphinx_mapping = {
- "python": ("https://docs.python.org/3", None),
-}
-
-
-# -- Options for HTML output -----------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-html_theme = "furo"
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#
-# html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-# html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-# html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-# html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-# html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-# html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-# html_static_path = ["_static"]
-
-# If not "", a "Last updated on:" timestamp is inserted at every page bottom,
-# using the given strftime format.
-# html_last_updated_fmt = "%b %d, %Y"
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-# html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-# html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-# html_additional_pages = {}
-
-# If false, no module index is generated.
-# html_domain_indices = True
-
-# If false, no index is generated.
-# html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-# html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-# html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-# html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-# html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-# html_use_opensearch = ""
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-# html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = "jsonschemadoc"
-
-
-# -- Options for LaTeX output ----------------------------------------------
-
-# Grouping the document tree into LaTeX files. List of tuples (source
-# start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
- ("index", "jsonschema.tex", "jsonschema Documentation", author, "manual"),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-# latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-# latex_use_parts = False
-
-# If true, show page references after internal links.
-# latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-# latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-# latex_appendices = []
-
-# If false, no module index is generated.
-# latex_domain_indices = True
-
-
-# -- Options for manual page output ----------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [("index", "jsonschema", "jsonschema Documentation", [author], 1)]
-
-# If true, show URL addresses after external links.
-# man_show_urls = False
-
-
-# -- Options for Texinfo output --------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- (
- "index",
- "jsonschema",
- "jsonschema Documentation",
- author,
- "jsonschema",
- "One line description of project.",
- "Miscellaneous",
- ),
-]
-
-# Documents to append as an appendix to all manuals.
-# texinfo_appendices = []
-
-# If false, no module index is generated.
-# texinfo_domain_indices = True
-
-# How to display URL addresses: "footnote", "no", or "inline".
-# texinfo_show_urls = "footnote"
-
-# -- Options for the linkcheck builder ------------------------------------
-
-
-def entire_domain(host):
- return r"http.?://" + re.escape(host) + r"($|/.*)"
-
-
-linkcheck_ignore = [
- entire_domain("img.shields.io"),
- "https://github.com/python-jsonschema/jsonschema/actions",
- "https://github.com/python-jsonschema/jsonschema/workflows/CI/badge.svg",
-]
-
-# -- Options for sphinxcontrib-autosectionlabel ---------------------------
-
-autosectionlabel_prefix_document = True
-
-# -- Options for sphinxcontrib-spelling -----------------------------------
-
-spelling_word_list_filename = "spelling-wordlist.txt"
diff --git a/docs/creating.rst b/docs/creating.rst
deleted file mode 100644
index 810293f..0000000
--- a/docs/creating.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-.. currentmodule:: jsonschema.validators
-
-.. _creating-validators:
-
-=======================================
-Creating or Extending Validator Classes
-=======================================
-
-.. autofunction:: create
-
-.. autofunction:: extend
-
-.. autofunction:: validator_for
-
-.. autofunction:: validates
-
-
-Creating Validation Errors
---------------------------
-
-Any validating function that validates against a subschema should call
-``descend``, rather than ``iter_errors``. If it recurses into the
-instance, or schema, it should pass one or both of the ``path`` or
-``schema_path`` arguments to ``descend`` in order to properly maintain
-where in the instance or schema respectively the error occurred.
-
-The Validator Protocol
-----------------------
-
-``jsonschema`` defines a `protocol <typing.Protocol>`,
-`jsonschema.protocols.Validator` which can be used in type annotations to
-describe the type of a validator object.
-
-For full details, see `validator-protocol`.
diff --git a/docs/errors.rst b/docs/errors.rst
deleted file mode 100644
index 4ca11d1..0000000
--- a/docs/errors.rst
+++ /dev/null
@@ -1,406 +0,0 @@
-==========================
-Handling Validation Errors
-==========================
-
-.. currentmodule:: jsonschema.exceptions
-
-When an invalid instance is encountered, a `ValidationError` will be
-raised or returned, depending on which method or function is used.
-
-.. autoexception:: ValidationError
-
- The information carried by an error roughly breaks down into:
-
- =============== ================= ========================
- What Happened Why Did It Happen What Was Being Validated
- =============== ================= ========================
- `message` `context` `instance`
-
- `cause` `json_path`
-
- `path`
-
- `schema`
-
- `schema_path`
-
- `validator`
-
- `validator_value`
- =============== ================= ========================
-
-
- .. attribute:: message
-
- A human readable message explaining the error.
-
- .. attribute:: validator
-
- The name of the failed `validator
- <https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural>`_.
-
- .. attribute:: validator_value
-
- The value for the failed validator in the schema.
-
- .. attribute:: schema
-
- The full schema that this error came from. This is potentially a
- subschema from within the schema that was passed in originally,
- or even an entirely different schema if a :validator:`$ref` was
- followed.
-
- .. attribute:: relative_schema_path
-
- A `collections.deque` containing the path to the failed
- validator within the schema.
-
- .. attribute:: absolute_schema_path
-
- A `collections.deque` containing the path to the failed
- validator within the schema, but always relative to the
- *original* schema as opposed to any subschema (i.e. the one
- originally passed into a validator class, *not* `schema`\).
-
- .. attribute:: schema_path
-
- Same as `relative_schema_path`.
-
- .. attribute:: relative_path
-
- A `collections.deque` containing the path to the
- offending element within the instance. The deque can be empty if
- the error happened at the root of the instance.
-
- .. attribute:: absolute_path
-
- A `collections.deque` containing the path to the
- offending element within the instance. The absolute path
- is always relative to the *original* instance that was
- validated (i.e. the one passed into a validation method, *not*
- `instance`\). The deque can be empty if the error happened
- at the root of the instance.
-
- .. attribute:: json_path
-
- A `JSON path <https://goessner.net/articles/JsonPath/index.html>`_
- to the offending element within the instance.
-
- .. attribute:: path
-
- Same as `relative_path`.
-
- .. attribute:: instance
-
- The instance that was being validated. This will differ from
- the instance originally passed into ``validate`` if the
- validator object was in the process of validating a (possibly
- nested) element within the top-level instance. The path within
- the top-level instance (i.e. `ValidationError.path`) could
- be used to find this object, but it is provided for convenience.
-
- .. attribute:: context
-
- If the error was caused by errors in subschemas, the list of errors
- from the subschemas will be available on this property. The
- `schema_path` and `path` of these errors will be relative
- to the parent error.
-
- .. attribute:: cause
-
- If the error was caused by a *non*-validation error, the
- exception object will be here. Currently this is only used
- for the exception raised by a failed format checker in
- `jsonschema.FormatChecker.check`.
-
- .. attribute:: parent
-
- A validation error which this error is the `context` of.
- ``None`` if there wasn't one.
-
-
-In case an invalid schema itself is encountered, a `SchemaError` is
-raised.
-
-.. autoexception:: SchemaError
-
- The same attributes are present as for `ValidationError`\s.
-
-
-These attributes can be clarified with a short example:
-
-.. testcode::
-
- schema = {
- "items": {
- "anyOf": [
- {"type": "string", "maxLength": 2},
- {"type": "integer", "minimum": 5}
- ]
- }
- }
- instance = [{}, 3, "foo"]
- v = Draft202012Validator(schema)
- errors = sorted(v.iter_errors(instance), key=lambda e: e.path)
-
-The error messages in this situation are not very helpful on their own.
-
-.. testcode::
-
- for error in errors:
- print(error.message)
-
-outputs:
-
-.. testoutput::
-
- {} is not valid under any of the given schemas
- 3 is not valid under any of the given schemas
- 'foo' is not valid under any of the given schemas
-
-If we look at `ValidationError.path` on each of the errors, we can find
-out which elements in the instance correspond to each of the errors. In
-this example, `ValidationError.path` will have only one element, which
-will be the index in our list.
-
-.. testcode::
-
- for error in errors:
- print(list(error.path))
-
-.. testoutput::
-
- [0]
- [1]
- [2]
-
-Since our schema contained nested subschemas, it can be helpful to look at
-the specific part of the instance and subschema that caused each of the errors.
-This can be seen with the `ValidationError.instance` and
-`ValidationError.schema` attributes.
-
-With validators like :validator:`anyOf`, the `ValidationError.context`
-attribute can be used to see the sub-errors which caused the failure. Since
-these errors actually came from two separate subschemas, it can be helpful to
-look at the `ValidationError.schema_path` attribute as well to see where
-exactly in the schema each of these errors come from. In the case of sub-errors
-from the `ValidationError.context` attribute, this path will be relative
-to the `ValidationError.schema_path` of the parent error.
-
-.. testcode::
-
- for error in errors:
- for suberror in sorted(error.context, key=lambda e: e.schema_path):
- print(list(suberror.schema_path), suberror.message, sep=", ")
-
-.. testoutput::
-
- [0, 'type'], {} is not of type 'string'
- [1, 'type'], {} is not of type 'integer'
- [0, 'type'], 3 is not of type 'string'
- [1, 'minimum'], 3 is less than the minimum of 5
- [0, 'maxLength'], 'foo' is too long
- [1, 'type'], 'foo' is not of type 'integer'
-
-The string representation of an error combines some of these attributes for
-easier debugging.
-
-.. testcode::
-
- print(errors[1])
-
-.. testoutput::
-
- 3 is not valid under any of the given schemas
-
- Failed validating 'anyOf' in schema['items']:
- {'anyOf': [{'maxLength': 2, 'type': 'string'},
- {'minimum': 5, 'type': 'integer'}]}
-
- On instance[1]:
- 3
-
-
-ErrorTrees
-----------
-
-If you want to programmatically be able to query which properties or validators
-failed when validating a given instance, you probably will want to do so using
-`jsonschema.exceptions.ErrorTree` objects.
-
-.. autoclass:: jsonschema.exceptions.ErrorTree
- :members:
- :special-members:
- :exclude-members: __dict__,__weakref__
-
- .. attribute:: errors
-
- The mapping of validator names to the error objects (usually
- `jsonschema.exceptions.ValidationError`\s) at this level
- of the tree.
-
-Consider the following example:
-
-.. testcode::
-
- schema = {
- "type" : "array",
- "items" : {"type" : "number", "enum" : [1, 2, 3]},
- "minItems" : 3,
- }
- instance = ["spam", 2]
-
-For clarity's sake, the given instance has three errors under this schema:
-
-.. testcode::
-
- v = Draft202012Validator(schema)
- for error in sorted(v.iter_errors(["spam", 2]), key=str):
- print(error.message)
-
-.. testoutput::
-
- 'spam' is not of type 'number'
- 'spam' is not one of [1, 2, 3]
- ['spam', 2] is too short
-
-Let's construct an `jsonschema.exceptions.ErrorTree` so that we
-can query the errors a bit more easily than by just iterating over the
-error objects.
-
-.. testcode::
-
- tree = ErrorTree(v.iter_errors(instance))
-
-As you can see, `jsonschema.exceptions.ErrorTree` takes an
-iterable of `ValidationError`\s when constructing a tree so
-you can directly pass it the return value of a validator object's
-`jsonschema.protocols.Validator.iter_errors` method.
-
-`ErrorTree`\s support a number of useful operations. The first one we
-might want to perform is to check whether a given element in our instance
-failed validation. We do so using the :keyword:`in` operator:
-
-.. doctest::
-
- >>> 0 in tree
- True
-
- >>> 1 in tree
- False
-
-The interpretation here is that the 0th index into the instance (``"spam"``)
-did have an error (in fact it had 2), while the 1th index (``2``) did not (i.e.
-it was valid).
-
-If we want to see which errors a child had, we index into the tree and look at
-the `ErrorTree.errors` attribute.
-
-.. doctest::
-
- >>> sorted(tree[0].errors)
- ['enum', 'type']
-
-Here we see that the :validator:`enum` and :validator:`type` validators failed
-for index ``0``. In fact `ErrorTree.errors` is a dict, whose values are
-the `ValidationError`\s, so we can get at those directly if we want
-them.
-
-.. doctest::
-
- >>> print(tree[0].errors["type"].message)
- 'spam' is not of type 'number'
-
-Of course this means that if we want to know if a given named
-validator failed for a given index, we check for its presence in
-`ErrorTree.errors`:
-
-.. doctest::
-
- >>> "enum" in tree[0].errors
- True
-
- >>> "minimum" in tree[0].errors
- False
-
-Finally, if you were paying close enough attention, you'll notice that we
-haven't seen our :validator:`minItems` error appear anywhere yet. This is
-because :validator:`minItems` is an error that applies globally to the instance
-itself. So it appears in the root node of the tree.
-
-.. doctest::
-
- >>> "minItems" in tree.errors
- True
-
-That's all you need to know to use error trees.
-
-To summarize, each tree contains child trees that can be accessed by
-indexing the tree to get the corresponding child tree for a given index
-into the instance. Each tree and child has a `ErrorTree.errors`
-attribute, a dict, that maps the failed validator name to the
-corresponding validation error.
-
-
-best_match and relevance
-------------------------
-
-The `best_match` function is a simple but useful function for attempting
-to guess the most relevant error in a given bunch.
-
-.. doctest::
-
- >>> from jsonschema import Draft202012Validator
- >>> from jsonschema.exceptions import best_match
-
- >>> schema = {
- ... "type": "array",
- ... "minItems": 3,
- ... }
- >>> print(best_match(Draft202012Validator(schema).iter_errors(11)).message)
- 11 is not of type 'array'
-
-
-.. autofunction:: best_match
-
-
-.. function:: relevance(validation_error)
-
- A key function that sorts errors based on heuristic relevance.
-
- If you want to sort a bunch of errors entirely, you can use
- this function to do so. Using this function as a key to e.g.
- `sorted` or `max` will cause more relevant errors to be
- considered greater than less relevant ones.
-
- Within the different validators that can fail, this function
- considers :validator:`anyOf` and :validator:`oneOf` to be *weak*
- validation errors, and will sort them lower than other validators at
- the same level in the instance.
-
- If you want to change the set of weak [or strong] validators you can create
- a custom version of this function with `by_relevance` and provide a
- different set of each.
-
-.. doctest::
-
- >>> schema = {
- ... "properties": {
- ... "name": {"type": "string"},
- ... "phones": {
- ... "properties": {
- ... "home": {"type": "string"}
- ... },
- ... },
- ... },
- ... }
- >>> instance = {"name": 123, "phones": {"home": [123]}}
- >>> errors = Draft202012Validator(schema).iter_errors(instance)
- >>> [
- ... e.path[-1]
- ... for e in sorted(errors, key=exceptions.relevance)
- ... ]
- ['home', 'name']
-
-
-.. autofunction:: by_relevance
diff --git a/docs/faq.rst b/docs/faq.rst
deleted file mode 100644
index 62b3d4b..0000000
--- a/docs/faq.rst
+++ /dev/null
@@ -1,291 +0,0 @@
-==========================
-Frequently Asked Questions
-==========================
-
-
-My schema specifies format validation. Why do invalid instances seem valid?
----------------------------------------------------------------------------
-
-The :validator:`format` validator can be a bit of a stumbling block for new
-users working with JSON Schema.
-
-In a schema such as:
-
-.. code-block:: json
-
- {"type": "string", "format": "date"}
-
-JSON Schema specifications have historically differentiated between the
-:validator:`format` validator and other validators. In particular, the
-:validator:`format` validator was specified to be *informational* as much
-as it may be used for validation.
-
-In other words, for many use cases, schema authors may wish to use
-values for the :validator:`format` validator but have no expectation
-they be validated alongside other required assertions in a schema.
-
-Of course this does not represent all or even most use cases -- many
-schema authors *do* wish to assert that instances conform fully, even to
-the specific format mentioned.
-
-In drafts prior to ``draft2019-09``, the decision on whether to
-automatically enable :validator:`format` validation was left up to
-validation implementations such as this one.
-
-This library made the choice to leave it off by default, for two reasons:
-
- * for forward compatibility and implementation complexity reasons
- -- if :validator:`format` validation were on by default, and a
- future draft of JSON Schema introduced a hard-to-implement format,
- either the implementation of that format would block releases of
- this library until it were implemented, or the behavior surrounding
- :validator:`format` would need to be even more complex than simply
- defaulting to be on. It therefore was safer to start with it off,
- and defend against the expectation that a given format would always
- automatically work.
-
- * given that a common use of JSON Schema is for portability across
- languages (and therefore implementations of JSON Schema), so that
- users be aware of this point itself regarding :validator:`format`
- validation, and therefore remember to check any *other*
- implementations they were using to ensure they too were explicitly
- enabled for :validator:`format` validation.
-
-As of ``draft2019-09`` however, the opt-out by default behavior
-mentioned here is now *required* for all validators.
-
-Difficult as this may sound for new users, at this point it at least
-means they should expect the same behavior that has always been
-implemented here, across any other implementation they encounter.
-
-.. seealso::
-
- `Draft 2019-09's release notes on format <https://json-schema.org/draft/2019-09/release-notes.html#format-vocabulary>`_
-
- for upstream details on the behavior of format and how it has changed
- in ``draft2019-09``
-
- `validating formats`
-
- for details on how to enable format validation
-
- `jsonschema.FormatChecker`
-
- the object which implements format validation
-
-
-How do I configure a base URI for ``$ref`` resolution using local files?
-------------------------------------------------------------------------
-
-`jsonschema` supports loading schemas from the filesystem.
-
-The most common mistake when configuring a :class:`~jsonschema.RefResolver`
-to retrieve schemas from the local filesystem is to give it a base URI
-which points to a directory, but forget to add a trailing slash.
-
-For example, given a directory ``/tmp/foo/`` with ``bar/schema.json``
-within it, you should use something like:
-
-.. code-block:: python
-
- from pathlib import Path
-
- import jsonschema.validators
-
- path = Path("/tmp/foo")
- resolver = jsonschema.validators.RefResolver(
- base_uri=f"{path.as_uri()}/",
- referrer=True,
- )
- jsonschema.validate(
- instance={},
- schema={"$ref": "bar/schema.json"},
- resolver=resolver,
- )
-
-where note:
-
- * the base URI has a trailing slash, even though
- `pathlib.PurePath.as_uri` does not add it!
- * any relative refs are now given relative to the provided directory
-
-If you forget the trailing slash, you'll find references are resolved a
-directory too high.
-
-You're likely familiar with this behavior from your browser. If you
-visit a page at ``https://example.com/foo``, then links on it like
-``<a href="./bar">`` take you to ``https://example.com/bar``, not
-``https://example.com/foo/bar``. For this reason many sites will
-redirect ``https://example.com/foo`` to ``https://example.com/foo/``,
-i.e. add the trailing slash, so that relative links on the page will keep the
-last path component.
-
-There are, in summary, 2 ways to do this properly:
-
-* Remember to include a trailing slash, so your base URI is
- ``file:///foo/bar/`` rather than ``file:///foo/bar``, as shown above
-* Use a file within the directory as your base URI rather than the
- directory itself, i.e. ``file://foo/bar/baz.json``, which will of course
- cause ``baz.json`` to be removed while resolving relative URIs
-
-Why doesn't my schema's default property set the default on my instance?
-------------------------------------------------------------------------
-
-The basic answer is that the specification does not require that
-:validator:`default` actually do anything.
-
-For an inkling as to *why* it doesn't actually do anything, consider
-that none of the other validators modify the instance either. More
-importantly, having :validator:`default` modify the instance can produce
-quite peculiar things. It's perfectly valid (and perhaps even useful)
-to have a default that is not valid under the schema it lives in! So an
-instance modified by the default would pass validation the first time,
-but fail the second!
-
-Still, filling in defaults is a thing that is useful. `jsonschema`
-allows you to `define your own validator classes and callables
-<creating>`, so you can easily create an `jsonschema.protocols.Validator`
-that does do default setting. Here's some code to get you started. (In
-this code, we add the default properties to each object *before* the
-properties are validated, so the default values themselves will need to
-be valid under the schema.)
-
- .. testcode::
-
- from jsonschema import Draft202012Validator, validators
-
-
- def extend_with_default(validator_class):
- validate_properties = validator_class.VALIDATORS["properties"]
-
- def set_defaults(validator, properties, instance, schema):
- for property, subschema in properties.items():
- if "default" in subschema:
- instance.setdefault(property, subschema["default"])
-
- for error in validate_properties(
- validator, properties, instance, schema,
- ):
- yield error
-
- return validators.extend(
- validator_class, {"properties" : set_defaults},
- )
-
-
- DefaultValidatingValidator = extend_with_default(Draft202012Validator)
-
-
- # Example usage:
- obj = {}
- schema = {'properties': {'foo': {'default': 'bar'}}}
- # Note jsonschem.validate(obj, schema, cls=DefaultValidatingValidator)
- # will not work because the metaschema contains `default` directives.
- DefaultValidatingValidator(schema).validate(obj)
- assert obj == {'foo': 'bar'}
-
-
-See the above-linked document for more info on how this works, but
-basically, it just extends the :validator:`properties` validator on
-a `jsonschema.Draft202012Validator` to then go ahead and update all the
-defaults.
-
-.. note::
-
- If you're interested in a more interesting solution to a larger
- class of these types of transformations, keep an eye on `Seep
- <https://github.com/Julian/Seep>`_, which is an experimental
- data transformation and extraction library written on top of
- `jsonschema`.
-
-
-.. hint::
-
- The above code can provide default values for an entire object and
- all of its properties, but only if your schema provides a default
- value for the object itself, like so:
-
- .. testcode::
-
- schema = {
- "type": "object",
- "properties": {
- "outer-object": {
- "type": "object",
- "properties" : {
- "inner-object": {
- "type": "string",
- "default": "INNER-DEFAULT"
- }
- },
- "default": {} # <-- MUST PROVIDE DEFAULT OBJECT
- }
- }
- }
-
- obj = {}
- DefaultValidatingValidator(schema).validate(obj)
- assert obj == {'outer-object': {'inner-object': 'INNER-DEFAULT'}}
-
- ...but if you don't provide a default value for your object, then
- it won't be instantiated at all, much less populated with default
- properties.
-
- .. testcode::
-
- del schema["properties"]["outer-object"]["default"]
- obj2 = {}
- DefaultValidatingValidator(schema).validate(obj2)
- assert obj2 == {} # whoops
-
-
-How do jsonschema version numbers work?
----------------------------------------
-
-``jsonschema`` tries to follow the `Semantic Versioning
-<https://semver.org/>`_ specification.
-
-This means broadly that no backwards-incompatible changes should be made
-in minor releases (and certainly not in dot releases).
-
-The full picture requires defining what constitutes a
-backwards-incompatible change.
-
-The following are simple examples of things considered public API,
-and therefore should *not* be changed without bumping a major version
-number:
-
- * module names and contents, when not marked private by Python
- convention (a single leading underscore)
-
- * function and object signature (parameter order and name)
-
-The following are *not* considered public API and may change without
-notice:
-
- * the exact wording and contents of error messages; typical reasons
- to rely on this seem to involve downstream tests in packages using
- `jsonschema`. These use cases are encouraged to use the extensive
- introspection provided in `jsonschema.exceptions.ValidationError`\s
- instead to make meaningful assertions about what failed rather than
- relying on *how* what failed is explained to a human.
-
- * the order in which validation errors are returned or raised
-
- * the contents of the ``jsonschema.tests`` package
-
- * the contents of the ``jsonschema.benchmarks`` package
-
- * the specific non-zero error codes presented by the command line
- interface
-
- * the exact representation of errors presented by the command line
- interface, other than that errors represented by the plain outputter
- will be reported one per line
-
- * anything marked private
-
-With the exception of the last two of those, flippant changes are
-avoided, but changes can and will be made if there is improvement to be
-had. Feel free to open an issue ticket if there is a specific issue or
-question worth raising.
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index e4d7252..0000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-.. module:: jsonschema
-.. include:: ../README.rst
-
-
-Contents
---------
-
-.. toctree::
- :maxdepth: 2
-
- validate
- errors
- references
- creating
- faq
-
-
-Indices and tables
-==================
-
-* `genindex`
-* `search`
diff --git a/docs/jsonschema_role.py b/docs/jsonschema_role.py
deleted file mode 100644
index 7610c06..0000000
--- a/docs/jsonschema_role.py
+++ /dev/null
@@ -1,146 +0,0 @@
-from contextlib import suppress
-from datetime import datetime
-from importlib import metadata
-from urllib.parse import urljoin
-import os
-import urllib.request
-
-from docutils import nodes
-from lxml import html
-import certifi
-
-__version__ = "1.2.0"
-
-BASE_URL = "https://json-schema.org/draft-07/"
-VALIDATION_SPEC = urljoin(BASE_URL, "json-schema-validation.html")
-REF_URL = urljoin(BASE_URL, "json-schema-core.html#rfc.section.8.3")
-SCHEMA_URL = urljoin(BASE_URL, "json-schema-core.html#rfc.section.7")
-
-
-def setup(app):
- """
- Install the plugin.
-
- Arguments:
-
- app (sphinx.application.Sphinx):
-
- the Sphinx application context
- """
-
- app.add_config_value("cache_path", "_cache", "")
-
- os.makedirs(app.config.cache_path, exist_ok=True)
-
- path = os.path.join(app.config.cache_path, "spec.html")
- spec = fetch_or_load(path)
- app.add_role("validator", docutils_does_not_allow_using_classes(spec))
-
- return dict(version=__version__, parallel_read_safe=True)
-
-
-def fetch_or_load(spec_path):
- """
- Fetch a new specification or use the cache if it's current.
-
- Arguments:
-
- cache_path:
-
- the path to a cached specification
- """
-
- headers = {
- "User-Agent": "python-jsonschema v{} - documentation build v{}".format(
- metadata.version("jsonschema"),
- __version__,
- ),
- }
-
- with suppress(FileNotFoundError):
- modified = datetime.utcfromtimestamp(os.path.getmtime(spec_path))
- date = modified.strftime("%a, %d %b %Y %I:%M:%S UTC")
- headers["If-Modified-Since"] = date
-
- request = urllib.request.Request(VALIDATION_SPEC, headers=headers)
- response = urllib.request.urlopen(request, cafile=certifi.where())
-
- if response.code == 200:
- with open(spec_path, "w+b") as spec:
- spec.writelines(response)
- spec.seek(0)
- return html.parse(spec)
-
- with open(spec_path) as spec:
- return html.parse(spec)
-
-
-def docutils_does_not_allow_using_classes(spec):
- """
- Yeah.
-
- It doesn't allow using a class because it does annoying stuff like
- try to set attributes on the callable object rather than just
- keeping a dict.
- """
-
- def validator(name, raw_text, text, lineno, inliner):
- """
- Link to the JSON Schema documentation for a validator.
-
- Arguments:
-
- name (str):
-
- the name of the role in the document
-
- raw_source (str):
-
- the raw text (role with argument)
-
- text (str):
-
- the argument given to the role
-
- lineno (int):
-
- the line number
-
- inliner (docutils.parsers.rst.states.Inliner):
-
- the inliner
-
- Returns:
-
- tuple:
-
- a 2-tuple of nodes to insert into the document and an
- iterable of system messages, both possibly empty
- """
-
- if text == "$ref":
- return [nodes.reference(raw_text, text, refuri=REF_URL)], []
- elif text == "$schema":
- return [nodes.reference(raw_text, text, refuri=SCHEMA_URL)], []
-
- # find the header in the validation spec containing matching text
- header = spec.xpath("//h1[contains(text(), '{0}')]".format(text))
-
- if len(header) == 0:
- inliner.reporter.warning(
- "Didn't find a target for {0}".format(text),
- )
- uri = VALIDATION_SPEC
- else:
- if len(header) > 1:
- inliner.reporter.info(
- "Found multiple targets for {0}".format(text),
- )
-
- # get the href from link in the header
- uri = urljoin(VALIDATION_SPEC, header[0].find("a").attrib["href"])
-
- reference = nodes.reference(raw_text, text, refuri=uri)
- return [reference], []
-
- return validator
diff --git a/docs/make.bat b/docs/make.bat
deleted file mode 100644
index fcb914f..0000000
--- a/docs/make.bat
+++ /dev/null
@@ -1,190 +0,0 @@
-@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-set I18NSPHINXOPTS=%SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
- :help
- echo.Please use `make ^<target^>` where ^<target^> is one of
- echo. html to make standalone HTML files
- echo. dirhtml to make HTML files named index.html in directories
- echo. singlehtml to make a single large HTML file
- echo. pickle to make pickle files
- echo. json to make JSON files
- echo. htmlhelp to make HTML files and a HTML help project
- echo. qthelp to make HTML files and a qthelp project
- echo. devhelp to make HTML files and a Devhelp project
- echo. epub to make an epub
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
- echo. text to make text files
- echo. man to make manual pages
- echo. texinfo to make Texinfo files
- echo. gettext to make PO message catalogs
- echo. changes to make an overview over all changed/added/deprecated items
- echo. linkcheck to check all external links for integrity
- echo. doctest to run all doctests embedded in the documentation if enabled
- goto end
-)
-
-if "%1" == "clean" (
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-if "%1" == "html" (
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "dirhtml" (
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
- goto end
-)
-
-if "%1" == "singlehtml" (
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
- goto end
-)
-
-if "%1" == "pickle" (
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the pickle files.
- goto end
-)
-
-if "%1" == "json" (
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the JSON files.
- goto end
-)
-
-if "%1" == "htmlhelp" (
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
- goto end
-)
-
-if "%1" == "qthelp" (
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\jsonschema.qhcp
- echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\jsonschema.ghc
- goto end
-)
-
-if "%1" == "devhelp" (
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished.
- goto end
-)
-
-if "%1" == "epub" (
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
- goto end
-)
-
-if "%1" == "latex" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "text" (
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The text files are in %BUILDDIR%/text.
- goto end
-)
-
-if "%1" == "man" (
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
- goto end
-)
-
-if "%1" == "texinfo" (
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
- goto end
-)
-
-if "%1" == "gettext" (
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
- goto end
-)
-
-if "%1" == "changes" (
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
- if errorlevel 1 exit /b 1
- echo.
- echo.The overview file is in %BUILDDIR%/changes.
- goto end
-)
-
-if "%1" == "linkcheck" (
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
- if errorlevel 1 exit /b 1
- echo.
- echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-:end
diff --git a/docs/references.rst b/docs/references.rst
deleted file mode 100644
index 9f24299..0000000
--- a/docs/references.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-=========================
-Resolving JSON References
-=========================
-
-
-.. currentmodule:: jsonschema
-
-.. autoclass:: RefResolver
- :members:
-
-.. autoexception:: RefResolutionError
-
- A JSON reference failed to resolve.
diff --git a/docs/requirements.in b/docs/requirements.in
deleted file mode 100644
index 06623c0..0000000
--- a/docs/requirements.in
+++ /dev/null
@@ -1,6 +0,0 @@
-file:.#egg=jsonschema
-furo
-lxml
-sphinx
-sphinx-autodoc-typehints
-sphinxcontrib-spelling
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index d35464c..0000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# This file is autogenerated by pip-compile with python 3.10
-# To update, run:
-#
-# pip-compile docs/requirements.in
-#
-alabaster==0.7.12
- # via sphinx
-attrs==22.1.0
- # via jsonschema
-babel==2.10.3
- # via sphinx
-beautifulsoup4==4.11.1
- # via furo
-certifi==2022.6.15
- # via requests
-charset-normalizer==2.1.0
- # via requests
-docutils==0.19
- # via sphinx
-furo==2022.6.21
- # via -r docs/requirements.in
-idna==3.3
- # via requests
-imagesize==1.4.1
- # via sphinx
-jinja2==3.1.2
- # via sphinx
-file:.#egg=jsonschema
- # via -r docs/requirements.in
-lxml==4.9.1
- # via -r docs/requirements.in
-markupsafe==2.1.1
- # via jinja2
-packaging==21.3
- # via sphinx
-pyenchant==3.2.2
- # via sphinxcontrib-spelling
-pygments==2.12.0
- # via
- # furo
- # sphinx
-pyparsing==3.0.9
- # via packaging
-pyrsistent==0.18.1
- # via jsonschema
-pytz==2022.1
- # via babel
-requests==2.28.1
- # via sphinx
-snowballstemmer==2.2.0
- # via sphinx
-soupsieve==2.3.2.post1
- # via beautifulsoup4
-sphinx==5.1.1
- # via
- # -r docs/requirements.in
- # furo
- # sphinx-autodoc-typehints
- # sphinx-basic-ng
- # sphinxcontrib-spelling
-sphinx-autodoc-typehints==1.19.0
- # via -r docs/requirements.in
-sphinx-basic-ng==0.0.1a12
- # via furo
-sphinxcontrib-applehelp==1.0.2
- # via sphinx
-sphinxcontrib-devhelp==1.0.2
- # via sphinx
-sphinxcontrib-htmlhelp==2.0.0
- # via sphinx
-sphinxcontrib-jsmath==1.0.1
- # via sphinx
-sphinxcontrib-qthelp==1.0.3
- # via sphinx
-sphinxcontrib-serializinghtml==1.1.5
- # via sphinx
-sphinxcontrib-spelling==7.6.0
- # via -r docs/requirements.in
-urllib3==1.26.11
- # via requests
diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt
deleted file mode 100644
index ab42031..0000000
--- a/docs/spelling-wordlist.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-# this appears to be misinterpreting Napoleon types as prose, sigh...
-Validator
-TypeChecker
-UnknownType
-ValidationError
-
-# 0th, sigh...
-th
-callables
-deque
-dereferences
-filesystem
-hostname
-implementers
-indices
-# ipv4/6, sigh...
-ipv
-iterable
-iteratively
-jsonschema
-majorly
-metaschema
-online
-outputter
-pre
-programmatically
-recurses
-regex
-repr
-sensical
-subschema
-subschemas
-subscopes
-uri
-validator
-validators
-versioned
-schemas
-
-Zac
-HD
-
-Berman
-Libera
-GPL
diff --git a/docs/validate.rst b/docs/validate.rst
deleted file mode 100644
index 744ea8a..0000000
--- a/docs/validate.rst
+++ /dev/null
@@ -1,288 +0,0 @@
-=================
-Schema Validation
-=================
-
-
-.. currentmodule:: jsonschema
-
-
-The Basics
-----------
-
-The simplest way to validate an instance under a given schema is to use the
-:func:`validate` function.
-
-.. autofunction:: validate
-
-.. [#] For information on creating JSON schemas to validate
- your data, there is a good introduction to JSON Schema
- fundamentals underway at `Understanding JSON Schema
- <https://json-schema.org/understanding-json-schema/>`_
-
-.. _validator-protocol:
-
-The Validator Protocol
------------------------
-
-`jsonschema` defines a protocol that all validator
-classes should adhere to.
-
-.. autoclass:: jsonschema.protocols.Validator
- :members:
-
-All of the `versioned validators <versioned-validators>` that are included with
-`jsonschema` adhere to the protocol, and implementers of validator classes
-that extend or complement the ones included should adhere to it as well. For
-more information see `creating-validators`.
-
-Type Checking
--------------
-
-To handle JSON Schema's :validator:`type` property, a `Validator` uses
-an associated `TypeChecker`. The type checker provides an immutable
-mapping between names of types and functions that can test if an instance is
-of that type. The defaults are suitable for most users - each of the
-`versioned validators <versioned-validators>` that are included with
-`jsonschema` have a `TypeChecker` that can correctly handle their respective
-versions.
-
-.. seealso:: `validating-types`
-
- For an example of providing a custom type check.
-
-.. autoclass:: TypeChecker
- :members:
-
-.. autoexception:: jsonschema.exceptions.UndefinedTypeCheck
-
- Raised when trying to remove a type check that is not known to this
- TypeChecker, or when calling `jsonschema.TypeChecker.is_type`
- directly.
-
-.. _validating-types:
-
-Validating With Additional Types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Occasionally it can be useful to provide additional or alternate types when
-validating the JSON Schema's :validator:`type` property.
-
-`jsonschema` tries to strike a balance between performance in the common
-case and generality. For instance, JSON Schema defines a ``number`` type, which
-can be validated with a schema such as ``{"type" : "number"}``. By default,
-this will accept instances of Python `numbers.Number`. This includes in
-particular `int`\s and `float`\s, along with
-`decimal.Decimal` objects, `complex` numbers etc. For
-``integer`` and ``object``, however, rather than checking for
-`numbers.Integral` and `collections.abc.Mapping`,
-`jsonschema` simply checks for `int` and `dict`, since the
-more general instance checks can introduce significant slowdown, especially
-given how common validating these types are.
-
-If you *do* want the generality, or just want to add a few specific additional
-types as being acceptable for a validator object, then you should update an
-existing `TypeChecker` or create a new one. You may then create a new
-`Validator` via `jsonschema.validators.extend`.
-
-.. testcode::
-
- from jsonschema import validators
-
- class MyInteger(object):
- pass
-
- def is_my_int(checker, instance):
- return (
- Draft202012Validator.TYPE_CHECKER.is_type(instance, "number") or
- isinstance(instance, MyInteger)
- )
-
- type_checker = Draft202012Validator.TYPE_CHECKER.redefine(
- "number", is_my_int,
- )
-
- CustomValidator = validators.extend(
- Draft202012Validator,
- type_checker=type_checker,
- )
- validator = CustomValidator(schema={"type" : "number"})
-
-
-.. autoexception:: jsonschema.exceptions.UnknownType
-
-.. _versioned-validators:
-
-Versioned Validators
---------------------
-
-`jsonschema` ships with validator classes for various versions of
-the JSON Schema specification. For details on the methods and attributes
-that each validator class provides see the `Validator` protocol,
-which each included validator class implements.
-
-.. autoclass:: Draft202012Validator
-
-.. autoclass:: Draft201909Validator
-
-.. autoclass:: Draft7Validator
-
-.. autoclass:: Draft6Validator
-
-.. autoclass:: Draft4Validator
-
-.. autoclass:: Draft3Validator
-
-
-For example, if you wanted to validate a schema you created against the
-Draft 2020-12 meta-schema, you could use:
-
-.. testcode::
-
- from jsonschema import Draft202012Validator
-
- schema = {
- "$schema": Draft202012Validator.META_SCHEMA["$id"],
-
- "type": "object",
- "properties": {
- "name": {"type": "string"},
- "email": {"type": "string"},
- },
- "required": ["email"]
- }
- Draft202012Validator.check_schema(schema)
-
-
-.. _validating formats:
-
-Validating Formats
-------------------
-
-JSON Schema defines the :validator:`format` property which can be used to check
-if primitive types (``string``\s, ``number``\s, ``boolean``\s) conform to
-well-defined formats. By default, no validation is enforced, but optionally,
-validation can be enabled by hooking in a format-checking object into an
-`Validator`.
-
-.. doctest::
-
- >>> validate("127.0.0.1", {"format" : "ipv4"})
- >>> validate(
- ... instance="-12",
- ... schema={"format" : "ipv4"},
- ... format_checker=draft202012_format_checker,
- ... )
- Traceback (most recent call last):
- ...
- ValidationError: "-12" is not a "ipv4"
-
-.. autoclass:: FormatChecker
- :members:
- :exclude-members: cls_checks
-
- .. attribute:: checkers
-
- A mapping of currently known formats to tuple of functions that
- validate them and errors that should be caught. New checkers can be
- added and removed either per-instance or globally for all checkers
- using the `FormatChecker.checks` or `FormatChecker.cls_checks`
- decorators respectively.
-
- .. classmethod:: cls_checks(format, raises=())
-
- Register a decorated function as *globally* validating a new format.
-
- Any instance created after this function is called will pick up the
- supplied checker.
-
- :argument str format: the format that the decorated function will check
- :argument Exception raises: the exception(s) raised
- by the decorated function when an invalid instance is
- found. The exception object will be accessible as the
- `jsonschema.exceptions.ValidationError.cause` attribute
- of the resulting validation error.
-
-
-.. autoexception:: FormatError
- :members:
-
-
-There are a number of default checkers that `FormatChecker`\s know how
-to validate. Their names can be viewed by inspecting the
-`FormatChecker.checkers` attribute. Certain checkers will only be
-available if an appropriate package is available for use. The easiest way to
-ensure you have what is needed is to install ``jsonschema`` using the
-``format`` or ``format_nongpl`` collection of optional dependencies -- e.g.
-
-.. code-block:: sh
-
- $ pip install jsonschema[format]
-
-which will install all of the below dependencies for all formats.
-
-Or if you want to install MIT-license compatible dependencies only:
-
-.. code-block:: sh
-
- $ pip install jsonschema[format_nongpl]
-
-The non-GPL extra is intended to not install any direct dependencies
-that are GPL (but that of course end-users should do their own verification).
-At the moment, it supports all the available checkers except for ``iri`` and
-``iri-reference``.
-
-The more specific list of available checkers, along with their requirement
-(if any,) are listed below.
-
-.. note::
-
- If the following packages are not installed when using a checker
- that requires it, validation will succeed without throwing an error,
- as specified by the JSON Schema specification.
-
-========================= ====================
-Checker Notes
-========================= ====================
-``color`` requires webcolors_
-``date``
-``date-time`` requires rfc3339-validator_
-``duration`` requires isoduration_
-``email``
-``hostname`` requires fqdn_
-``idn-hostname`` requires idna_
-``ipv4``
-``ipv6`` OS must have `socket.inet_pton` function
-``iri`` requires rfc3987_
-``iri-reference`` requires rfc3987_
-``json-pointer`` requires jsonpointer_
-``regex``
-``relative-json-pointer`` requires jsonpointer_
-``time`` requires rfc3339-validator_
-``uri`` requires rfc3987_ or rfc3986-validator_
-``uri-reference`` requires rfc3987_ or rfc3986-validator_
-``uri-template`` requires uri-template_
-========================= ====================
-
-
-.. _fqdn: https://pypi.org/pypi/fqdn/
-.. _idna: https://pypi.org/pypi/idna/
-.. _isoduration: https://pypi.org/pypi/isoduration/
-.. _jsonpointer: https://pypi.org/pypi/jsonpointer/
-.. _rfc3339-validator: https://pypi.org/project/rfc3339-validator/
-.. _rfc3986-validator: https://pypi.org/project/rfc3986-validator/
-.. _rfc3987: https://pypi.org/pypi/rfc3987/
-.. _rfc5322: https://tools.ietf.org/html/rfc5322#section-3.4.1
-.. _uri-template: https://pypi.org/pypi/uri-template/
-.. _webcolors: https://pypi.org/pypi/webcolors/
-
-.. note::
-
- Since in most cases "validating" an email address is an attempt
- instead to confirm that mail sent to it will deliver to a recipient,
- and that that recipient is the correct one the email is intended
- for, and since many valid email addresses are in many places
- incorrectly rejected, and many invalid email addresses are in many
- places incorrectly accepted, the ``email`` format validator only
- provides a sanity check, not full rfc5322_ validation.
-
- The same applies to the ``idn-email`` format.
diff --git a/json/.github/workflows/ci.yml b/json/.github/workflows/ci.yml
deleted file mode 100644
index a826069..0000000
--- a/json/.github/workflows/ci.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: Test Suite Sanity Checking
-
-on:
- push:
- pull_request:
- release:
- types: [published]
- schedule:
- # Daily at 6:42, arbitrarily as a time that's possibly non-busy
- - cron: '42 6 * * *'
-
-jobs:
- ci:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- - name: Set up Python
- uses: actions/setup-python@v4
- with:
- python-version: '3.x'
- - name: Install tox
- run: python -m pip install tox
- - name: Run the sanity checks
- run: python -m tox
diff --git a/json/.gitignore b/json/.gitignore
deleted file mode 100644
index 68bc17f..0000000
--- a/json/.gitignore
+++ /dev/null
@@ -1,160 +0,0 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-share/python-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-MANIFEST
-
-# PyInstaller
-# Usually these files are written by a python script from a template
-# before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.nox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*.cover
-*.py,cover
-.hypothesis/
-.pytest_cache/
-cover/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-db.sqlite3
-db.sqlite3-journal
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-.pybuilder/
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# IPython
-profile_default/
-ipython_config.py
-
-# pyenv
-# For a library or package, you might want to ignore these files since the code is
-# intended to run in multiple environments; otherwise, check them in:
-# .python-version
-
-# pipenv
-# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
-# However, in case of collaboration, if having platform-specific dependencies or dependencies
-# having no cross-platform support, pipenv may install dependencies that don't work, or not
-# install all needed dependencies.
-#Pipfile.lock
-
-# poetry
-# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
-# This is especially recommended for binary packages to ensure reproducibility, and is more
-# commonly ignored for libraries.
-# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
-#poetry.lock
-
-# pdm
-# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
-#pdm.lock
-# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
-# in version control.
-# https://pdm.fming.dev/#use-with-ide
-.pdm.toml
-
-# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
-__pypackages__/
-
-# Celery stuff
-celerybeat-schedule
-celerybeat.pid
-
-# SageMath parsed files
-*.sage.py
-
-# Environments
-.env
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-.dmypy.json
-dmypy.json
-
-# Pyre type checker
-.pyre/
-
-# pytype static type analyzer
-.pytype/
-
-# Cython debug symbols
-cython_debug/
-
-# PyCharm
-# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
-# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
-# and can be added to the global gitignore or merged into this file. For a more nuclear
-# option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/
diff --git a/json/tests/draft3/optional/bignum.json b/json/tests/draft3/optional/bignum.json
deleted file mode 100644
index ccc7c17..0000000
--- a/json/tests/draft3/optional/bignum.json
+++ /dev/null
@@ -1,107 +0,0 @@
-[
- {
- "description": "integer",
- "schema": {"type": "integer"},
- "tests": [
- {
- "description": "a bignum is an integer",
- "data": 12345678910111213141516171819202122232425262728293031,
- "valid": true
- }
- ]
- },
- {
- "description": "number",
- "schema": {"type": "number"},
- "tests": [
- {
- "description": "a bignum is a number",
- "data": 98249283749234923498293171823948729348710298301928331,
- "valid": true
- }
- ]
- },
- {
- "description": "integer",
- "schema": {"type": "integer"},
- "tests": [
- {
- "description": "a negative bignum is an integer",
- "data": -12345678910111213141516171819202122232425262728293031,
- "valid": true
- }
- ]
- },
- {
- "description": "number",
- "schema": {"type": "number"},
- "tests": [
- {
- "description": "a negative bignum is a number",
- "data": -98249283749234923498293171823948729348710298301928331,
- "valid": true
- }
- ]
- },
- {
- "description": "string",
- "schema": {"type": "string"},
- "tests": [
- {
- "description": "a bignum is not a string",
- "data": 98249283749234923498293171823948729348710298301928331,
- "valid": false
- }
- ]
- },
- {
- "description": "integer comparison",
- "schema": {"maximum": 18446744073709551615},
- "tests": [
- {
- "description": "comparison works for high numbers",
- "data": 18446744073709551600,
- "valid": true
- }
- ]
- },
- {
- "description": "float comparison with high precision",
- "schema": {
- "maximum": 972783798187987123879878123.18878137,
- "exclusiveMaximum": true
- },
- "tests": [
- {
- "description": "comparison works for high numbers",
- "data": 972783798187987123879878123.188781371,
- "valid": false
- }
- ]
- },
- {
- "description": "integer comparison",
- "schema": {"minimum": -18446744073709551615},
- "tests": [
- {
- "description": "comparison works for very negative numbers",
- "data": -18446744073709551600,
- "valid": true
- }
- ]
- },
- {
- "description": "float comparison with high precision on negative numbers",
- "schema": {
- "minimum": -972783798187987123879878123.18878137,
- "exclusiveMinimum": true
- },
- "tests": [
- {
- "description": "comparison works for very negative numbers",
- "data": -972783798187987123879878123.188781371,
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft6/optional/format/date-time.json b/json/tests/draft6/optional/format/date-time.json
deleted file mode 100644
index f4f9933..0000000
--- a/json/tests/draft6/optional/format/date-time.json
+++ /dev/null
@@ -1,133 +0,0 @@
-[
- {
- "description": "validation of date-time strings",
- "schema": { "format": "date-time" },
- "tests": [
- {
- "description": "all string formats ignore integers",
- "data": 12,
- "valid": true
- },
- {
- "description": "all string formats ignore floats",
- "data": 13.7,
- "valid": true
- },
- {
- "description": "all string formats ignore objects",
- "data": {},
- "valid": true
- },
- {
- "description": "all string formats ignore arrays",
- "data": [],
- "valid": true
- },
- {
- "description": "all string formats ignore booleans",
- "data": false,
- "valid": true
- },
- {
- "description": "all string formats ignore nulls",
- "data": null,
- "valid": true
- },
- {
- "description": "a valid date-time string",
- "data": "1963-06-19T08:30:06.283185Z",
- "valid": true
- },
- {
- "description": "a valid date-time string without second fraction",
- "data": "1963-06-19T08:30:06Z",
- "valid": true
- },
- {
- "description": "a valid date-time string with plus offset",
- "data": "1937-01-01T12:00:27.87+00:20",
- "valid": true
- },
- {
- "description": "a valid date-time string with minus offset",
- "data": "1990-12-31T15:59:50.123-08:00",
- "valid": true
- },
- {
- "description": "a valid date-time with a leap second, UTC",
- "data": "1998-12-31T23:59:60Z",
- "valid": true
- },
- {
- "description": "a valid date-time with a leap second, with minus offset",
- "data": "1998-12-31T15:59:60.123-08:00",
- "valid": true
- },
- {
- "description": "an invalid date-time past leap second, UTC",
- "data": "1998-12-31T23:59:61Z",
- "valid": false
- },
- {
- "description": "an invalid date-time with leap second on a wrong minute, UTC",
- "data": "1998-12-31T23:58:60Z",
- "valid": false
- },
- {
- "description": "an invalid date-time with leap second on a wrong hour, UTC",
- "data": "1998-12-31T22:59:60Z",
- "valid": false
- },
- {
- "description": "an invalid day in date-time string",
- "data": "1990-02-31T15:59:59.123-08:00",
- "valid": false
- },
- {
- "description": "an invalid offset in date-time string",
- "data": "1990-12-31T15:59:59-24:00",
- "valid": false
- },
- {
- "description": "an invalid closing Z after time-zone offset",
- "data": "1963-06-19T08:30:06.28123+01:00Z",
- "valid": false
- },
- {
- "description": "an invalid date-time string",
- "data": "06/19/1963 08:30:06 PST",
- "valid": false
- },
- {
- "description": "case-insensitive T and Z",
- "data": "1963-06-19t08:30:06.283185z",
- "valid": true
- },
- {
- "description": "only RFC3339 not all of ISO 8601 are valid",
- "data": "2013-350T01:01:01",
- "valid": false
- },
- {
- "description": "invalid non-padded month dates",
- "data": "1963-6-19T08:30:06.283185Z",
- "valid": false
- },
- {
- "description": "invalid non-padded day dates",
- "data": "1963-06-1T08:30:06.283185Z",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected in the date portion",
- "data": "1963-06-1৪T00:00:00Z",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected in the time portion",
- "data": "1963-06-11T0৪:00:00Z",
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft6/optional/format/ipv4.json b/json/tests/draft6/optional/format/ipv4.json
deleted file mode 100644
index 6b166c7..0000000
--- a/json/tests/draft6/optional/format/ipv4.json
+++ /dev/null
@@ -1,84 +0,0 @@
-[
- {
- "description": "validation of IP addresses",
- "schema": { "format": "ipv4" },
- "tests": [
- {
- "description": "all string formats ignore integers",
- "data": 12,
- "valid": true
- },
- {
- "description": "all string formats ignore floats",
- "data": 13.7,
- "valid": true
- },
- {
- "description": "all string formats ignore objects",
- "data": {},
- "valid": true
- },
- {
- "description": "all string formats ignore arrays",
- "data": [],
- "valid": true
- },
- {
- "description": "all string formats ignore booleans",
- "data": false,
- "valid": true
- },
- {
- "description": "all string formats ignore nulls",
- "data": null,
- "valid": true
- },
- {
- "description": "a valid IP address",
- "data": "192.168.0.1",
- "valid": true
- },
- {
- "description": "an IP address with too many components",
- "data": "127.0.0.0.1",
- "valid": false
- },
- {
- "description": "an IP address with out-of-range values",
- "data": "256.256.256.256",
- "valid": false
- },
- {
- "description": "an IP address without 4 components",
- "data": "127.0",
- "valid": false
- },
- {
- "description": "an IP address as an integer",
- "data": "0x7f000001",
- "valid": false
- },
- {
- "description": "an IP address as an integer (decimal)",
- "data": "2130706433",
- "valid": false
- },
- {
- "description": "leading zeroes should be rejected, as they are treated as octals",
- "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
- "data": "087.10.0.1",
- "valid": false
- },
- {
- "description": "value without leading zero is valid",
- "data": "87.10.0.1",
- "valid": true
- },
- {
- "description": "non-ascii digits should be rejected",
- "data": "1২7.0.0.1",
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft6/optional/format/ipv6.json b/json/tests/draft6/optional/format/ipv6.json
deleted file mode 100644
index 6379927..0000000
--- a/json/tests/draft6/optional/format/ipv6.json
+++ /dev/null
@@ -1,208 +0,0 @@
-[
- {
- "description": "validation of IPv6 addresses",
- "schema": { "format": "ipv6" },
- "tests": [
- {
- "description": "all string formats ignore integers",
- "data": 12,
- "valid": true
- },
- {
- "description": "all string formats ignore floats",
- "data": 13.7,
- "valid": true
- },
- {
- "description": "all string formats ignore objects",
- "data": {},
- "valid": true
- },
- {
- "description": "all string formats ignore arrays",
- "data": [],
- "valid": true
- },
- {
- "description": "all string formats ignore booleans",
- "data": false,
- "valid": true
- },
- {
- "description": "all string formats ignore nulls",
- "data": null,
- "valid": true
- },
- {
- "description": "a valid IPv6 address",
- "data": "::1",
- "valid": true
- },
- {
- "description": "an IPv6 address with out-of-range values",
- "data": "12345::",
- "valid": false
- },
- {
- "description": "trailing 4 hex symbols is valid",
- "data": "::abef",
- "valid": true
- },
- {
- "description": "trailing 5 hex symbols is invalid",
- "data": "::abcef",
- "valid": false
- },
- {
- "description": "an IPv6 address with too many components",
- "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1",
- "valid": false
- },
- {
- "description": "an IPv6 address containing illegal characters",
- "data": "::laptop",
- "valid": false
- },
- {
- "description": "no digits is valid",
- "data": "::",
- "valid": true
- },
- {
- "description": "leading colons is valid",
- "data": "::42:ff:1",
- "valid": true
- },
- {
- "description": "trailing colons is valid",
- "data": "d6::",
- "valid": true
- },
- {
- "description": "missing leading octet is invalid",
- "data": ":2:3:4:5:6:7:8",
- "valid": false
- },
- {
- "description": "missing trailing octet is invalid",
- "data": "1:2:3:4:5:6:7:",
- "valid": false
- },
- {
- "description": "missing leading octet with omitted octets later",
- "data": ":2:3:4::8",
- "valid": false
- },
- {
- "description": "single set of double colons in the middle is valid",
- "data": "1:d6::42",
- "valid": true
- },
- {
- "description": "two sets of double colons is invalid",
- "data": "1::d6::42",
- "valid": false
- },
- {
- "description": "mixed format with the ipv4 section as decimal octets",
- "data": "1::d6:192.168.0.1",
- "valid": true
- },
- {
- "description": "mixed format with double colons between the sections",
- "data": "1:2::192.168.0.1",
- "valid": true
- },
- {
- "description": "mixed format with ipv4 section with octet out of range",
- "data": "1::2:192.168.256.1",
- "valid": false
- },
- {
- "description": "mixed format with ipv4 section with a hex octet",
- "data": "1::2:192.168.ff.1",
- "valid": false
- },
- {
- "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)",
- "data": "::ffff:192.168.0.1",
- "valid": true
- },
- {
- "description": "triple colons is invalid",
- "data": "1:2:3:4:5:::8",
- "valid": false
- },
- {
- "description": "8 octets",
- "data": "1:2:3:4:5:6:7:8",
- "valid": true
- },
- {
- "description": "insufficient octets without double colons",
- "data": "1:2:3:4:5:6:7",
- "valid": false
- },
- {
- "description": "no colons is invalid",
- "data": "1",
- "valid": false
- },
- {
- "description": "ipv4 is not ipv6",
- "data": "127.0.0.1",
- "valid": false
- },
- {
- "description": "ipv4 segment must have 4 octets",
- "data": "1:2:3:4:1.2.3",
- "valid": false
- },
- {
- "description": "leading whitespace is invalid",
- "data": " ::1",
- "valid": false
- },
- {
- "description": "trailing whitespace is invalid",
- "data": "::1 ",
- "valid": false
- },
- {
- "description": "netmask is not a part of ipv6 address",
- "data": "fe80::/64",
- "valid": false
- },
- {
- "description": "zone id is not a part of ipv6 address",
- "data": "fe80::a%eth1",
- "valid": false
- },
- {
- "description": "a long valid ipv6",
- "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
- "valid": true
- },
- {
- "description": "a long invalid ipv6, below length limit, first",
- "data": "100:100:100:100:100:100:255.255.255.255.255",
- "valid": false
- },
- {
- "description": "a long invalid ipv6, below length limit, second",
- "data": "100:100:100:100:100:100:100:255.255.255.255",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected",
- "data": "1:2:3:4:5:6:7:৪",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected in the ipv4 portion also",
- "data": "1:2::192.16৪.0.1",
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft7/anyOf.json b/json/tests/draft7/anyOf.json
deleted file mode 100644
index b720afa..0000000
--- a/json/tests/draft7/anyOf.json
+++ /dev/null
@@ -1,215 +0,0 @@
-[
- {
- "description": "anyOf",
- "schema": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "minimum": 2
- }
- ]
- },
- "tests": [
- {
- "description": "first anyOf valid",
- "data": 1,
- "valid": true
- },
- {
- "description": "second anyOf valid",
- "data": 2.5,
- "valid": true
- },
- {
- "description": "both anyOf valid",
- "data": 3,
- "valid": true
- },
- {
- "description": "neither anyOf valid",
- "data": 1.5,
- "valid": false
- }
- ]
- },
- {
- "description": "anyOf with base schema",
- "schema": {
- "type": "string",
- "anyOf" : [
- {
- "maxLength": 2
- },
- {
- "minLength": 4
- }
- ]
- },
- "tests": [
- {
- "description": "mismatch base schema",
- "data": 3,
- "valid": false
- },
- {
- "description": "one anyOf valid",
- "data": "foobar",
- "valid": true
- },
- {
- "description": "both anyOf invalid",
- "data": "foo",
- "valid": false
- }
- ]
- },
- {
- "description": "anyOf with boolean schemas, all true",
- "schema": {"anyOf": [true, true]},
- "tests": [
- {
- "description": "any value is valid",
- "data": "foo",
- "valid": true
- }
- ]
- },
- {
- "description": "anyOf with boolean schemas, some true",
- "schema": {"anyOf": [true, false]},
- "tests": [
- {
- "description": "any value is valid",
- "data": "foo",
- "valid": true
- }
- ]
- },
- {
- "description": "anyOf with boolean schemas, all false",
- "schema": {"anyOf": [false, false]},
- "tests": [
- {
- "description": "any value is invalid",
- "data": "foo",
- "valid": false
- }
- ]
- },
- {
- "description": "anyOf complex types",
- "schema": {
- "anyOf": [
- {
- "properties": {
- "bar": {"type": "integer"}
- },
- "required": ["bar"]
- },
- {
- "properties": {
- "foo": {"type": "string"}
- },
- "required": ["foo"]
- }
- ]
- },
- "tests": [
- {
- "description": "first anyOf valid (complex)",
- "data": {"bar": 2},
- "valid": true
- },
- {
- "description": "second anyOf valid (complex)",
- "data": {"foo": "baz"},
- "valid": true
- },
- {
- "description": "both anyOf valid (complex)",
- "data": {"foo": "baz", "bar": 2},
- "valid": true
- },
- {
- "description": "neither anyOf valid (complex)",
- "data": {"foo": 2, "bar": "quux"},
- "valid": false
- }
- ]
- },
- {
- "description": "anyOf with one empty schema",
- "schema": {
- "anyOf": [
- { "type": "number" },
- {}
- ]
- },
- "tests": [
- {
- "description": "string is valid",
- "data": "foo",
- "valid": true
- },
- {
- "description": "number is valid",
- "data": 123,
- "valid": true
- }
- ]
- },
- {
- "description": "nested anyOf, to check validation semantics",
- "schema": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- }
- ]
- }
- ]
- },
- "tests": [
- {
- "description": "null is valid",
- "data": null,
- "valid": true
- },
- {
- "description": "anything non-null is invalid",
- "data": 123,
- "valid": false
- }
- ]
- },
- {
- "description": "nested anyOf, to check validation semantics",
- "schema": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- }
- ]
- }
- ]
- },
- "tests": [
- {
- "description": "null is valid",
- "data": null,
- "valid": true
- },
- {
- "description": "anything non-null is invalid",
- "data": 123,
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft7/optional/bignum.json b/json/tests/draft7/optional/bignum.json
deleted file mode 100644
index 3f49226..0000000
--- a/json/tests/draft7/optional/bignum.json
+++ /dev/null
@@ -1,93 +0,0 @@
-[
- {
- "description": "integer",
- "schema": { "type": "integer" },
- "tests": [
- {
- "description": "a bignum is an integer",
- "data": 12345678910111213141516171819202122232425262728293031,
- "valid": true
- },
- {
- "description": "a negative bignum is an integer",
- "data": -12345678910111213141516171819202122232425262728293031,
- "valid": true
- }
- ]
- },
- {
- "description": "number",
- "schema": { "type": "number" },
- "tests": [
- {
- "description": "a bignum is a number",
- "data": 98249283749234923498293171823948729348710298301928331,
- "valid": true
- },
- {
- "description": "a negative bignum is a number",
- "data": -98249283749234923498293171823948729348710298301928331,
- "valid": true
- }
- ]
- },
- {
- "description": "string",
- "schema": { "type": "string" },
- "tests": [
- {
- "description": "a bignum is not a string",
- "data": 98249283749234923498293171823948729348710298301928331,
- "valid": false
- }
- ]
- },
- {
- "description": "integer comparison",
- "schema": { "maximum": 18446744073709551615 },
- "tests": [
- {
- "description": "comparison works for high numbers",
- "data": 18446744073709551600,
- "valid": true
- }
- ]
- },
- {
- "description": "float comparison with high precision",
- "schema": {
- "exclusiveMaximum": 972783798187987123879878123.18878137
- },
- "tests": [
- {
- "description": "comparison works for high numbers",
- "data": 972783798187987123879878123.188781371,
- "valid": false
- }
- ]
- },
- {
- "description": "integer comparison",
- "schema": { "minimum": -18446744073709551615 },
- "tests": [
- {
- "description": "comparison works for very negative numbers",
- "data": -18446744073709551600,
- "valid": true
- }
- ]
- },
- {
- "description": "float comparison with high precision on negative numbers",
- "schema": {
- "exclusiveMinimum": -972783798187987123879878123.18878137
- },
- "tests": [
- {
- "description": "comparison works for very negative numbers",
- "data": -972783798187987123879878123.188781371,
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft7/optional/format/date-time.json b/json/tests/draft7/optional/format/date-time.json
deleted file mode 100644
index f4f9933..0000000
--- a/json/tests/draft7/optional/format/date-time.json
+++ /dev/null
@@ -1,133 +0,0 @@
-[
- {
- "description": "validation of date-time strings",
- "schema": { "format": "date-time" },
- "tests": [
- {
- "description": "all string formats ignore integers",
- "data": 12,
- "valid": true
- },
- {
- "description": "all string formats ignore floats",
- "data": 13.7,
- "valid": true
- },
- {
- "description": "all string formats ignore objects",
- "data": {},
- "valid": true
- },
- {
- "description": "all string formats ignore arrays",
- "data": [],
- "valid": true
- },
- {
- "description": "all string formats ignore booleans",
- "data": false,
- "valid": true
- },
- {
- "description": "all string formats ignore nulls",
- "data": null,
- "valid": true
- },
- {
- "description": "a valid date-time string",
- "data": "1963-06-19T08:30:06.283185Z",
- "valid": true
- },
- {
- "description": "a valid date-time string without second fraction",
- "data": "1963-06-19T08:30:06Z",
- "valid": true
- },
- {
- "description": "a valid date-time string with plus offset",
- "data": "1937-01-01T12:00:27.87+00:20",
- "valid": true
- },
- {
- "description": "a valid date-time string with minus offset",
- "data": "1990-12-31T15:59:50.123-08:00",
- "valid": true
- },
- {
- "description": "a valid date-time with a leap second, UTC",
- "data": "1998-12-31T23:59:60Z",
- "valid": true
- },
- {
- "description": "a valid date-time with a leap second, with minus offset",
- "data": "1998-12-31T15:59:60.123-08:00",
- "valid": true
- },
- {
- "description": "an invalid date-time past leap second, UTC",
- "data": "1998-12-31T23:59:61Z",
- "valid": false
- },
- {
- "description": "an invalid date-time with leap second on a wrong minute, UTC",
- "data": "1998-12-31T23:58:60Z",
- "valid": false
- },
- {
- "description": "an invalid date-time with leap second on a wrong hour, UTC",
- "data": "1998-12-31T22:59:60Z",
- "valid": false
- },
- {
- "description": "an invalid day in date-time string",
- "data": "1990-02-31T15:59:59.123-08:00",
- "valid": false
- },
- {
- "description": "an invalid offset in date-time string",
- "data": "1990-12-31T15:59:59-24:00",
- "valid": false
- },
- {
- "description": "an invalid closing Z after time-zone offset",
- "data": "1963-06-19T08:30:06.28123+01:00Z",
- "valid": false
- },
- {
- "description": "an invalid date-time string",
- "data": "06/19/1963 08:30:06 PST",
- "valid": false
- },
- {
- "description": "case-insensitive T and Z",
- "data": "1963-06-19t08:30:06.283185z",
- "valid": true
- },
- {
- "description": "only RFC3339 not all of ISO 8601 are valid",
- "data": "2013-350T01:01:01",
- "valid": false
- },
- {
- "description": "invalid non-padded month dates",
- "data": "1963-6-19T08:30:06.283185Z",
- "valid": false
- },
- {
- "description": "invalid non-padded day dates",
- "data": "1963-06-1T08:30:06.283185Z",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected in the date portion",
- "data": "1963-06-1৪T00:00:00Z",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected in the time portion",
- "data": "1963-06-11T0৪:00:00Z",
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft7/optional/format/ipv4.json b/json/tests/draft7/optional/format/ipv4.json
deleted file mode 100644
index 6b166c7..0000000
--- a/json/tests/draft7/optional/format/ipv4.json
+++ /dev/null
@@ -1,84 +0,0 @@
-[
- {
- "description": "validation of IP addresses",
- "schema": { "format": "ipv4" },
- "tests": [
- {
- "description": "all string formats ignore integers",
- "data": 12,
- "valid": true
- },
- {
- "description": "all string formats ignore floats",
- "data": 13.7,
- "valid": true
- },
- {
- "description": "all string formats ignore objects",
- "data": {},
- "valid": true
- },
- {
- "description": "all string formats ignore arrays",
- "data": [],
- "valid": true
- },
- {
- "description": "all string formats ignore booleans",
- "data": false,
- "valid": true
- },
- {
- "description": "all string formats ignore nulls",
- "data": null,
- "valid": true
- },
- {
- "description": "a valid IP address",
- "data": "192.168.0.1",
- "valid": true
- },
- {
- "description": "an IP address with too many components",
- "data": "127.0.0.0.1",
- "valid": false
- },
- {
- "description": "an IP address with out-of-range values",
- "data": "256.256.256.256",
- "valid": false
- },
- {
- "description": "an IP address without 4 components",
- "data": "127.0",
- "valid": false
- },
- {
- "description": "an IP address as an integer",
- "data": "0x7f000001",
- "valid": false
- },
- {
- "description": "an IP address as an integer (decimal)",
- "data": "2130706433",
- "valid": false
- },
- {
- "description": "leading zeroes should be rejected, as they are treated as octals",
- "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
- "data": "087.10.0.1",
- "valid": false
- },
- {
- "description": "value without leading zero is valid",
- "data": "87.10.0.1",
- "valid": true
- },
- {
- "description": "non-ascii digits should be rejected",
- "data": "1২7.0.0.1",
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tests/draft7/optional/format/ipv6.json b/json/tests/draft7/optional/format/ipv6.json
deleted file mode 100644
index 6379927..0000000
--- a/json/tests/draft7/optional/format/ipv6.json
+++ /dev/null
@@ -1,208 +0,0 @@
-[
- {
- "description": "validation of IPv6 addresses",
- "schema": { "format": "ipv6" },
- "tests": [
- {
- "description": "all string formats ignore integers",
- "data": 12,
- "valid": true
- },
- {
- "description": "all string formats ignore floats",
- "data": 13.7,
- "valid": true
- },
- {
- "description": "all string formats ignore objects",
- "data": {},
- "valid": true
- },
- {
- "description": "all string formats ignore arrays",
- "data": [],
- "valid": true
- },
- {
- "description": "all string formats ignore booleans",
- "data": false,
- "valid": true
- },
- {
- "description": "all string formats ignore nulls",
- "data": null,
- "valid": true
- },
- {
- "description": "a valid IPv6 address",
- "data": "::1",
- "valid": true
- },
- {
- "description": "an IPv6 address with out-of-range values",
- "data": "12345::",
- "valid": false
- },
- {
- "description": "trailing 4 hex symbols is valid",
- "data": "::abef",
- "valid": true
- },
- {
- "description": "trailing 5 hex symbols is invalid",
- "data": "::abcef",
- "valid": false
- },
- {
- "description": "an IPv6 address with too many components",
- "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1",
- "valid": false
- },
- {
- "description": "an IPv6 address containing illegal characters",
- "data": "::laptop",
- "valid": false
- },
- {
- "description": "no digits is valid",
- "data": "::",
- "valid": true
- },
- {
- "description": "leading colons is valid",
- "data": "::42:ff:1",
- "valid": true
- },
- {
- "description": "trailing colons is valid",
- "data": "d6::",
- "valid": true
- },
- {
- "description": "missing leading octet is invalid",
- "data": ":2:3:4:5:6:7:8",
- "valid": false
- },
- {
- "description": "missing trailing octet is invalid",
- "data": "1:2:3:4:5:6:7:",
- "valid": false
- },
- {
- "description": "missing leading octet with omitted octets later",
- "data": ":2:3:4::8",
- "valid": false
- },
- {
- "description": "single set of double colons in the middle is valid",
- "data": "1:d6::42",
- "valid": true
- },
- {
- "description": "two sets of double colons is invalid",
- "data": "1::d6::42",
- "valid": false
- },
- {
- "description": "mixed format with the ipv4 section as decimal octets",
- "data": "1::d6:192.168.0.1",
- "valid": true
- },
- {
- "description": "mixed format with double colons between the sections",
- "data": "1:2::192.168.0.1",
- "valid": true
- },
- {
- "description": "mixed format with ipv4 section with octet out of range",
- "data": "1::2:192.168.256.1",
- "valid": false
- },
- {
- "description": "mixed format with ipv4 section with a hex octet",
- "data": "1::2:192.168.ff.1",
- "valid": false
- },
- {
- "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)",
- "data": "::ffff:192.168.0.1",
- "valid": true
- },
- {
- "description": "triple colons is invalid",
- "data": "1:2:3:4:5:::8",
- "valid": false
- },
- {
- "description": "8 octets",
- "data": "1:2:3:4:5:6:7:8",
- "valid": true
- },
- {
- "description": "insufficient octets without double colons",
- "data": "1:2:3:4:5:6:7",
- "valid": false
- },
- {
- "description": "no colons is invalid",
- "data": "1",
- "valid": false
- },
- {
- "description": "ipv4 is not ipv6",
- "data": "127.0.0.1",
- "valid": false
- },
- {
- "description": "ipv4 segment must have 4 octets",
- "data": "1:2:3:4:1.2.3",
- "valid": false
- },
- {
- "description": "leading whitespace is invalid",
- "data": " ::1",
- "valid": false
- },
- {
- "description": "trailing whitespace is invalid",
- "data": "::1 ",
- "valid": false
- },
- {
- "description": "netmask is not a part of ipv6 address",
- "data": "fe80::/64",
- "valid": false
- },
- {
- "description": "zone id is not a part of ipv6 address",
- "data": "fe80::a%eth1",
- "valid": false
- },
- {
- "description": "a long valid ipv6",
- "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
- "valid": true
- },
- {
- "description": "a long invalid ipv6, below length limit, first",
- "data": "100:100:100:100:100:100:255.255.255.255.255",
- "valid": false
- },
- {
- "description": "a long invalid ipv6, below length limit, second",
- "data": "100:100:100:100:100:100:100:255.255.255.255",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected",
- "data": "1:2:3:4:5:6:7:৪",
- "valid": false
- },
- {
- "description": "non-ascii digits should be rejected in the ipv4 portion also",
- "data": "1:2::192.16৪.0.1",
- "valid": false
- }
- ]
- }
-]
diff --git a/json/tox.ini b/json/tox.ini
deleted file mode 100644
index ec180a9..0000000
--- a/json/tox.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[tox]
-minversion = 1.6
-envlist = sanity
-skipsdist = True
-
-[testenv:sanity]
-# used just for validating the structure of the test case files themselves
-deps = jsonschema==4.6.1
-commands = {envpython} bin/jsonschema_suite check
diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py
deleted file mode 100644
index 75f2946..0000000
--- a/jsonschema/__init__.py
+++ /dev/null
@@ -1,58 +0,0 @@
-"""
-An implementation of JSON Schema for Python
-
-The main functionality is provided by the validator classes for each of the
-supported JSON Schema versions.
-
-Most commonly, `validate` is the quickest way to simply validate a given
-instance under a schema, and will create a validator for you.
-"""
-import warnings
-
-from jsonschema._format import (
- FormatChecker,
- draft3_format_checker,
- draft4_format_checker,
- draft6_format_checker,
- draft7_format_checker,
- draft201909_format_checker,
- draft202012_format_checker,
-)
-from jsonschema._types import TypeChecker
-from jsonschema.exceptions import (
- ErrorTree,
- FormatError,
- RefResolutionError,
- SchemaError,
- ValidationError,
-)
-from jsonschema.protocols import Validator
-from jsonschema.validators import (
- Draft3Validator,
- Draft4Validator,
- Draft6Validator,
- Draft7Validator,
- Draft201909Validator,
- Draft202012Validator,
- RefResolver,
- validate,
-)
-
-
-def __getattr__(name):
- if name == "__version__":
- warnings.warn(
- "Accessing jsonschema.__version__ is deprecated and will be "
- "removed in a future release. Use importlib.metadata directly "
- "to query for jsonschema's version.",
- DeprecationWarning,
- stacklevel=2,
- )
-
- try:
- from importlib import metadata
- except ImportError:
- import importlib_metadata as metadata
-
- return metadata.version("jsonschema")
- raise AttributeError(f"module {__name__} has no attribute {name}")
diff --git a/jsonschema/__main__.py b/jsonschema/__main__.py
deleted file mode 100644
index fdc21e2..0000000
--- a/jsonschema/__main__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from jsonschema.cli import main
-
-main()
diff --git a/jsonschema/_format.py b/jsonschema/_format.py
deleted file mode 100644
index da4bb79..0000000
--- a/jsonschema/_format.py
+++ /dev/null
@@ -1,498 +0,0 @@
-from __future__ import annotations
-
-from contextlib import suppress
-from uuid import UUID
-import datetime
-import ipaddress
-import re
-import typing
-
-from jsonschema.exceptions import FormatError
-
-_FormatCheckCallable = typing.Callable[[object], bool]
-_F = typing.TypeVar("_F", bound=_FormatCheckCallable)
-_RaisesType = typing.Union[
- typing.Type[Exception], typing.Tuple[typing.Type[Exception], ...],
-]
-
-
-class FormatChecker(object):
- """
- A ``format`` property checker.
-
- JSON Schema does not mandate that the ``format`` property actually do any
- validation. If validation is desired however, instances of this class can
- be hooked into validators to enable format validation.
-
- `FormatChecker` objects always return ``True`` when asked about
- formats that they do not know how to validate.
-
- To check a custom format using a function that takes an instance and
- returns a ``bool``, use the `FormatChecker.checks` or
- `FormatChecker.cls_checks` decorators.
-
- Arguments:
-
- formats (~collections.abc.Iterable):
-
- The known formats to validate. This argument can be used to
- limit which formats will be used during validation.
- """
-
- checkers: dict[
- str,
- tuple[_FormatCheckCallable, _RaisesType],
- ] = {}
-
- def __init__(self, formats: typing.Iterable[str] | None = None):
- if formats is None:
- self.checkers = self.checkers.copy()
- else:
- self.checkers = dict((k, self.checkers[k]) for k in formats)
-
- def __repr__(self):
- return "<FormatChecker checkers={}>".format(sorted(self.checkers))
-
- def checks(
- self, format: str, raises: _RaisesType = (),
- ) -> typing.Callable[[_F], _F]:
- """
- Register a decorated function as validating a new format.
-
- Arguments:
-
- format (str):
-
- The format that the decorated function will check.
-
- raises (Exception):
-
- The exception(s) raised by the decorated function when an
- invalid instance is found.
-
- The exception object will be accessible as the
- `jsonschema.exceptions.ValidationError.cause` attribute of the
- resulting validation error.
- """
-
- def _checks(func: _F) -> _F:
- self.checkers[format] = (func, raises)
- return func
-
- return _checks
-
- @classmethod
- def cls_checks(
- cls, format: str, raises: _RaisesType = (),
- ) -> typing.Callable[[_F], _F]:
- def _checks(func: _F) -> _F:
- cls.checkers[format] = (func, raises)
- return func
-
- return _checks
-
- def check(self, instance: object, format: str) -> None:
- """
- Check whether the instance conforms to the given format.
-
- Arguments:
-
- instance (*any primitive type*, i.e. str, number, bool):
-
- The instance to check
-
- format (str):
-
- The format that instance should conform to
-
-
- Raises:
-
- FormatError: if the instance does not conform to ``format``
- """
-
- if format not in self.checkers:
- return
-
- func, raises = self.checkers[format]
- result, cause = None, None
- try:
- result = func(instance)
- except raises as e:
- cause = e
- if not result:
- raise FormatError(f"{instance!r} is not a {format!r}", cause=cause)
-
- def conforms(self, instance: object, format: str) -> bool:
- """
- Check whether the instance conforms to the given format.
-
- Arguments:
-
- instance (*any primitive type*, i.e. str, number, bool):
-
- The instance to check
-
- format (str):
-
- The format that instance should conform to
-
- Returns:
-
- bool: whether it conformed
- """
-
- try:
- self.check(instance, format)
- except FormatError:
- return False
- else:
- return True
-
-
-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[str, FormatChecker] = dict(
- draft3=draft3_format_checker,
- draft4=draft4_format_checker,
- draft6=draft6_format_checker,
- draft7=draft7_format_checker,
- draft201909=draft201909_format_checker,
- draft202012=draft202012_format_checker,
-)
-
-
-def _checks_drafts(
- name=None,
- draft3=None,
- draft4=None,
- draft6=None,
- draft7=None,
- draft201909=None,
- draft202012=None,
- raises=(),
-) -> typing.Callable[[_F], _F]:
- draft3 = draft3 or name
- draft4 = draft4 or name
- draft6 = draft6 or name
- draft7 = draft7 or name
- draft201909 = draft201909 or name
- draft202012 = draft202012 or name
-
- def wrap(func: _F) -> _F:
- if draft3:
- func = _draft_checkers["draft3"].checks(draft3, raises)(func)
- if draft4:
- func = _draft_checkers["draft4"].checks(draft4, raises)(func)
- if draft6:
- 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,
- )
-
- # Oy. This is bad global state, but relied upon for now, until
- # deprecation. See #519 and test_format_checkers_come_with_defaults
- FormatChecker.cls_checks(
- draft202012 or draft201909 or draft7 or draft6 or draft4 or draft3,
- raises,
- )(func)
- return func
-
- return wrap
-
-
-@_checks_drafts(name="idn-email")
-@_checks_drafts(name="email")
-def is_email(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return "@" in instance
-
-
-@_checks_drafts(
- draft3="ip-address",
- draft4="ipv4",
- draft6="ipv4",
- draft7="ipv4",
- draft201909="ipv4",
- draft202012="ipv4",
- raises=ipaddress.AddressValueError,
-)
-def is_ipv4(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return bool(ipaddress.IPv4Address(instance))
-
-
-@_checks_drafts(name="ipv6", raises=ipaddress.AddressValueError)
-def is_ipv6(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- address = ipaddress.IPv6Address(instance)
- return not getattr(address, "scope_id", "")
-
-
-with suppress(ImportError):
- from fqdn import FQDN
-
- @_checks_drafts(
- draft3="host-name",
- draft4="hostname",
- draft6="hostname",
- draft7="hostname",
- draft201909="hostname",
- draft202012="hostname",
- )
- def is_host_name(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return FQDN(instance).is_valid
-
-
-with suppress(ImportError):
- # The built-in `idna` codec only implements RFC 3890, so we go elsewhere.
- import idna
-
- @_checks_drafts(
- draft7="idn-hostname",
- draft201909="idn-hostname",
- draft202012="idn-hostname",
- raises=(idna.IDNAError, UnicodeError),
- )
- def is_idn_host_name(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- idna.encode(instance)
- return True
-
-
-try:
- import rfc3987
-except ImportError:
- with suppress(ImportError):
- from rfc3986_validator import validate_rfc3986
-
- @_checks_drafts(name="uri")
- def is_uri(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return validate_rfc3986(instance, rule="URI")
-
- @_checks_drafts(
- draft6="uri-reference",
- draft7="uri-reference",
- draft201909="uri-reference",
- draft202012="uri-reference",
- raises=ValueError,
- )
- def is_uri_reference(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return validate_rfc3986(instance, rule="URI_reference")
-
-else:
-
- @_checks_drafts(
- draft7="iri",
- draft201909="iri",
- draft202012="iri",
- raises=ValueError,
- )
- def is_iri(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return rfc3987.parse(instance, rule="IRI")
-
- @_checks_drafts(
- draft7="iri-reference",
- draft201909="iri-reference",
- draft202012="iri-reference",
- raises=ValueError,
- )
- def is_iri_reference(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return rfc3987.parse(instance, rule="IRI_reference")
-
- @_checks_drafts(name="uri", raises=ValueError)
- def is_uri(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return rfc3987.parse(instance, rule="URI")
-
- @_checks_drafts(
- draft6="uri-reference",
- draft7="uri-reference",
- draft201909="uri-reference",
- draft202012="uri-reference",
- raises=ValueError,
- )
- def is_uri_reference(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return rfc3987.parse(instance, rule="URI_reference")
-
-
-with suppress(ImportError):
- from rfc3339_validator import validate_rfc3339
-
- @_checks_drafts(name="date-time")
- def is_datetime(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return validate_rfc3339(instance.upper())
-
- @_checks_drafts(
- draft7="time",
- draft201909="time",
- draft202012="time",
- )
- def is_time(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return is_datetime("1970-01-01T" + instance)
-
-
-@_checks_drafts(name="regex", raises=re.error)
-def is_regex(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return bool(re.compile(instance))
-
-
-@_checks_drafts(
- draft3="date",
- draft7="date",
- draft201909="date",
- draft202012="date",
- raises=ValueError,
-)
-def is_date(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return bool(instance.isascii() and datetime.date.fromisoformat(instance))
-
-
-@_checks_drafts(draft3="time", raises=ValueError)
-def is_draft3_time(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return bool(datetime.datetime.strptime(instance, "%H:%M:%S"))
-
-
-with suppress(ImportError):
- from webcolors import CSS21_NAMES_TO_HEX
- import webcolors
-
- def is_css_color_code(instance: object) -> bool:
- return webcolors.normalize_hex(instance)
-
- @_checks_drafts(draft3="color", raises=(ValueError, TypeError))
- def is_css21_color(instance: object) -> bool:
- if (
- not isinstance(instance, str)
- or instance.lower() in CSS21_NAMES_TO_HEX
- ):
- return True
- return is_css_color_code(instance)
-
-
-with suppress(ImportError):
- import jsonpointer
-
- @_checks_drafts(
- draft6="json-pointer",
- draft7="json-pointer",
- draft201909="json-pointer",
- draft202012="json-pointer",
- raises=jsonpointer.JsonPointerException,
- )
- def is_json_pointer(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return bool(jsonpointer.JsonPointer(instance))
-
- # TODO: I don't want to maintain this, so it
- # needs to go either into jsonpointer (pending
- # https://github.com/stefankoegl/python-json-pointer/issues/34) or
- # into a new external library.
- @_checks_drafts(
- draft7="relative-json-pointer",
- draft201909="relative-json-pointer",
- draft202012="relative-json-pointer",
- raises=jsonpointer.JsonPointerException,
- )
- def is_relative_json_pointer(instance: object) -> bool:
- # Definition taken from:
- # https://tools.ietf.org/html/draft-handrews-relative-json-pointer-01#section-3
- if not isinstance(instance, str):
- return True
- non_negative_integer, rest = [], ""
- for i, character in enumerate(instance):
- if character.isdigit():
- # digits with a leading "0" are not allowed
- if i > 0 and int(instance[i - 1]) == 0:
- return False
-
- non_negative_integer.append(character)
- continue
-
- if not non_negative_integer:
- return False
-
- rest = instance[i:]
- break
- return (rest == "#") or bool(jsonpointer.JsonPointer(rest))
-
-
-with suppress(ImportError):
- import uri_template
-
- @_checks_drafts(
- draft6="uri-template",
- draft7="uri-template",
- draft201909="uri-template",
- draft202012="uri-template",
- )
- def is_uri_template(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return uri_template.validate(instance)
-
-
-with suppress(ImportError):
- import isoduration
-
- @_checks_drafts(
- draft201909="duration",
- draft202012="duration",
- raises=isoduration.DurationParsingException,
- )
- def is_duration(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- return bool(isoduration.parse_duration(instance))
-
-
-@_checks_drafts(
- draft201909="uuid",
- draft202012="uuid",
- raises=ValueError,
-)
-def is_uuid(instance: object) -> bool:
- if not isinstance(instance, str):
- return True
- UUID(instance)
- return all(instance[position] == "-" for position in (8, 13, 18, 23))
diff --git a/jsonschema/_legacy_validators.py b/jsonschema/_legacy_validators.py
deleted file mode 100644
index 5be628f..0000000
--- a/jsonschema/_legacy_validators.py
+++ /dev/null
@@ -1,228 +0,0 @@
-from jsonschema import _utils
-from jsonschema.exceptions import ValidationError
-
-
-def ignore_ref_siblings(schema):
- """
- Ignore siblings of ``$ref`` if it is present.
-
- Otherwise, return all validators.
-
- Suitable for use with `create`'s ``applicable_validators`` argument.
- """
- ref = schema.get("$ref")
- if ref is not None:
- return [("$ref", ref)]
- else:
- return schema.items()
-
-
-def dependencies_draft3(validator, dependencies, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- for property, dependency in dependencies.items():
- if property not in instance:
- continue
-
- if validator.is_type(dependency, "object"):
- yield from validator.descend(
- instance, dependency, schema_path=property,
- )
- elif validator.is_type(dependency, "string"):
- if dependency not in instance:
- message = f"{dependency!r} is a dependency of {property!r}"
- yield ValidationError(message)
- else:
- for each in dependency:
- if each not in instance:
- message = f"{each!r} is a dependency of {property!r}"
- yield ValidationError(message)
-
-
-def dependencies_draft4_draft6_draft7(
- validator,
- dependencies,
- instance,
- schema,
-):
- """
- Support for the ``dependencies`` validator from pre-draft 2019-09.
-
- In later drafts, the validator was split into separate
- ``dependentRequired`` and ``dependentSchemas`` validators.
- """
- if not validator.is_type(instance, "object"):
- return
-
- for property, dependency in dependencies.items():
- if property not in instance:
- continue
-
- if validator.is_type(dependency, "array"):
- for each in dependency:
- if each not in instance:
- message = f"{each!r} is a dependency of {property!r}"
- yield ValidationError(message)
- else:
- yield from validator.descend(
- instance, dependency, schema_path=property,
- )
-
-
-def disallow_draft3(validator, disallow, instance, schema):
- for disallowed in _utils.ensure_list(disallow):
- if validator.evolve(schema={"type": [disallowed]}).is_valid(instance):
- message = f"{disallowed!r} is disallowed for {instance!r}"
- yield ValidationError(message)
-
-
-def extends_draft3(validator, extends, instance, schema):
- if validator.is_type(extends, "object"):
- yield from validator.descend(instance, extends)
- return
- for index, subschema in enumerate(extends):
- yield from validator.descend(instance, subschema, schema_path=index)
-
-
-def items_draft3_draft4(validator, items, instance, schema):
- if not validator.is_type(instance, "array"):
- return
-
- if validator.is_type(items, "object"):
- for index, item in enumerate(instance):
- yield from validator.descend(item, items, path=index)
- else:
- for (index, item), subschema in zip(enumerate(instance), items):
- yield from validator.descend(
- item, subschema, path=index, schema_path=index,
- )
-
-
-def items_draft6_draft7_draft201909(validator, items, instance, schema):
- if not validator.is_type(instance, "array"):
- return
-
- if validator.is_type(items, "array"):
- for (index, item), subschema in zip(enumerate(instance), items):
- yield from validator.descend(
- item, subschema, path=index, schema_path=index,
- )
- else:
- for index, item in enumerate(instance):
- yield from validator.descend(item, items, path=index)
-
-
-def minimum_draft3_draft4(validator, minimum, instance, schema):
- if not validator.is_type(instance, "number"):
- return
-
- if schema.get("exclusiveMinimum", False):
- failed = instance <= minimum
- cmp = "less than or equal to"
- else:
- failed = instance < minimum
- cmp = "less than"
-
- if failed:
- message = f"{instance!r} is {cmp} the minimum of {minimum!r}"
- yield ValidationError(message)
-
-
-def maximum_draft3_draft4(validator, maximum, instance, schema):
- if not validator.is_type(instance, "number"):
- return
-
- if schema.get("exclusiveMaximum", False):
- failed = instance >= maximum
- cmp = "greater than or equal to"
- else:
- failed = instance > maximum
- cmp = "greater than"
-
- if failed:
- message = f"{instance!r} is {cmp} the maximum of {maximum!r}"
- yield ValidationError(message)
-
-
-def properties_draft3(validator, properties, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- for property, subschema in properties.items():
- if property in instance:
- yield from validator.descend(
- instance[property],
- subschema,
- path=property,
- schema_path=property,
- )
- elif subschema.get("required", False):
- error = ValidationError(f"{property!r} is a required property")
- error._set(
- validator="required",
- validator_value=subschema["required"],
- instance=instance,
- schema=schema,
- )
- error.path.appendleft(property)
- error.schema_path.extend([property, "required"])
- yield error
-
-
-def type_draft3(validator, types, instance, schema):
- types = _utils.ensure_list(types)
-
- all_errors = []
- for index, type in enumerate(types):
- if validator.is_type(type, "object"):
- errors = list(validator.descend(instance, type, schema_path=index))
- if not errors:
- return
- all_errors.extend(errors)
- else:
- if validator.is_type(instance, type):
- return
- else:
- reprs = []
- for type in types:
- try:
- reprs.append(repr(type["name"]))
- except Exception:
- reprs.append(repr(type))
- yield ValidationError(
- f"{instance!r} is not of type {', '.join(reprs)}",
- context=all_errors,
- )
-
-
-def contains_draft6_draft7(validator, contains, instance, schema):
- if not validator.is_type(instance, "array"):
- return
-
- if not any(
- validator.evolve(schema=contains).is_valid(element)
- for element in instance
- ):
- yield ValidationError(
- f"None of {instance!r} are valid under the given schema",
- )
-
-
-def recursiveRef(validator, recursiveRef, instance, schema):
- lookup_url, target = validator.resolver.resolution_scope, validator.schema
-
- for each in reversed(validator.resolver._scopes_stack[1:]):
- lookup_url, next_target = validator.resolver.resolve(each)
- if next_target.get("$recursiveAnchor"):
- target = next_target
- else:
- break
-
- fragment = recursiveRef.lstrip("#")
- subschema = validator.resolver.resolve_fragment(target, fragment)
- # FIXME: This is gutted (and not calling .descend) because it can trigger
- # recursion errors, so there's a bug here. Re-enable the tests to
- # see it.
- subschema
- return []
diff --git a/jsonschema/_types.py b/jsonschema/_types.py
deleted file mode 100644
index 9d59eb3..0000000
--- a/jsonschema/_types.py
+++ /dev/null
@@ -1,217 +0,0 @@
-from __future__ import annotations
-
-import numbers
-import typing
-
-from pyrsistent import pmap
-import attr
-
-from jsonschema.exceptions import UndefinedTypeCheck
-
-
-# unfortunately, the type of pmap is generic, and if used as the attr.ib
-# converter, the generic type is presented to mypy, which then fails to match
-# the concrete type of a type checker mapping
-# this "do nothing" wrapper presents the correct information to mypy
-def _typed_pmap_converter(
- init_val: typing.Mapping[
- str,
- typing.Callable[["TypeChecker", typing.Any], bool],
- ],
-) -> typing.Mapping[str, typing.Callable[["TypeChecker", typing.Any], bool]]:
- return typing.cast(
- typing.Mapping[
- str,
- typing.Callable[["TypeChecker", typing.Any], bool],
- ],
- pmap(init_val),
- )
-
-
-def is_array(checker, instance):
- return isinstance(instance, list)
-
-
-def is_bool(checker, instance):
- return isinstance(instance, bool)
-
-
-def is_integer(checker, instance):
- # bool inherits from int, so ensure bools aren't reported as ints
- if isinstance(instance, bool):
- return False
- return isinstance(instance, int)
-
-
-def is_null(checker, instance):
- return instance is None
-
-
-def is_number(checker, instance):
- # bool inherits from int, so ensure bools aren't reported as ints
- if isinstance(instance, bool):
- return False
- return isinstance(instance, numbers.Number)
-
-
-def is_object(checker, instance):
- return isinstance(instance, dict)
-
-
-def is_string(checker, instance):
- return isinstance(instance, str)
-
-
-def is_any(checker, instance):
- return True
-
-
-@attr.s(frozen=True)
-class TypeChecker(object):
- """
- A ``type`` property checker.
-
- A `TypeChecker` performs type checking for a `Validator`. Type
- checks to perform are updated using `TypeChecker.redefine` or
- `TypeChecker.redefine_many` and removed via `TypeChecker.remove`.
- Each of these return a new `TypeChecker` object.
-
- Arguments:
-
- type_checkers (dict):
-
- The initial mapping of types to their checking functions.
- """
-
- _type_checkers: typing.Mapping[
- str, typing.Callable[["TypeChecker", typing.Any], bool],
- ] = attr.ib(
- default=pmap(),
- converter=_typed_pmap_converter,
- )
-
- def is_type(self, instance, type):
- """
- Check if the instance is of the appropriate type.
-
- Arguments:
-
- instance (object):
-
- The instance to check
-
- type (str):
-
- The name of the type that is expected.
-
- Returns:
-
- bool: Whether it conformed.
-
-
- Raises:
-
- `jsonschema.exceptions.UndefinedTypeCheck`:
- if type is unknown to this object.
- """
- try:
- fn = self._type_checkers[type]
- except KeyError:
- raise UndefinedTypeCheck(type) from None
-
- return fn(self, instance)
-
- def redefine(self, type, fn):
- """
- Produce a new checker with the given type redefined.
-
- Arguments:
-
- type (str):
-
- The name of the type to check.
-
- fn (collections.abc.Callable):
-
- A function taking exactly two parameters - the type
- checker calling the function and the instance to check.
- The function should return true if instance is of this
- type and false otherwise.
-
- Returns:
-
- A new `TypeChecker` instance.
- """
- return self.redefine_many({type: fn})
-
- def redefine_many(self, definitions=()):
- """
- Produce a new checker with the given types redefined.
-
- Arguments:
-
- definitions (dict):
-
- A dictionary mapping types to their checking functions.
-
- Returns:
-
- A new `TypeChecker` instance.
- """
- return attr.evolve(
- self, type_checkers=self._type_checkers.update(definitions),
- )
-
- def remove(self, *types):
- """
- Produce a new checker with the given types forgotten.
-
- Arguments:
-
- types (~collections.abc.Iterable):
-
- the names of the types to remove.
-
- Returns:
-
- A new `TypeChecker` instance
-
- Raises:
-
- `jsonschema.exceptions.UndefinedTypeCheck`:
-
- if any given type is unknown to this object
- """
-
- checkers = self._type_checkers
- for each in types:
- try:
- checkers = checkers.remove(each)
- except KeyError:
- raise UndefinedTypeCheck(each)
- return attr.evolve(self, type_checkers=checkers)
-
-
-draft3_type_checker = TypeChecker(
- {
- "any": is_any,
- "array": is_array,
- "boolean": is_bool,
- "integer": is_integer,
- "object": is_object,
- "null": is_null,
- "number": is_number,
- "string": is_string,
- },
-)
-draft4_type_checker = draft3_type_checker.remove("any")
-draft6_type_checker = draft4_type_checker.redefine(
- "integer",
- lambda checker, instance: (
- is_integer(checker, instance)
- or isinstance(instance, float) and instance.is_integer()
- ),
-)
-draft7_type_checker = draft6_type_checker
-draft201909_type_checker = draft7_type_checker
-draft202012_type_checker = draft201909_type_checker
diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py
deleted file mode 100644
index a2ad5a9..0000000
--- a/jsonschema/_utils.py
+++ /dev/null
@@ -1,348 +0,0 @@
-from collections.abc import Mapping, MutableMapping, Sequence
-from urllib.parse import urlsplit
-import itertools
-import json
-import re
-import sys
-
-# The files() API was added in Python 3.9.
-if sys.version_info >= (3, 9): # pragma: no cover
- from importlib import resources
-else: # pragma: no cover
- import importlib_resources as resources # type: ignore
-
-
-class URIDict(MutableMapping):
- """
- Dictionary which uses normalized URIs as keys.
- """
-
- def normalize(self, uri):
- return urlsplit(uri).geturl()
-
- def __init__(self, *args, **kwargs):
- self.store = dict()
- self.store.update(*args, **kwargs)
-
- def __getitem__(self, uri):
- return self.store[self.normalize(uri)]
-
- def __setitem__(self, uri, value):
- self.store[self.normalize(uri)] = value
-
- def __delitem__(self, uri):
- del self.store[self.normalize(uri)]
-
- def __iter__(self):
- return iter(self.store)
-
- def __len__(self):
- return len(self.store)
-
- def __repr__(self):
- return repr(self.store)
-
-
-class Unset(object):
- """
- An as-of-yet unset attribute or unprovided default parameter.
- """
-
- def __repr__(self):
- return "<unset>"
-
-
-def load_schema(name):
- """
- Load a schema from ./schemas/``name``.json and return it.
- """
-
- path = resources.files(__package__).joinpath(f"schemas/{name}.json")
- data = path.read_text(encoding="utf-8")
- return json.loads(data)
-
-
-def format_as_index(container, indices):
- """
- Construct a single string containing indexing operations for the indices.
-
- For example for a container ``bar``, [1, 2, "foo"] -> bar[1][2]["foo"]
-
- Arguments:
-
- container (str):
-
- A word to use for the thing being indexed
-
- indices (sequence):
-
- The indices to format.
- """
-
- if not indices:
- return container
- return f"{container}[{']['.join(repr(index) for index in indices)}]"
-
-
-def find_additional_properties(instance, schema):
- """
- Return the set of additional properties for the given ``instance``.
-
- Weeds out properties that should have been validated by ``properties`` and
- / or ``patternProperties``.
-
- Assumes ``instance`` is dict-like already.
- """
-
- properties = schema.get("properties", {})
- patterns = "|".join(schema.get("patternProperties", {}))
- for property in instance:
- if property not in properties:
- if patterns and re.search(patterns, property):
- continue
- yield property
-
-
-def extras_msg(extras):
- """
- Create an error message for extra items or properties.
- """
-
- if len(extras) == 1:
- verb = "was"
- else:
- verb = "were"
- return ", ".join(repr(extra) for extra in sorted(extras)), verb
-
-
-def ensure_list(thing):
- """
- Wrap ``thing`` in a list if it's a single str.
-
- Otherwise, return it unchanged.
- """
-
- if isinstance(thing, str):
- return [thing]
- return thing
-
-
-def _mapping_equal(one, two):
- """
- Check if two mappings are equal using the semantics of `equal`.
- """
- if len(one) != len(two):
- return False
- return all(
- key in two and equal(value, two[key])
- for key, value in one.items()
- )
-
-
-def _sequence_equal(one, two):
- """
- Check if two sequences are equal using the semantics of `equal`.
- """
- if len(one) != len(two):
- return False
- return all(equal(i, j) for i, j in zip(one, two))
-
-
-def equal(one, two):
- """
- Check if two things are equal evading some Python type hierarchy semantics.
-
- Specifically in JSON Schema, evade `bool` inheriting from `int`,
- recursing into sequences to do the same.
- """
- if isinstance(one, str) or isinstance(two, str):
- return one == two
- if isinstance(one, Sequence) and isinstance(two, Sequence):
- return _sequence_equal(one, two)
- if isinstance(one, Mapping) and isinstance(two, Mapping):
- return _mapping_equal(one, two)
- return unbool(one) == unbool(two)
-
-
-def unbool(element, true=object(), false=object()):
- """
- A hack to make True and 1 and False and 0 unique for ``uniq``.
- """
-
- if element is True:
- return true
- elif element is False:
- return false
- return element
-
-
-def uniq(container):
- """
- Check if all of a container's elements are unique.
-
- Tries to rely on the container being recursively sortable, or otherwise
- falls back on (slow) brute force.
- """
- try:
- sort = sorted(unbool(i) for i in container)
- sliced = itertools.islice(sort, 1, None)
-
- for i, j in zip(sort, sliced):
- if equal(i, j):
- return False
-
- except (NotImplementedError, TypeError):
- seen = []
- for e in container:
- e = unbool(e)
-
- for i in seen:
- if equal(i, e):
- return False
-
- seen.append(e)
- return True
-
-
-def find_evaluated_item_indexes_by_schema(validator, instance, schema):
- """
- Get all indexes of items that get evaluated under the current schema
-
- Covers all keywords related to unevaluatedItems: items, prefixItems, if,
- then, else, contains, unevaluatedItems, allOf, oneOf, anyOf
- """
- if validator.is_type(schema, "boolean"):
- return []
- evaluated_indexes = []
-
- if "items" in schema:
- return list(range(0, len(instance)))
-
- if "$ref" in schema:
- scope, resolved = validator.resolver.resolve(schema["$ref"])
- validator.resolver.push_scope(scope)
-
- try:
- evaluated_indexes += find_evaluated_item_indexes_by_schema(
- validator, instance, resolved)
- finally:
- validator.resolver.pop_scope()
-
- if "prefixItems" in schema:
- evaluated_indexes += list(range(0, len(schema["prefixItems"])))
-
- if "if" in schema:
- if validator.evolve(schema=schema["if"]).is_valid(instance):
- evaluated_indexes += find_evaluated_item_indexes_by_schema(
- validator, instance, schema["if"],
- )
- if "then" in schema:
- evaluated_indexes += find_evaluated_item_indexes_by_schema(
- validator, instance, schema["then"],
- )
- else:
- if "else" in schema:
- evaluated_indexes += find_evaluated_item_indexes_by_schema(
- validator, instance, schema["else"],
- )
-
- for keyword in ["contains", "unevaluatedItems"]:
- if keyword in schema:
- for k, v in enumerate(instance):
- if validator.evolve(schema=schema[keyword]).is_valid(v):
- evaluated_indexes.append(k)
-
- for keyword in ["allOf", "oneOf", "anyOf"]:
- if keyword in schema:
- for subschema in schema[keyword]:
- errs = list(validator.descend(instance, subschema))
- if not errs:
- evaluated_indexes += find_evaluated_item_indexes_by_schema(
- validator, instance, subschema,
- )
-
- return evaluated_indexes
-
-
-def find_evaluated_property_keys_by_schema(validator, instance, schema):
- """
- Get all keys of items that get evaluated under the current schema
-
- Covers all keywords related to unevaluatedProperties: properties,
- additionalProperties, unevaluatedProperties, patternProperties,
- dependentSchemas, allOf, oneOf, anyOf, if, then, else
- """
- if validator.is_type(schema, "boolean"):
- return []
- evaluated_keys = []
-
- if "$ref" in schema:
- scope, resolved = validator.resolver.resolve(schema["$ref"])
- validator.resolver.push_scope(scope)
-
- try:
- evaluated_keys += find_evaluated_property_keys_by_schema(
- validator, instance, resolved,
- )
- finally:
- validator.resolver.pop_scope()
-
- for keyword in [
- "properties", "additionalProperties", "unevaluatedProperties",
- ]:
- if keyword in schema:
- if validator.is_type(schema[keyword], "boolean"):
- for property, value in instance.items():
- if validator.evolve(schema=schema[keyword]).is_valid(
- {property: value},
- ):
- evaluated_keys.append(property)
-
- if validator.is_type(schema[keyword], "object"):
- for property, subschema in schema[keyword].items():
- if property in instance and validator.evolve(
- schema=subschema,
- ).is_valid(instance[property]):
- evaluated_keys.append(property)
-
- if "patternProperties" in schema:
- for property, value in instance.items():
- for pattern, _ in schema["patternProperties"].items():
- if re.search(pattern, property) and validator.evolve(
- schema=schema["patternProperties"],
- ).is_valid({property: value}):
- evaluated_keys.append(property)
-
- if "dependentSchemas" in schema:
- for property, subschema in schema["dependentSchemas"].items():
- if property not in instance:
- continue
- evaluated_keys += find_evaluated_property_keys_by_schema(
- validator, instance, subschema,
- )
-
- for keyword in ["allOf", "oneOf", "anyOf"]:
- if keyword in schema:
- for subschema in schema[keyword]:
- errs = list(validator.descend(instance, subschema))
- if not errs:
- evaluated_keys += find_evaluated_property_keys_by_schema(
- validator, instance, subschema,
- )
-
- if "if" in schema:
- if validator.evolve(schema=schema["if"]).is_valid(instance):
- evaluated_keys += find_evaluated_property_keys_by_schema(
- validator, instance, schema["if"],
- )
- if "then" in schema:
- evaluated_keys += find_evaluated_property_keys_by_schema(
- validator, instance, schema["then"],
- )
- else:
- if "else" in schema:
- evaluated_keys += find_evaluated_property_keys_by_schema(
- validator, instance, schema["else"],
- )
-
- return evaluated_keys
diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py
deleted file mode 100644
index 874e879..0000000
--- a/jsonschema/_validators.py
+++ /dev/null
@@ -1,467 +0,0 @@
-from fractions import Fraction
-from urllib.parse import urldefrag, urljoin
-import re
-
-from jsonschema._utils import (
- ensure_list,
- equal,
- extras_msg,
- find_additional_properties,
- find_evaluated_item_indexes_by_schema,
- find_evaluated_property_keys_by_schema,
- unbool,
- uniq,
-)
-from jsonschema.exceptions import FormatError, ValidationError
-
-
-def patternProperties(validator, patternProperties, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- for pattern, subschema in patternProperties.items():
- for k, v in instance.items():
- if re.search(pattern, k):
- yield from validator.descend(
- v, subschema, path=k, schema_path=pattern,
- )
-
-
-def propertyNames(validator, propertyNames, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- for property in instance:
- yield from validator.descend(instance=property, schema=propertyNames)
-
-
-def additionalProperties(validator, aP, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- extras = set(find_additional_properties(instance, schema))
-
- if validator.is_type(aP, "object"):
- for extra in extras:
- yield from validator.descend(instance[extra], aP, path=extra)
- elif not aP and extras:
- if "patternProperties" in schema:
- if len(extras) == 1:
- verb = "does"
- else:
- verb = "do"
-
- joined = ", ".join(repr(each) for each in sorted(extras))
- patterns = ", ".join(
- repr(each) for each in sorted(schema["patternProperties"])
- )
- error = f"{joined} {verb} not match any of the regexes: {patterns}"
- yield ValidationError(error)
- else:
- error = "Additional properties are not allowed (%s %s unexpected)"
- yield ValidationError(error % extras_msg(extras))
-
-
-def items(validator, items, instance, schema):
- if not validator.is_type(instance, "array"):
- return
-
- prefix = len(schema.get("prefixItems", []))
- total = len(instance)
- if items is False and total > prefix:
- message = f"Expected at most {prefix} items, but found {total}"
- yield ValidationError(message)
- else:
- for index in range(prefix, total):
- yield from validator.descend(
- instance=instance[index],
- schema=items,
- path=index,
- )
-
-
-def additionalItems(validator, aI, instance, schema):
- if (
- not validator.is_type(instance, "array")
- or validator.is_type(schema.get("items", {}), "object")
- ):
- return
-
- len_items = len(schema.get("items", []))
- if validator.is_type(aI, "object"):
- for index, item in enumerate(instance[len_items:], start=len_items):
- yield from validator.descend(item, aI, path=index)
- elif not aI and len(instance) > len(schema.get("items", [])):
- error = "Additional items are not allowed (%s %s unexpected)"
- yield ValidationError(
- error % extras_msg(instance[len(schema.get("items", [])):]),
- )
-
-
-def const(validator, const, instance, schema):
- if not equal(instance, const):
- yield ValidationError(f"{const!r} was expected")
-
-
-def contains(validator, contains, instance, schema):
- if not validator.is_type(instance, "array"):
- return
-
- matches = 0
- min_contains = schema.get("minContains", 1)
- max_contains = schema.get("maxContains", len(instance))
-
- for each in instance:
- if validator.evolve(schema=contains).is_valid(each):
- matches += 1
- if matches > max_contains:
- yield ValidationError(
- "Too many items match the given schema "
- f"(expected at most {max_contains})",
- validator="maxContains",
- validator_value=max_contains,
- )
- return
-
- if matches < min_contains:
- if not matches:
- yield ValidationError(
- f"{instance!r} does not contain items "
- "matching the given schema",
- )
- else:
- yield ValidationError(
- "Too few items match the given schema (expected at least "
- f"{min_contains} but only {matches} matched)",
- validator="minContains",
- validator_value=min_contains,
- )
-
-
-def exclusiveMinimum(validator, minimum, instance, schema):
- if not validator.is_type(instance, "number"):
- return
-
- if instance <= minimum:
- yield ValidationError(
- f"{instance!r} is less than or equal to "
- f"the minimum of {minimum!r}",
- )
-
-
-def exclusiveMaximum(validator, maximum, instance, schema):
- if not validator.is_type(instance, "number"):
- return
-
- if instance >= maximum:
- yield ValidationError(
- f"{instance!r} is greater than or equal "
- f"to the maximum of {maximum!r}",
- )
-
-
-def minimum(validator, minimum, instance, schema):
- if not validator.is_type(instance, "number"):
- return
-
- if instance < minimum:
- message = f"{instance!r} is less than the minimum of {minimum!r}"
- yield ValidationError(message)
-
-
-def maximum(validator, maximum, instance, schema):
- if not validator.is_type(instance, "number"):
- return
-
- if instance > maximum:
- message = f"{instance!r} is greater than the maximum of {maximum!r}"
- yield ValidationError(message)
-
-
-def multipleOf(validator, dB, instance, schema):
- if not validator.is_type(instance, "number"):
- return
-
- if isinstance(dB, float):
- quotient = instance / dB
- try:
- failed = int(quotient) != quotient
- except OverflowError:
- # When `instance` is large and `dB` is less than one,
- # quotient can overflow to infinity; and then casting to int
- # raises an error.
- #
- # In this case we fall back to Fraction logic, which is
- # exact and cannot overflow. The performance is also
- # acceptable: we try the fast all-float option first, and
- # we know that fraction(dB) can have at most a few hundred
- # digits in each part. The worst-case slowdown is therefore
- # for already-slow enormous integers or Decimals.
- failed = (Fraction(instance) / Fraction(dB)).denominator != 1
- else:
- failed = instance % dB
-
- if failed:
- yield ValidationError(f"{instance!r} is not a multiple of {dB}")
-
-
-def minItems(validator, mI, instance, schema):
- if validator.is_type(instance, "array") and len(instance) < mI:
- yield ValidationError(f"{instance!r} is too short")
-
-
-def maxItems(validator, mI, instance, schema):
- if validator.is_type(instance, "array") and len(instance) > mI:
- yield ValidationError(f"{instance!r} is too long")
-
-
-def uniqueItems(validator, uI, instance, schema):
- if (
- uI
- and validator.is_type(instance, "array")
- and not uniq(instance)
- ):
- yield ValidationError(f"{instance!r} has non-unique elements")
-
-
-def pattern(validator, patrn, instance, schema):
- if (
- validator.is_type(instance, "string")
- and not re.search(patrn, instance)
- ):
- yield ValidationError(f"{instance!r} does not match {patrn!r}")
-
-
-def format(validator, format, instance, schema):
- if validator.format_checker is not None:
- try:
- validator.format_checker.check(instance, format)
- except FormatError as error:
- yield ValidationError(error.message, cause=error.cause)
-
-
-def minLength(validator, mL, instance, schema):
- if validator.is_type(instance, "string") and len(instance) < mL:
- yield ValidationError(f"{instance!r} is too short")
-
-
-def maxLength(validator, mL, instance, schema):
- if validator.is_type(instance, "string") and len(instance) > mL:
- yield ValidationError(f"{instance!r} is too long")
-
-
-def dependentRequired(validator, dependentRequired, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- for property, dependency in dependentRequired.items():
- if property not in instance:
- continue
-
- for each in dependency:
- if each not in instance:
- message = f"{each!r} is a dependency of {property!r}"
- yield ValidationError(message)
-
-
-def dependentSchemas(validator, dependentSchemas, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- for property, dependency in dependentSchemas.items():
- if property not in instance:
- continue
- yield from validator.descend(
- instance, dependency, schema_path=property,
- )
-
-
-def enum(validator, enums, instance, schema):
- if instance == 0 or instance == 1:
- unbooled = unbool(instance)
- if all(unbooled != unbool(each) for each in enums):
- yield ValidationError(f"{instance!r} is not one of {enums!r}")
- elif instance not in enums:
- yield ValidationError(f"{instance!r} is not one of {enums!r}")
-
-
-def ref(validator, ref, instance, schema):
- resolve = getattr(validator.resolver, "resolve", None)
- if resolve is None:
- with validator.resolver.resolving(ref) as resolved:
- yield from validator.descend(instance, resolved)
- else:
- scope, resolved = validator.resolver.resolve(ref)
- validator.resolver.push_scope(scope)
-
- try:
- yield from validator.descend(instance, resolved)
- finally:
- validator.resolver.pop_scope()
-
-
-def dynamicRef(validator, dynamicRef, instance, schema):
- _, fragment = urldefrag(dynamicRef)
-
- for url in validator.resolver._scopes_stack:
- lookup_url = urljoin(url, dynamicRef)
- with validator.resolver.resolving(lookup_url) as subschema:
- if ("$dynamicAnchor" in subschema
- and fragment == subschema["$dynamicAnchor"]):
- yield from validator.descend(instance, subschema)
- break
- else:
- with validator.resolver.resolving(dynamicRef) as subschema:
- yield from validator.descend(instance, subschema)
-
-
-def type(validator, types, instance, schema):
- types = ensure_list(types)
-
- if not any(validator.is_type(instance, type) for type in types):
- reprs = ", ".join(repr(type) for type in types)
- yield ValidationError(f"{instance!r} is not of type {reprs}")
-
-
-def properties(validator, properties, instance, schema):
- if not validator.is_type(instance, "object"):
- return
-
- for property, subschema in properties.items():
- if property in instance:
- yield from validator.descend(
- instance[property],
- subschema,
- path=property,
- schema_path=property,
- )
-
-
-def required(validator, required, instance, schema):
- if not validator.is_type(instance, "object"):
- return
- for property in required:
- if property not in instance:
- yield ValidationError(f"{property!r} is a required property")
-
-
-def minProperties(validator, mP, instance, schema):
- if validator.is_type(instance, "object") and len(instance) < mP:
- yield ValidationError(f"{instance!r} does not have enough properties")
-
-
-def maxProperties(validator, mP, instance, schema):
- if not validator.is_type(instance, "object"):
- return
- if validator.is_type(instance, "object") and len(instance) > mP:
- yield ValidationError(f"{instance!r} has too many properties")
-
-
-def allOf(validator, allOf, instance, schema):
- for index, subschema in enumerate(allOf):
- yield from validator.descend(instance, subschema, schema_path=index)
-
-
-def anyOf(validator, anyOf, instance, schema):
- all_errors = []
- for index, subschema in enumerate(anyOf):
- errs = list(validator.descend(instance, subschema, schema_path=index))
- if not errs:
- break
- all_errors.extend(errs)
- else:
- yield ValidationError(
- f"{instance!r} is not valid under any of the given schemas",
- context=all_errors,
- )
-
-
-def oneOf(validator, oneOf, instance, schema):
- subschemas = enumerate(oneOf)
- all_errors = []
- for index, subschema in subschemas:
- errs = list(validator.descend(instance, subschema, schema_path=index))
- if not errs:
- first_valid = subschema
- break
- all_errors.extend(errs)
- else:
- yield ValidationError(
- f"{instance!r} is not valid under any of the given schemas",
- context=all_errors,
- )
-
- more_valid = [
- each for _, each in subschemas
- if validator.evolve(schema=each).is_valid(instance)
- ]
- if more_valid:
- more_valid.append(first_valid)
- reprs = ", ".join(repr(schema) for schema in more_valid)
- yield ValidationError(f"{instance!r} is valid under each of {reprs}")
-
-
-def not_(validator, not_schema, instance, schema):
- if validator.evolve(schema=not_schema).is_valid(instance):
- message = f"{instance!r} should not be valid under {not_schema!r}"
- yield ValidationError(message)
-
-
-def if_(validator, if_schema, instance, schema):
- if validator.evolve(schema=if_schema).is_valid(instance):
- if "then" in schema:
- then = schema["then"]
- yield from validator.descend(instance, then, schema_path="then")
- elif "else" in schema:
- else_ = schema["else"]
- yield from validator.descend(instance, else_, schema_path="else")
-
-
-def unevaluatedItems(validator, unevaluatedItems, instance, schema):
- if not validator.is_type(instance, "array"):
- return
- evaluated_item_indexes = find_evaluated_item_indexes_by_schema(
- validator, instance, schema,
- )
- unevaluated_items = [
- item for index, item in enumerate(instance)
- if index not in evaluated_item_indexes
- ]
- if unevaluated_items:
- error = "Unevaluated items are not allowed (%s %s unexpected)"
- yield ValidationError(error % extras_msg(unevaluated_items))
-
-
-def unevaluatedProperties(validator, unevaluatedProperties, instance, schema):
- if not validator.is_type(instance, "object"):
- return
- evaluated_property_keys = find_evaluated_property_keys_by_schema(
- validator, instance, schema,
- )
- unevaluated_property_keys = []
- for property in instance:
- if property not in evaluated_property_keys:
- for _ in validator.descend(
- instance[property],
- unevaluatedProperties,
- path=property,
- schema_path=property,
- ):
- unevaluated_property_keys.append(property)
-
- if unevaluated_property_keys:
- error = "Unevaluated properties are not allowed (%s %s unexpected)"
- yield ValidationError(error % extras_msg(unevaluated_property_keys))
-
-
-def prefixItems(validator, prefixItems, instance, schema):
- if not validator.is_type(instance, "array"):
- return
-
- for (index, item), subschema in zip(enumerate(instance), prefixItems):
- yield from validator.descend(
- instance=item,
- schema=subschema,
- schema_path=index,
- path=index,
- )
diff --git a/jsonschema/benchmarks/__init__.py b/jsonschema/benchmarks/__init__.py
deleted file mode 100644
index e3dcc68..0000000
--- a/jsonschema/benchmarks/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-"""
-Benchmarks for validation.
-
-This package is *not* public API.
-"""
diff --git a/jsonschema/benchmarks/issue232.py b/jsonschema/benchmarks/issue232.py
deleted file mode 100644
index bf357e9..0000000
--- a/jsonschema/benchmarks/issue232.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""
-A performance benchmark using the example from issue #232.
-
-See https://github.com/python-jsonschema/jsonschema/pull/232.
-"""
-from pathlib import Path
-
-from pyperf import Runner
-from pyrsistent import m
-
-from jsonschema.tests._suite import Version
-import jsonschema
-
-issue232 = Version(
- path=Path(__file__).parent / "issue232",
- remotes=m(),
- name="issue232",
-)
-
-
-if __name__ == "__main__":
- issue232.benchmark(
- runner=Runner(),
- Validator=jsonschema.Draft4Validator,
- )
diff --git a/jsonschema/benchmarks/issue232/issue.json b/jsonschema/benchmarks/issue232/issue.json
deleted file mode 100644
index 804c340..0000000
--- a/jsonschema/benchmarks/issue232/issue.json
+++ /dev/null
@@ -1,2653 +0,0 @@
-[
- {
- "description": "Petstore",
- "schema": {
- "title": "A JSON Schema for Swagger 2.0 API.",
- "id": "http://swagger.io/v2/schema.json#",
- "$schema": "http://json-schema.org/draft-04/schema#",
- "type": "object",
- "required": [
- "swagger",
- "info",
- "paths"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "swagger": {
- "type": "string",
- "enum": [
- "2.0"
- ],
- "description": "The Swagger version of this document."
- },
- "info": {
- "$ref": "#/definitions/info"
- },
- "host": {
- "type": "string",
- "pattern": "^[^{}/ :\\\\]+(?::\\d+)?$",
- "description": "The host (name or ip) of the API. Example: 'swagger.io'"
- },
- "basePath": {
- "type": "string",
- "pattern": "^/",
- "description": "The base path to the API. Example: '/api'."
- },
- "schemes": {
- "$ref": "#/definitions/schemesList"
- },
- "consumes": {
- "description": "A list of MIME types accepted by the API.",
- "allOf": [
- {
- "$ref": "#/definitions/mediaTypeList"
- }
- ]
- },
- "produces": {
- "description": "A list of MIME types the API can produce.",
- "allOf": [
- {
- "$ref": "#/definitions/mediaTypeList"
- }
- ]
- },
- "paths": {
- "$ref": "#/definitions/paths"
- },
- "definitions": {
- "$ref": "#/definitions/definitions"
- },
- "parameters": {
- "$ref": "#/definitions/parameterDefinitions"
- },
- "responses": {
- "$ref": "#/definitions/responseDefinitions"
- },
- "security": {
- "$ref": "#/definitions/security"
- },
- "securityDefinitions": {
- "$ref": "#/definitions/securityDefinitions"
- },
- "tags": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/tag"
- },
- "uniqueItems": true
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- }
- },
- "definitions": {
- "info": {
- "type": "object",
- "description": "General information about the API.",
- "required": [
- "version",
- "title"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "title": {
- "type": "string",
- "description": "A unique and precise title of the API."
- },
- "version": {
- "type": "string",
- "description": "A semantic version number of the API."
- },
- "description": {
- "type": "string",
- "description": "A longer description of the API. Should be different from the title. GitHub Flavored Markdown is allowed."
- },
- "termsOfService": {
- "type": "string",
- "description": "The terms of service for the API."
- },
- "contact": {
- "$ref": "#/definitions/contact"
- },
- "license": {
- "$ref": "#/definitions/license"
- }
- }
- },
- "contact": {
- "type": "object",
- "description": "Contact information for the owners of the API.",
- "additionalProperties": false,
- "properties": {
- "name": {
- "type": "string",
- "description": "The identifying name of the contact person/organization."
- },
- "url": {
- "type": "string",
- "description": "The URL pointing to the contact information.",
- "format": "uri"
- },
- "email": {
- "type": "string",
- "description": "The email address of the contact person/organization.",
- "format": "email"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "license": {
- "type": "object",
- "required": [
- "name"
- ],
- "additionalProperties": false,
- "properties": {
- "name": {
- "type": "string",
- "description": "The name of the license type. It's encouraged to use an OSI compatible license."
- },
- "url": {
- "type": "string",
- "description": "The URL pointing to the license.",
- "format": "uri"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "paths": {
- "type": "object",
- "description": "Relative paths to the individual endpoints. They must be relative to the 'basePath'.",
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- },
- "^/": {
- "$ref": "#/definitions/pathItem"
- }
- },
- "additionalProperties": false
- },
- "definitions": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/schema"
- },
- "description": "One or more JSON objects describing the schemas being consumed and produced by the API."
- },
- "parameterDefinitions": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/parameter"
- },
- "description": "One or more JSON representations for parameters"
- },
- "responseDefinitions": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/response"
- },
- "description": "One or more JSON representations for parameters"
- },
- "externalDocs": {
- "type": "object",
- "additionalProperties": false,
- "description": "information about external documentation",
- "required": [
- "url"
- ],
- "properties": {
- "description": {
- "type": "string"
- },
- "url": {
- "type": "string",
- "format": "uri"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "examples": {
- "type": "object",
- "additionalProperties": true
- },
- "mimeType": {
- "type": "string",
- "description": "The MIME type of the HTTP message."
- },
- "operation": {
- "type": "object",
- "required": [
- "responses"
- ],
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "tags": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- },
- "summary": {
- "type": "string",
- "description": "A brief summary of the operation."
- },
- "description": {
- "type": "string",
- "description": "A longer description of the operation, GitHub Flavored Markdown is allowed."
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- },
- "operationId": {
- "type": "string",
- "description": "A unique identifier of the operation."
- },
- "produces": {
- "description": "A list of MIME types the API can produce.",
- "allOf": [
- {
- "$ref": "#/definitions/mediaTypeList"
- }
- ]
- },
- "consumes": {
- "description": "A list of MIME types the API can consume.",
- "allOf": [
- {
- "$ref": "#/definitions/mediaTypeList"
- }
- ]
- },
- "parameters": {
- "$ref": "#/definitions/parametersList"
- },
- "responses": {
- "$ref": "#/definitions/responses"
- },
- "schemes": {
- "$ref": "#/definitions/schemesList"
- },
- "deprecated": {
- "type": "boolean",
- "default": false
- },
- "security": {
- "$ref": "#/definitions/security"
- }
- }
- },
- "pathItem": {
- "type": "object",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "$ref": {
- "type": "string"
- },
- "get": {
- "$ref": "#/definitions/operation"
- },
- "put": {
- "$ref": "#/definitions/operation"
- },
- "post": {
- "$ref": "#/definitions/operation"
- },
- "delete": {
- "$ref": "#/definitions/operation"
- },
- "options": {
- "$ref": "#/definitions/operation"
- },
- "head": {
- "$ref": "#/definitions/operation"
- },
- "patch": {
- "$ref": "#/definitions/operation"
- },
- "parameters": {
- "$ref": "#/definitions/parametersList"
- }
- }
- },
- "responses": {
- "type": "object",
- "description": "Response objects names can either be any valid HTTP status code or 'default'.",
- "minProperties": 1,
- "additionalProperties": false,
- "patternProperties": {
- "^([0-9]{3})$|^(default)$": {
- "$ref": "#/definitions/responseValue"
- },
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "not": {
- "type": "object",
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- }
- },
- "responseValue": {
- "oneOf": [
- {
- "$ref": "#/definitions/response"
- },
- {
- "$ref": "#/definitions/jsonReference"
- }
- ]
- },
- "response": {
- "type": "object",
- "required": [
- "description"
- ],
- "properties": {
- "description": {
- "type": "string"
- },
- "schema": {
- "oneOf": [
- {
- "$ref": "#/definitions/schema"
- },
- {
- "$ref": "#/definitions/fileSchema"
- }
- ]
- },
- "headers": {
- "$ref": "#/definitions/headers"
- },
- "examples": {
- "$ref": "#/definitions/examples"
- }
- },
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "headers": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/header"
- }
- },
- "header": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "type"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "string",
- "number",
- "integer",
- "boolean",
- "array"
- ]
- },
- "format": {
- "type": "string"
- },
- "items": {
- "$ref": "#/definitions/primitivesItems"
- },
- "collectionFormat": {
- "$ref": "#/definitions/collectionFormat"
- },
- "default": {
- "$ref": "#/definitions/default"
- },
- "maximum": {
- "$ref": "#/definitions/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "#/definitions/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "#/definitions/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "#/definitions/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "#/definitions/maxLength"
- },
- "minLength": {
- "$ref": "#/definitions/minLength"
- },
- "pattern": {
- "$ref": "#/definitions/pattern"
- },
- "maxItems": {
- "$ref": "#/definitions/maxItems"
- },
- "minItems": {
- "$ref": "#/definitions/minItems"
- },
- "uniqueItems": {
- "$ref": "#/definitions/uniqueItems"
- },
- "enum": {
- "$ref": "#/definitions/enum"
- },
- "multipleOf": {
- "$ref": "#/definitions/multipleOf"
- },
- "description": {
- "type": "string"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "vendorExtension": {
- "description": "Any property starting with x- is valid.",
- "additionalProperties": true,
- "additionalItems": true
- },
- "bodyParameter": {
- "type": "object",
- "required": [
- "name",
- "in",
- "schema"
- ],
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "description": {
- "type": "string",
- "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
- },
- "name": {
- "type": "string",
- "description": "The name of the parameter."
- },
- "in": {
- "type": "string",
- "description": "Determines the location of the parameter.",
- "enum": [
- "body"
- ]
- },
- "required": {
- "type": "boolean",
- "description": "Determines whether or not this parameter is required or optional.",
- "default": false
- },
- "schema": {
- "$ref": "#/definitions/schema"
- }
- },
- "additionalProperties": false
- },
- "headerParameterSubSchema": {
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "required": {
- "type": "boolean",
- "description": "Determines whether or not this parameter is required or optional.",
- "default": false
- },
- "in": {
- "type": "string",
- "description": "Determines the location of the parameter.",
- "enum": [
- "header"
- ]
- },
- "description": {
- "type": "string",
- "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
- },
- "name": {
- "type": "string",
- "description": "The name of the parameter."
- },
- "type": {
- "type": "string",
- "enum": [
- "string",
- "number",
- "boolean",
- "integer",
- "array"
- ]
- },
- "format": {
- "type": "string"
- },
- "items": {
- "$ref": "#/definitions/primitivesItems"
- },
- "collectionFormat": {
- "$ref": "#/definitions/collectionFormat"
- },
- "default": {
- "$ref": "#/definitions/default"
- },
- "maximum": {
- "$ref": "#/definitions/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "#/definitions/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "#/definitions/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "#/definitions/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "#/definitions/maxLength"
- },
- "minLength": {
- "$ref": "#/definitions/minLength"
- },
- "pattern": {
- "$ref": "#/definitions/pattern"
- },
- "maxItems": {
- "$ref": "#/definitions/maxItems"
- },
- "minItems": {
- "$ref": "#/definitions/minItems"
- },
- "uniqueItems": {
- "$ref": "#/definitions/uniqueItems"
- },
- "enum": {
- "$ref": "#/definitions/enum"
- },
- "multipleOf": {
- "$ref": "#/definitions/multipleOf"
- }
- }
- },
- "queryParameterSubSchema": {
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "required": {
- "type": "boolean",
- "description": "Determines whether or not this parameter is required or optional.",
- "default": false
- },
- "in": {
- "type": "string",
- "description": "Determines the location of the parameter.",
- "enum": [
- "query"
- ]
- },
- "description": {
- "type": "string",
- "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
- },
- "name": {
- "type": "string",
- "description": "The name of the parameter."
- },
- "allowEmptyValue": {
- "type": "boolean",
- "default": false,
- "description": "allows sending a parameter by name only or with an empty value."
- },
- "type": {
- "type": "string",
- "enum": [
- "string",
- "number",
- "boolean",
- "integer",
- "array"
- ]
- },
- "format": {
- "type": "string"
- },
- "items": {
- "$ref": "#/definitions/primitivesItems"
- },
- "collectionFormat": {
- "$ref": "#/definitions/collectionFormatWithMulti"
- },
- "default": {
- "$ref": "#/definitions/default"
- },
- "maximum": {
- "$ref": "#/definitions/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "#/definitions/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "#/definitions/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "#/definitions/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "#/definitions/maxLength"
- },
- "minLength": {
- "$ref": "#/definitions/minLength"
- },
- "pattern": {
- "$ref": "#/definitions/pattern"
- },
- "maxItems": {
- "$ref": "#/definitions/maxItems"
- },
- "minItems": {
- "$ref": "#/definitions/minItems"
- },
- "uniqueItems": {
- "$ref": "#/definitions/uniqueItems"
- },
- "enum": {
- "$ref": "#/definitions/enum"
- },
- "multipleOf": {
- "$ref": "#/definitions/multipleOf"
- }
- }
- },
- "formDataParameterSubSchema": {
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "required": {
- "type": "boolean",
- "description": "Determines whether or not this parameter is required or optional.",
- "default": false
- },
- "in": {
- "type": "string",
- "description": "Determines the location of the parameter.",
- "enum": [
- "formData"
- ]
- },
- "description": {
- "type": "string",
- "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
- },
- "name": {
- "type": "string",
- "description": "The name of the parameter."
- },
- "allowEmptyValue": {
- "type": "boolean",
- "default": false,
- "description": "allows sending a parameter by name only or with an empty value."
- },
- "type": {
- "type": "string",
- "enum": [
- "string",
- "number",
- "boolean",
- "integer",
- "array",
- "file"
- ]
- },
- "format": {
- "type": "string"
- },
- "items": {
- "$ref": "#/definitions/primitivesItems"
- },
- "collectionFormat": {
- "$ref": "#/definitions/collectionFormatWithMulti"
- },
- "default": {
- "$ref": "#/definitions/default"
- },
- "maximum": {
- "$ref": "#/definitions/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "#/definitions/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "#/definitions/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "#/definitions/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "#/definitions/maxLength"
- },
- "minLength": {
- "$ref": "#/definitions/minLength"
- },
- "pattern": {
- "$ref": "#/definitions/pattern"
- },
- "maxItems": {
- "$ref": "#/definitions/maxItems"
- },
- "minItems": {
- "$ref": "#/definitions/minItems"
- },
- "uniqueItems": {
- "$ref": "#/definitions/uniqueItems"
- },
- "enum": {
- "$ref": "#/definitions/enum"
- },
- "multipleOf": {
- "$ref": "#/definitions/multipleOf"
- }
- }
- },
- "pathParameterSubSchema": {
- "additionalProperties": false,
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "required": [
- "required"
- ],
- "properties": {
- "required": {
- "type": "boolean",
- "enum": [
- true
- ],
- "description": "Determines whether or not this parameter is required or optional."
- },
- "in": {
- "type": "string",
- "description": "Determines the location of the parameter.",
- "enum": [
- "path"
- ]
- },
- "description": {
- "type": "string",
- "description": "A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed."
- },
- "name": {
- "type": "string",
- "description": "The name of the parameter."
- },
- "type": {
- "type": "string",
- "enum": [
- "string",
- "number",
- "boolean",
- "integer",
- "array"
- ]
- },
- "format": {
- "type": "string"
- },
- "items": {
- "$ref": "#/definitions/primitivesItems"
- },
- "collectionFormat": {
- "$ref": "#/definitions/collectionFormat"
- },
- "default": {
- "$ref": "#/definitions/default"
- },
- "maximum": {
- "$ref": "#/definitions/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "#/definitions/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "#/definitions/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "#/definitions/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "#/definitions/maxLength"
- },
- "minLength": {
- "$ref": "#/definitions/minLength"
- },
- "pattern": {
- "$ref": "#/definitions/pattern"
- },
- "maxItems": {
- "$ref": "#/definitions/maxItems"
- },
- "minItems": {
- "$ref": "#/definitions/minItems"
- },
- "uniqueItems": {
- "$ref": "#/definitions/uniqueItems"
- },
- "enum": {
- "$ref": "#/definitions/enum"
- },
- "multipleOf": {
- "$ref": "#/definitions/multipleOf"
- }
- }
- },
- "nonBodyParameter": {
- "type": "object",
- "required": [
- "name",
- "in",
- "type"
- ],
- "oneOf": [
- {
- "$ref": "#/definitions/headerParameterSubSchema"
- },
- {
- "$ref": "#/definitions/formDataParameterSubSchema"
- },
- {
- "$ref": "#/definitions/queryParameterSubSchema"
- },
- {
- "$ref": "#/definitions/pathParameterSubSchema"
- }
- ]
- },
- "parameter": {
- "oneOf": [
- {
- "$ref": "#/definitions/bodyParameter"
- },
- {
- "$ref": "#/definitions/nonBodyParameter"
- }
- ]
- },
- "schema": {
- "type": "object",
- "description": "A deterministic version of a JSON Schema object.",
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "properties": {
- "$ref": {
- "type": "string"
- },
- "format": {
- "type": "string"
- },
- "title": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
- },
- "description": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
- },
- "default": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
- },
- "multipleOf": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
- },
- "maximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
- },
- "minLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
- },
- "pattern": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
- },
- "maxItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
- },
- "minItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
- },
- "uniqueItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
- },
- "maxProperties": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
- },
- "minProperties": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
- },
- "required": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
- },
- "enum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
- },
- "additionalProperties": {
- "anyOf": [
- {
- "$ref": "#/definitions/schema"
- },
- {
- "type": "boolean"
- }
- ],
- "default": {}
- },
- "type": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/type"
- },
- "items": {
- "anyOf": [
- {
- "$ref": "#/definitions/schema"
- },
- {
- "type": "array",
- "minItems": 1,
- "items": {
- "$ref": "#/definitions/schema"
- }
- }
- ],
- "default": {}
- },
- "allOf": {
- "type": "array",
- "minItems": 1,
- "items": {
- "$ref": "#/definitions/schema"
- }
- },
- "properties": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/schema"
- },
- "default": {}
- },
- "discriminator": {
- "type": "string"
- },
- "readOnly": {
- "type": "boolean",
- "default": false
- },
- "xml": {
- "$ref": "#/definitions/xml"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- },
- "example": {}
- },
- "additionalProperties": false
- },
- "fileSchema": {
- "type": "object",
- "description": "A deterministic version of a JSON Schema object.",
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- },
- "required": [
- "type"
- ],
- "properties": {
- "format": {
- "type": "string"
- },
- "title": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
- },
- "description": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
- },
- "default": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
- },
- "required": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
- },
- "type": {
- "type": "string",
- "enum": [
- "file"
- ]
- },
- "readOnly": {
- "type": "boolean",
- "default": false
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- },
- "example": {}
- },
- "additionalProperties": false
- },
- "primitivesItems": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "string",
- "number",
- "integer",
- "boolean",
- "array"
- ]
- },
- "format": {
- "type": "string"
- },
- "items": {
- "$ref": "#/definitions/primitivesItems"
- },
- "collectionFormat": {
- "$ref": "#/definitions/collectionFormat"
- },
- "default": {
- "$ref": "#/definitions/default"
- },
- "maximum": {
- "$ref": "#/definitions/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "#/definitions/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "#/definitions/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "#/definitions/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "#/definitions/maxLength"
- },
- "minLength": {
- "$ref": "#/definitions/minLength"
- },
- "pattern": {
- "$ref": "#/definitions/pattern"
- },
- "maxItems": {
- "$ref": "#/definitions/maxItems"
- },
- "minItems": {
- "$ref": "#/definitions/minItems"
- },
- "uniqueItems": {
- "$ref": "#/definitions/uniqueItems"
- },
- "enum": {
- "$ref": "#/definitions/enum"
- },
- "multipleOf": {
- "$ref": "#/definitions/multipleOf"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "security": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/securityRequirement"
- },
- "uniqueItems": true
- },
- "securityRequirement": {
- "type": "object",
- "additionalProperties": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- }
- },
- "xml": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "name": {
- "type": "string"
- },
- "namespace": {
- "type": "string"
- },
- "prefix": {
- "type": "string"
- },
- "attribute": {
- "type": "boolean",
- "default": false
- },
- "wrapped": {
- "type": "boolean",
- "default": false
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "tag": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "name"
- ],
- "properties": {
- "name": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "externalDocs": {
- "$ref": "#/definitions/externalDocs"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "securityDefinitions": {
- "type": "object",
- "additionalProperties": {
- "oneOf": [
- {
- "$ref": "#/definitions/basicAuthenticationSecurity"
- },
- {
- "$ref": "#/definitions/apiKeySecurity"
- },
- {
- "$ref": "#/definitions/oauth2ImplicitSecurity"
- },
- {
- "$ref": "#/definitions/oauth2PasswordSecurity"
- },
- {
- "$ref": "#/definitions/oauth2ApplicationSecurity"
- },
- {
- "$ref": "#/definitions/oauth2AccessCodeSecurity"
- }
- ]
- }
- },
- "basicAuthenticationSecurity": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "type"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "basic"
- ]
- },
- "description": {
- "type": "string"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "apiKeySecurity": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "type",
- "name",
- "in"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "apiKey"
- ]
- },
- "name": {
- "type": "string"
- },
- "in": {
- "type": "string",
- "enum": [
- "header",
- "query"
- ]
- },
- "description": {
- "type": "string"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "oauth2ImplicitSecurity": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "type",
- "flow",
- "authorizationUrl"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "oauth2"
- ]
- },
- "flow": {
- "type": "string",
- "enum": [
- "implicit"
- ]
- },
- "scopes": {
- "$ref": "#/definitions/oauth2Scopes"
- },
- "authorizationUrl": {
- "type": "string",
- "format": "uri"
- },
- "description": {
- "type": "string"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "oauth2PasswordSecurity": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "type",
- "flow",
- "tokenUrl"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "oauth2"
- ]
- },
- "flow": {
- "type": "string",
- "enum": [
- "password"
- ]
- },
- "scopes": {
- "$ref": "#/definitions/oauth2Scopes"
- },
- "tokenUrl": {
- "type": "string",
- "format": "uri"
- },
- "description": {
- "type": "string"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "oauth2ApplicationSecurity": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "type",
- "flow",
- "tokenUrl"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "oauth2"
- ]
- },
- "flow": {
- "type": "string",
- "enum": [
- "application"
- ]
- },
- "scopes": {
- "$ref": "#/definitions/oauth2Scopes"
- },
- "tokenUrl": {
- "type": "string",
- "format": "uri"
- },
- "description": {
- "type": "string"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "oauth2AccessCodeSecurity": {
- "type": "object",
- "additionalProperties": false,
- "required": [
- "type",
- "flow",
- "authorizationUrl",
- "tokenUrl"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "oauth2"
- ]
- },
- "flow": {
- "type": "string",
- "enum": [
- "accessCode"
- ]
- },
- "scopes": {
- "$ref": "#/definitions/oauth2Scopes"
- },
- "authorizationUrl": {
- "type": "string",
- "format": "uri"
- },
- "tokenUrl": {
- "type": "string",
- "format": "uri"
- },
- "description": {
- "type": "string"
- }
- },
- "patternProperties": {
- "^x-": {
- "$ref": "#/definitions/vendorExtension"
- }
- }
- },
- "oauth2Scopes": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
- },
- "mediaTypeList": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/mimeType"
- },
- "uniqueItems": true
- },
- "parametersList": {
- "type": "array",
- "description": "The parameters needed to send a valid API call.",
- "additionalItems": false,
- "items": {
- "oneOf": [
- {
- "$ref": "#/definitions/parameter"
- },
- {
- "$ref": "#/definitions/jsonReference"
- }
- ]
- },
- "uniqueItems": true
- },
- "schemesList": {
- "type": "array",
- "description": "The transfer protocol of the API.",
- "items": {
- "type": "string",
- "enum": [
- "http",
- "https",
- "ws",
- "wss"
- ]
- },
- "uniqueItems": true
- },
- "collectionFormat": {
- "type": "string",
- "enum": [
- "csv",
- "ssv",
- "tsv",
- "pipes"
- ],
- "default": "csv"
- },
- "collectionFormatWithMulti": {
- "type": "string",
- "enum": [
- "csv",
- "ssv",
- "tsv",
- "pipes",
- "multi"
- ],
- "default": "csv"
- },
- "title": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
- },
- "description": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
- },
- "default": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
- },
- "multipleOf": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
- },
- "maximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
- },
- "exclusiveMaximum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
- },
- "minimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
- },
- "exclusiveMinimum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
- },
- "maxLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
- },
- "minLength": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
- },
- "pattern": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
- },
- "maxItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
- },
- "minItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
- },
- "uniqueItems": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
- },
- "enum": {
- "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
- },
- "jsonReference": {
- "type": "object",
- "required": [
- "$ref"
- ],
- "additionalProperties": false,
- "properties": {
- "$ref": {
- "type": "string"
- }
- }
- }
- }
- },
- "tests": [
- {
- "description": "Example petsore",
- "data": {
- "swagger": "2.0",
- "info": {
- "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
- "version": "1.0.0",
- "title": "Swagger Petstore",
- "termsOfService": "http://swagger.io/terms/",
- "contact": {
- "email": "apiteam@swagger.io"
- },
- "license": {
- "name": "Apache 2.0",
- "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
- }
- },
- "host": "petstore.swagger.io",
- "basePath": "/v2",
- "tags": [
- {
- "name": "pet",
- "description": "Everything about your Pets",
- "externalDocs": {
- "description": "Find out more",
- "url": "http://swagger.io"
- }
- },
- {
- "name": "store",
- "description": "Access to Petstore orders"
- },
- {
- "name": "user",
- "description": "Operations about user",
- "externalDocs": {
- "description": "Find out more about our store",
- "url": "http://swagger.io"
- }
- }
- ],
- "schemes": [
- "http"
- ],
- "paths": {
- "/pet": {
- "post": {
- "tags": [
- "pet"
- ],
- "summary": "Add a new pet to the store",
- "description": "",
- "operationId": "addPet",
- "consumes": [
- "application/json",
- "application/xml"
- ],
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "Pet object that needs to be added to the store",
- "required": true,
- "schema": {
- "$ref": "#/definitions/Pet"
- }
- }
- ],
- "responses": {
- "405": {
- "description": "Invalid input"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- },
- "put": {
- "tags": [
- "pet"
- ],
- "summary": "Update an existing pet",
- "description": "",
- "operationId": "updatePet",
- "consumes": [
- "application/json",
- "application/xml"
- ],
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "Pet object that needs to be added to the store",
- "required": true,
- "schema": {
- "$ref": "#/definitions/Pet"
- }
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Pet not found"
- },
- "405": {
- "description": "Validation exception"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- }
- },
- "/pet/findByStatus": {
- "get": {
- "tags": [
- "pet"
- ],
- "summary": "Finds Pets by status",
- "description": "Multiple status values can be provided with comma separated strings",
- "operationId": "findPetsByStatus",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "status",
- "in": "query",
- "description": "Status values that need to be considered for filter",
- "required": true,
- "type": "array",
- "items": {
- "type": "string",
- "enum": [
- "available",
- "pending",
- "sold"
- ],
- "default": "available"
- },
- "collectionFormat": "multi"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/Pet"
- }
- }
- },
- "400": {
- "description": "Invalid status value"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- }
- },
- "/pet/findByTags": {
- "get": {
- "tags": [
- "pet"
- ],
- "summary": "Finds Pets by tags",
- "description": "Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
- "operationId": "findPetsByTags",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "tags",
- "in": "query",
- "description": "Tags to filter by",
- "required": true,
- "type": "array",
- "items": {
- "type": "string"
- },
- "collectionFormat": "multi"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/Pet"
- }
- }
- },
- "400": {
- "description": "Invalid tag value"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ],
- "deprecated": true
- }
- },
- "/pet/{petId}": {
- "get": {
- "tags": [
- "pet"
- ],
- "summary": "Find pet by ID",
- "description": "Returns a single pet",
- "operationId": "getPetById",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "petId",
- "in": "path",
- "description": "ID of pet to return",
- "required": true,
- "type": "integer",
- "format": "int64"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/Pet"
- }
- },
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Pet not found"
- }
- },
- "security": [
- {
- "api_key": []
- }
- ]
- },
- "post": {
- "tags": [
- "pet"
- ],
- "summary": "Updates a pet in the store with form data",
- "description": "",
- "operationId": "updatePetWithForm",
- "consumes": [
- "application/x-www-form-urlencoded"
- ],
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "petId",
- "in": "path",
- "description": "ID of pet that needs to be updated",
- "required": true,
- "type": "integer",
- "format": "int64"
- },
- {
- "name": "name",
- "in": "formData",
- "description": "Updated name of the pet",
- "required": false,
- "type": "string"
- },
- {
- "name": "status",
- "in": "formData",
- "description": "Updated status of the pet",
- "required": false,
- "type": "string"
- }
- ],
- "responses": {
- "405": {
- "description": "Invalid input"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- },
- "delete": {
- "tags": [
- "pet"
- ],
- "summary": "Deletes a pet",
- "description": "",
- "operationId": "deletePet",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "api_key",
- "in": "header",
- "required": false,
- "type": "string"
- },
- {
- "name": "petId",
- "in": "path",
- "description": "Pet id to delete",
- "required": true,
- "type": "integer",
- "format": "int64"
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Pet not found"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- }
- },
- "/pet/{petId}/uploadImage": {
- "post": {
- "tags": [
- "pet"
- ],
- "summary": "uploads an image",
- "description": "",
- "operationId": "uploadFile",
- "consumes": [
- "multipart/form-data"
- ],
- "produces": [
- "application/json"
- ],
- "parameters": [
- {
- "name": "petId",
- "in": "path",
- "description": "ID of pet to update",
- "required": true,
- "type": "integer",
- "format": "int64"
- },
- {
- "name": "additionalMetadata",
- "in": "formData",
- "description": "Additional data to pass to server",
- "required": false,
- "type": "string"
- },
- {
- "name": "file",
- "in": "formData",
- "description": "file to upload",
- "required": false,
- "type": "file"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/ApiResponse"
- }
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- }
- },
- "/store/inventory": {
- "get": {
- "tags": [
- "store"
- ],
- "summary": "Returns pet inventories by status",
- "description": "Returns a map of status codes to quantities",
- "operationId": "getInventory",
- "produces": [
- "application/json"
- ],
- "parameters": [],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "type": "object",
- "additionalProperties": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- },
- "security": [
- {
- "api_key": []
- }
- ]
- }
- },
- "/store/order": {
- "post": {
- "tags": [
- "store"
- ],
- "summary": "Place an order for a pet",
- "description": "",
- "operationId": "placeOrder",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "order placed for purchasing the pet",
- "required": true,
- "schema": {
- "$ref": "#/definitions/Order"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/Order"
- }
- },
- "400": {
- "description": "Invalid Order"
- }
- }
- }
- },
- "/store/order/{orderId}": {
- "get": {
- "tags": [
- "store"
- ],
- "summary": "Find purchase order by ID",
- "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
- "operationId": "getOrderById",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "orderId",
- "in": "path",
- "description": "ID of pet that needs to be fetched",
- "required": true,
- "type": "integer",
- "maximum": 10.0,
- "minimum": 1.0,
- "format": "int64"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/Order"
- }
- },
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Order not found"
- }
- }
- },
- "delete": {
- "tags": [
- "store"
- ],
- "summary": "Delete purchase order by ID",
- "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
- "operationId": "deleteOrder",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "orderId",
- "in": "path",
- "description": "ID of the order that needs to be deleted",
- "required": true,
- "type": "integer",
- "minimum": 1.0,
- "format": "int64"
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Order not found"
- }
- }
- }
- },
- "/user": {
- "post": {
- "tags": [
- "user"
- ],
- "summary": "Create user",
- "description": "This can only be done by the logged in user.",
- "operationId": "createUser",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "Created user object",
- "required": true,
- "schema": {
- "$ref": "#/definitions/User"
- }
- }
- ],
- "responses": {
- "default": {
- "description": "successful operation"
- }
- }
- }
- },
- "/user/createWithArray": {
- "post": {
- "tags": [
- "user"
- ],
- "summary": "Creates list of users with given input array",
- "description": "",
- "operationId": "createUsersWithArrayInput",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "List of user object",
- "required": true,
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/User"
- }
- }
- }
- ],
- "responses": {
- "default": {
- "description": "successful operation"
- }
- }
- }
- },
- "/user/createWithList": {
- "post": {
- "tags": [
- "user"
- ],
- "summary": "Creates list of users with given input array",
- "description": "",
- "operationId": "createUsersWithListInput",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "List of user object",
- "required": true,
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/User"
- }
- }
- }
- ],
- "responses": {
- "default": {
- "description": "successful operation"
- }
- }
- }
- },
- "/user/login": {
- "get": {
- "tags": [
- "user"
- ],
- "summary": "Logs user into the system",
- "description": "",
- "operationId": "loginUser",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "username",
- "in": "query",
- "description": "The user name for login",
- "required": true,
- "type": "string"
- },
- {
- "name": "password",
- "in": "query",
- "description": "The password for login in clear text",
- "required": true,
- "type": "string"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "type": "string"
- },
- "headers": {
- "X-Rate-Limit": {
- "type": "integer",
- "format": "int32",
- "description": "calls per hour allowed by the user"
- },
- "X-Expires-After": {
- "type": "string",
- "format": "date-time",
- "description": "date in UTC when token expires"
- }
- }
- },
- "400": {
- "description": "Invalid username/password supplied"
- }
- }
- }
- },
- "/user/logout": {
- "get": {
- "tags": [
- "user"
- ],
- "summary": "Logs out current logged in user session",
- "description": "",
- "operationId": "logoutUser",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [],
- "responses": {
- "default": {
- "description": "successful operation"
- }
- }
- }
- },
- "/user/{username}": {
- "get": {
- "tags": [
- "user"
- ],
- "summary": "Get user by user name",
- "description": "",
- "operationId": "getUserByName",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "username",
- "in": "path",
- "description": "The name that needs to be fetched. Use user1 for testing. ",
- "required": true,
- "type": "string"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/User"
- }
- },
- "400": {
- "description": "Invalid username supplied"
- },
- "404": {
- "description": "User not found"
- }
- }
- },
- "put": {
- "tags": [
- "user"
- ],
- "summary": "Updated user",
- "description": "This can only be done by the logged in user.",
- "operationId": "updateUser",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "username",
- "in": "path",
- "description": "name that need to be updated",
- "required": true,
- "type": "string"
- },
- {
- "in": "body",
- "name": "body",
- "description": "Updated user object",
- "required": true,
- "schema": {
- "$ref": "#/definitions/User"
- }
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid user supplied"
- },
- "404": {
- "description": "User not found"
- }
- }
- },
- "delete": {
- "tags": [
- "user"
- ],
- "summary": "Delete user",
- "description": "This can only be done by the logged in user.",
- "operationId": "deleteUser",
- "produces": [
- "application/xml",
- "application/json"
- ],
- "parameters": [
- {
- "name": "username",
- "in": "path",
- "description": "The name that needs to be deleted",
- "required": true,
- "type": "string"
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid username supplied"
- },
- "404": {
- "description": "User not found"
- }
- }
- }
- }
- },
- "securityDefinitions": {
- "petstore_auth": {
- "type": "oauth2",
- "authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
- "flow": "implicit",
- "scopes": {
- "write:pets": "modify pets in your account",
- "read:pets": "read your pets"
- }
- },
- "api_key": {
- "type": "apiKey",
- "name": "api_key",
- "in": "header"
- }
- },
- "definitions": {
- "Order": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "petId": {
- "type": "integer",
- "format": "int64"
- },
- "quantity": {
- "type": "integer",
- "format": "int32"
- },
- "shipDate": {
- "type": "string",
- "format": "date-time"
- },
- "status": {
- "type": "string",
- "description": "Order Status",
- "enum": [
- "placed",
- "approved",
- "delivered"
- ]
- },
- "complete": {
- "type": "boolean",
- "default": false
- }
- },
- "xml": {
- "name": "Order"
- }
- },
- "Category": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "name": {
- "type": "string"
- }
- },
- "xml": {
- "name": "Category"
- }
- },
- "User": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "username": {
- "type": "string"
- },
- "firstName": {
- "type": "string"
- },
- "lastName": {
- "type": "string"
- },
- "email": {
- "type": "string"
- },
- "password": {
- "type": "string"
- },
- "phone": {
- "type": "string"
- },
- "userStatus": {
- "type": "integer",
- "format": "int32",
- "description": "User Status"
- }
- },
- "xml": {
- "name": "User"
- }
- },
- "Tag": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "name": {
- "type": "string"
- }
- },
- "xml": {
- "name": "Tag"
- }
- },
- "Pet": {
- "type": "object",
- "required": [
- "name",
- "photoUrls"
- ],
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "category": {
- "$ref": "#/definitions/Category"
- },
- "name": {
- "type": "string",
- "example": "doggie"
- },
- "photoUrls": {
- "type": "array",
- "xml": {
- "name": "photoUrl",
- "wrapped": true
- },
- "items": {
- "type": "string"
- }
- },
- "tags": {
- "type": "array",
- "xml": {
- "name": "tag",
- "wrapped": true
- },
- "items": {
- "$ref": "#/definitions/Tag"
- }
- },
- "status": {
- "type": "string",
- "description": "pet status in the store",
- "enum": [
- "available",
- "pending",
- "sold"
- ]
- }
- },
- "xml": {
- "name": "Pet"
- }
- },
- "ApiResponse": {
- "type": "object",
- "properties": {
- "code": {
- "type": "integer",
- "format": "int32"
- },
- "type": {
- "type": "string"
- },
- "message": {
- "type": "string"
- }
- }
- }
- },
- "externalDocs": {
- "description": "Find out more about Swagger",
- "url": "http://swagger.io"
- }
- },
- "valid": true
- }
- ]
- }
-]
diff --git a/jsonschema/benchmarks/json_schema_test_suite.py b/jsonschema/benchmarks/json_schema_test_suite.py
deleted file mode 100644
index 905fb6a..0000000
--- a/jsonschema/benchmarks/json_schema_test_suite.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""
-A performance benchmark using the official test suite.
-
-This benchmarks jsonschema using every valid example in the
-JSON-Schema-Test-Suite. It will take some time to complete.
-"""
-from pyperf import Runner
-
-from jsonschema.tests._suite import Suite
-
-if __name__ == "__main__":
- Suite().benchmark(runner=Runner())
diff --git a/jsonschema/cli.py b/jsonschema/cli.py
deleted file mode 100644
index f19b680..0000000
--- a/jsonschema/cli.py
+++ /dev/null
@@ -1,288 +0,0 @@
-"""
-The ``jsonschema`` command line.
-"""
-
-from json import JSONDecodeError
-from textwrap import dedent
-import argparse
-import json
-import sys
-import traceback
-
-try:
- from importlib import metadata
-except ImportError:
- import importlib_metadata as metadata # type: ignore
-
-try:
- from pkgutil import resolve_name
-except ImportError:
- from pkgutil_resolve_name import resolve_name # type: ignore
-
-import attr
-
-from jsonschema.exceptions import SchemaError
-from jsonschema.validators import RefResolver, validator_for
-
-
-class _CannotLoadFile(Exception):
- pass
-
-
-@attr.s
-class _Outputter(object):
-
- _formatter = attr.ib()
- _stdout = attr.ib()
- _stderr = attr.ib()
-
- @classmethod
- def from_arguments(cls, arguments, stdout, stderr):
- if arguments["output"] == "plain":
- formatter = _PlainFormatter(arguments["error_format"])
- elif arguments["output"] == "pretty":
- formatter = _PrettyFormatter()
- return cls(formatter=formatter, stdout=stdout, stderr=stderr)
-
- def load(self, path):
- try:
- file = open(path)
- except FileNotFoundError:
- self.filenotfound_error(path=path, exc_info=sys.exc_info())
- raise _CannotLoadFile()
-
- with file:
- try:
- return json.load(file)
- except JSONDecodeError:
- self.parsing_error(path=path, exc_info=sys.exc_info())
- raise _CannotLoadFile()
-
- def filenotfound_error(self, **kwargs):
- self._stderr.write(self._formatter.filenotfound_error(**kwargs))
-
- def parsing_error(self, **kwargs):
- self._stderr.write(self._formatter.parsing_error(**kwargs))
-
- def validation_error(self, **kwargs):
- self._stderr.write(self._formatter.validation_error(**kwargs))
-
- def validation_success(self, **kwargs):
- self._stdout.write(self._formatter.validation_success(**kwargs))
-
-
-@attr.s
-class _PrettyFormatter(object):
-
- _ERROR_MSG = dedent(
- """\
- ===[{type}]===({path})===
-
- {body}
- -----------------------------
- """,
- )
- _SUCCESS_MSG = "===[SUCCESS]===({path})===\n"
-
- def filenotfound_error(self, path, exc_info):
- return self._ERROR_MSG.format(
- path=path,
- type="FileNotFoundError",
- body="{!r} does not exist.".format(path),
- )
-
- def parsing_error(self, path, exc_info):
- exc_type, exc_value, exc_traceback = exc_info
- exc_lines = "".join(
- traceback.format_exception(exc_type, exc_value, exc_traceback),
- )
- return self._ERROR_MSG.format(
- path=path,
- type=exc_type.__name__,
- body=exc_lines,
- )
-
- def validation_error(self, instance_path, error):
- return self._ERROR_MSG.format(
- path=instance_path,
- type=error.__class__.__name__,
- body=error,
- )
-
- def validation_success(self, instance_path):
- return self._SUCCESS_MSG.format(path=instance_path)
-
-
-@attr.s
-class _PlainFormatter(object):
-
- _error_format = attr.ib()
-
- def filenotfound_error(self, path, exc_info):
- return "{!r} does not exist.\n".format(path)
-
- def parsing_error(self, path, exc_info):
- return "Failed to parse {}: {}\n".format(
- "<stdin>" if path == "<stdin>" else repr(path),
- exc_info[1],
- )
-
- def validation_error(self, instance_path, error):
- return self._error_format.format(file_name=instance_path, error=error)
-
- def validation_success(self, instance_path):
- return ""
-
-
-def _resolve_name_with_default(name):
- if "." not in name:
- name = "jsonschema." + name
- return resolve_name(name)
-
-
-parser = argparse.ArgumentParser(
- description="JSON Schema Validation CLI",
-)
-parser.add_argument(
- "-i", "--instance",
- action="append",
- dest="instances",
- help="""
- a path to a JSON instance (i.e. filename.json) to validate (may
- be specified multiple times). If no instances are provided via this
- option, one will be expected on standard input.
- """,
-)
-parser.add_argument(
- "-F", "--error-format",
- help="""
- the format to use for each validation error message, specified
- in a form suitable for str.format. This string will be passed
- one formatted object named 'error' for each ValidationError.
- Only provide this option when using --output=plain, which is the
- default. If this argument is unprovided and --output=plain is
- used, a simple default representation will be used.
- """,
-)
-parser.add_argument(
- "-o", "--output",
- choices=["plain", "pretty"],
- default="plain",
- help="""
- an output format to use. 'plain' (default) will produce minimal
- text with one line for each error, while 'pretty' will produce
- more detailed human-readable output on multiple lines.
- """,
-)
-parser.add_argument(
- "-V", "--validator",
- type=_resolve_name_with_default,
- help="""
- the fully qualified object name of a validator to use, or, for
- validators that are registered with jsonschema, simply the name
- of the class.
- """,
-)
-parser.add_argument(
- "--base-uri",
- help="""
- a base URI to assign to the provided schema, even if it does not
- declare one (via e.g. $id). This option can be used if you wish to
- resolve relative references to a particular URI (or local path)
- """,
-)
-parser.add_argument(
- "--version",
- action="version",
- version=metadata.version("jsonschema"),
-)
-parser.add_argument(
- "schema",
- help="the path to a JSON Schema to validate with (i.e. schema.json)",
-)
-
-
-def parse_args(args):
- arguments = vars(parser.parse_args(args=args or ["--help"]))
- if arguments["output"] != "plain" and arguments["error_format"]:
- raise parser.error(
- "--error-format can only be used with --output plain",
- )
- if arguments["output"] == "plain" and arguments["error_format"] is None:
- arguments["error_format"] = "{error.instance}: {error.message}\n"
- return arguments
-
-
-def _validate_instance(instance_path, instance, validator, outputter):
- invalid = False
- for error in validator.iter_errors(instance):
- invalid = True
- outputter.validation_error(instance_path=instance_path, error=error)
-
- if not invalid:
- outputter.validation_success(instance_path=instance_path)
- return invalid
-
-
-def main(args=sys.argv[1:]):
- sys.exit(run(arguments=parse_args(args=args)))
-
-
-def run(arguments, stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin):
- outputter = _Outputter.from_arguments(
- arguments=arguments,
- stdout=stdout,
- stderr=stderr,
- )
-
- try:
- schema = outputter.load(arguments["schema"])
- except _CannotLoadFile:
- return 1
-
- if arguments["validator"] is None:
- arguments["validator"] = validator_for(schema)
-
- try:
- arguments["validator"].check_schema(schema)
- except SchemaError as error:
- outputter.validation_error(
- instance_path=arguments["schema"],
- error=error,
- )
- return 1
-
- if arguments["instances"]:
- load, instances = outputter.load, arguments["instances"]
- else:
- def load(_):
- try:
- return json.load(stdin)
- except JSONDecodeError:
- outputter.parsing_error(
- path="<stdin>", exc_info=sys.exc_info(),
- )
- raise _CannotLoadFile()
- instances = ["<stdin>"]
-
- resolver = RefResolver(
- base_uri=arguments["base_uri"],
- referrer=schema,
- ) if arguments["base_uri"] is not None else None
-
- validator = arguments["validator"](schema, resolver=resolver)
- exit_code = 0
- for each in instances:
- try:
- instance = load(each)
- except _CannotLoadFile:
- exit_code = 1
- else:
- exit_code |= _validate_instance(
- instance_path=each,
- instance=instance,
- validator=validator,
- outputter=outputter,
- )
-
- return exit_code
diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py
deleted file mode 100644
index 43cb635..0000000
--- a/jsonschema/exceptions.py
+++ /dev/null
@@ -1,393 +0,0 @@
-"""
-Validation errors, and some surrounding helpers.
-"""
-from __future__ import annotations
-
-from collections import defaultdict, deque
-from pprint import pformat
-from textwrap import dedent, indent
-import heapq
-import itertools
-
-import attr
-
-from jsonschema import _utils
-
-WEAK_MATCHES: frozenset[str] = frozenset(["anyOf", "oneOf"])
-STRONG_MATCHES: frozenset[str] = frozenset()
-
-_unset = _utils.Unset()
-
-
-class _Error(Exception):
- def __init__(
- self,
- message,
- validator=_unset,
- path=(),
- cause=None,
- context=(),
- validator_value=_unset,
- instance=_unset,
- schema=_unset,
- schema_path=(),
- parent=None,
- type_checker=_unset,
- ):
- super(_Error, self).__init__(
- message,
- validator,
- path,
- cause,
- context,
- validator_value,
- instance,
- schema,
- schema_path,
- parent,
- )
- self.message = message
- self.path = self.relative_path = deque(path)
- self.schema_path = self.relative_schema_path = deque(schema_path)
- self.context = list(context)
- self.cause = self.__cause__ = cause
- self.validator = validator
- self.validator_value = validator_value
- self.instance = instance
- self.schema = schema
- self.parent = parent
- self._type_checker = type_checker
-
- for error in context:
- error.parent = self
-
- def __repr__(self):
- return f"<{self.__class__.__name__}: {self.message!r}>"
-
- def __str__(self):
- essential_for_verbose = (
- self.validator, self.validator_value, self.instance, self.schema,
- )
- if any(m is _unset for m in essential_for_verbose):
- return self.message
-
- schema_path = _utils.format_as_index(
- container=self._word_for_schema_in_error_message,
- indices=list(self.relative_schema_path)[:-1],
- )
- instance_path = _utils.format_as_index(
- container=self._word_for_instance_in_error_message,
- indices=self.relative_path,
- )
- prefix = 16 * " "
-
- return dedent(
- f"""\
- {self.message}
-
- Failed validating {self.validator!r} in {schema_path}:
- {indent(pformat(self.schema, width=72), prefix).lstrip()}
-
- On {instance_path}:
- {indent(pformat(self.instance, width=72), prefix).lstrip()}
- """.rstrip(),
- )
-
- @classmethod
- def create_from(cls, other):
- return cls(**other._contents())
-
- @property
- def absolute_path(self):
- parent = self.parent
- if parent is None:
- return self.relative_path
-
- path = deque(self.relative_path)
- path.extendleft(reversed(parent.absolute_path))
- return path
-
- @property
- def absolute_schema_path(self):
- parent = self.parent
- if parent is None:
- return self.relative_schema_path
-
- path = deque(self.relative_schema_path)
- path.extendleft(reversed(parent.absolute_schema_path))
- return path
-
- @property
- def json_path(self):
- path = "$"
- for elem in self.absolute_path:
- if isinstance(elem, int):
- path += "[" + str(elem) + "]"
- else:
- path += "." + elem
- return path
-
- def _set(self, type_checker=None, **kwargs):
- if type_checker is not None and self._type_checker is _unset:
- self._type_checker = type_checker
-
- for k, v in kwargs.items():
- if getattr(self, k) is _unset:
- setattr(self, k, v)
-
- def _contents(self):
- attrs = (
- "message", "cause", "context", "validator", "validator_value",
- "path", "schema_path", "instance", "schema", "parent",
- )
- return dict((attr, getattr(self, attr)) for attr in attrs)
-
- def _matches_type(self):
- try:
- expected = self.schema["type"]
- except (KeyError, TypeError):
- return False
-
- if isinstance(expected, str):
- return self._type_checker.is_type(self.instance, expected)
-
- return any(
- self._type_checker.is_type(self.instance, expected_type)
- for expected_type in expected
- )
-
-
-class ValidationError(_Error):
- """
- An instance was invalid under a provided schema.
- """
-
- _word_for_schema_in_error_message = "schema"
- _word_for_instance_in_error_message = "instance"
-
-
-class SchemaError(_Error):
- """
- A schema was invalid under its corresponding metaschema.
- """
-
- _word_for_schema_in_error_message = "metaschema"
- _word_for_instance_in_error_message = "schema"
-
-
-@attr.s(hash=True)
-class RefResolutionError(Exception):
- """
- A ref could not be resolved.
- """
-
- _cause = attr.ib()
-
- def __str__(self):
- return str(self._cause)
-
-
-class UndefinedTypeCheck(Exception):
- """
- A type checker was asked to check a type it did not have registered.
- """
-
- def __init__(self, type):
- self.type = type
-
- def __str__(self):
- return f"Type {self.type!r} is unknown to this type checker"
-
-
-class UnknownType(Exception):
- """
- A validator was asked to validate an instance against an unknown type.
- """
-
- def __init__(self, type, instance, schema):
- self.type = type
- self.instance = instance
- self.schema = schema
-
- def __str__(self):
- prefix = 16 * " "
-
- return dedent(
- f"""\
- Unknown type {self.type!r} for validator with schema:
- {indent(pformat(self.schema, width=72), prefix).lstrip()}
-
- While checking instance:
- {indent(pformat(self.instance, width=72), prefix).lstrip()}
- """.rstrip(),
- )
-
-
-class FormatError(Exception):
- """
- Validating a format failed.
- """
-
- def __init__(self, message, cause=None):
- super(FormatError, self).__init__(message, cause)
- self.message = message
- self.cause = self.__cause__ = cause
-
- def __str__(self):
- return self.message
-
-
-class ErrorTree(object):
- """
- ErrorTrees make it easier to check which validations failed.
- """
-
- _instance = _unset
-
- def __init__(self, errors=()):
- self.errors = {}
- self._contents = defaultdict(self.__class__)
-
- for error in errors:
- container = self
- for element in error.path:
- container = container[element]
- container.errors[error.validator] = error
-
- container._instance = error.instance
-
- def __contains__(self, index):
- """
- Check whether ``instance[index]`` has any errors.
- """
-
- return index in self._contents
-
- def __getitem__(self, index):
- """
- 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, whatever error would be raised
- by ``instance.__getitem__`` will be propagated (usually this is
- some subclass of `LookupError`.
- """
-
- if self._instance is not _unset and index not in self:
- self._instance[index]
- return self._contents[index]
-
- def __setitem__(self, index, value):
- """
- Add an error to the tree at the given ``index``.
- """
- self._contents[index] = value
-
- def __iter__(self):
- """
- Iterate (non-recursively) over the indices in the instance with errors.
- """
-
- return iter(self._contents)
-
- def __len__(self):
- """
- Return the `total_errors`.
- """
- return self.total_errors
-
- def __repr__(self):
- return f"<{self.__class__.__name__} ({len(self)} total errors)>"
-
- @property
- def total_errors(self):
- """
- The total number of errors in the entire tree, including children.
- """
-
- child_errors = sum(len(tree) for _, tree in self._contents.items())
- return len(self.errors) + child_errors
-
-
-def by_relevance(weak=WEAK_MATCHES, strong=STRONG_MATCHES):
- """
- Create a key function that can be used to sort errors by relevance.
-
- Arguments:
- weak (set):
- a collection of validator names to consider to be "weak".
- If there are two errors at the same level of the instance
- and one is in the set of weak validator names, the other
- error will take priority. By default, :validator:`anyOf` and
- :validator:`oneOf` are considered weak validators and will
- be superseded by other same-level validation errors.
-
- strong (set):
- a collection of validator names to consider to be "strong"
- """
- def relevance(error):
- validator = error.validator
- return (
- -len(error.path),
- validator not in weak,
- validator in strong,
- not error._matches_type(),
- )
- return relevance
-
-
-relevance = by_relevance()
-
-
-def best_match(errors, key=relevance):
- """
- 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
- `ValidationError.path` is shorter) are considered better matches,
- since they indicate "more" is wrong with the instance.
-
- If the resulting match is either :validator:`oneOf` or :validator:`anyOf`,
- the *opposite* assumption is made -- i.e. the deepest error is picked,
- since these validators only need to match once, and any other errors may
- not be relevant.
-
- Arguments:
- errors (collections.abc.Iterable):
-
- the errors to select from. Do not provide a mixture of
- errors from different validation attempts (i.e. from
- different instances or schemas), since it won't produce
- sensical output.
-
- key (collections.abc.Callable):
-
- the key to use when sorting errors. See `relevance` and
- transitively `by_relevance` for more details (the default is
- to sort with the defaults of that function). Changing the
- default is only useful if you want to change the function
- that rates errors but still want the error context descent
- done by this function.
-
- Returns:
- the best matching error, or ``None`` if the iterable was empty
-
- .. note::
-
- This function is a heuristic. Its return value may change for a given
- set of inputs from version to version if better heuristics are added.
- """
- errors = iter(errors)
- best = next(errors, None)
- if best is None:
- return
- best = max(itertools.chain([best], errors), key=key)
-
- while best.context:
- # Calculate the minimum via nsmallest, because we don't recurse if
- # all nested errors have the same relevance (i.e. if min == max == all)
- smallest = heapq.nsmallest(2, best.context, key=key)
- if len(smallest) == 2 and key(smallest[0]) == key(smallest[1]):
- return best
- best = smallest[0]
- return best
diff --git a/jsonschema/protocols.py b/jsonschema/protocols.py
deleted file mode 100644
index 96e3885..0000000
--- a/jsonschema/protocols.py
+++ /dev/null
@@ -1,171 +0,0 @@
-"""
-typing.Protocol classes for jsonschema interfaces.
-"""
-
-# for reference material on Protocols, see
-# https://www.python.org/dev/peps/pep-0544/
-
-from __future__ import annotations
-
-from typing import TYPE_CHECKING, Any, ClassVar, Iterator
-import sys
-
-# doing these imports with `try ... except ImportError` doesn't pass mypy
-# checking because mypy sees `typing._SpecialForm` and
-# `typing_extensions._SpecialForm` as incompatible
-#
-# see:
-# https://mypy.readthedocs.io/en/stable/runtime_troubles.html#using-new-additions-to-the-typing-module
-# https://github.com/python/mypy/issues/4427
-if sys.version_info >= (3, 8):
- from typing import Protocol, runtime_checkable
-else:
- from typing_extensions import Protocol, runtime_checkable
-
-# in order for Sphinx to resolve references accurately from type annotations,
-# it needs to see names like `jsonschema.TypeChecker`
-# therefore, only import at type-checking time (to avoid circular references),
-# but use `jsonschema` for any types which will otherwise not be resolvable
-if TYPE_CHECKING:
- import jsonschema
-
-from jsonschema.exceptions import ValidationError
-from jsonschema.validators import RefResolver
-
-# For code authors working on the validator protocol, these are the three
-# use-cases which should be kept in mind:
-#
-# 1. As a protocol class, it can be used in type annotations to describe the
-# available methods and attributes of a validator
-# 2. It is the source of autodoc for the validator documentation
-# 3. It is runtime_checkable, meaning that it can be used in isinstance()
-# checks.
-#
-# Since protocols are not base classes, isinstance() checking is limited in
-# its capabilities. See docs on runtime_checkable for detail
-
-
-@runtime_checkable
-class Validator(Protocol):
- """
- The protocol to which all validator classes should adhere.
-
- :argument schema: the schema that the validator object
- will validate with. It is assumed to be valid, and providing
- an invalid schema can lead to undefined behavior. See
- `Validator.check_schema` to validate a schema first.
- :argument resolver: an instance of `jsonschema.RefResolver` that will be
- used to resolve :validator:`$ref` properties (JSON references). If
- unprovided, one will be created.
- :argument format_checker: an instance of `jsonschema.FormatChecker`
- whose `jsonschema.FormatChecker.conforms` method will be called to
- check and see if instances conform to each :validator:`format`
- property present in the schema. If unprovided, no validation
- will be done for :validator:`format`. Certain formats require
- additional packages to be installed (ipv5, uri, color, date-time).
- The required packages can be found at the bottom of this page.
- """
-
- #: An object representing the validator's meta schema (the schema that
- #: describes valid schemas in the given version).
- META_SCHEMA: ClassVar[dict]
-
- #: A mapping of validator names (`str`\s) to functions
- #: that validate the validator property with that name. For more
- #: information see `creating-validators`.
- VALIDATORS: ClassVar[dict]
-
- #: A `jsonschema.TypeChecker` that will be used when validating
- #: :validator:`type` properties in JSON schemas.
- TYPE_CHECKER: ClassVar[jsonschema.TypeChecker]
-
- #: A `jsonschema.FormatChecker` that will be used when validating
- #: :validator:`format` properties in JSON schemas.
- FORMAT_CHECKER: ClassVar[jsonschema.FormatChecker]
-
- #: The schema that was passed in when initializing the object.
- schema: dict | bool
-
- def __init__(
- self,
- schema: dict | bool,
- resolver: RefResolver | None = None,
- format_checker: jsonschema.FormatChecker | None = None,
- ) -> None:
- ...
-
- @classmethod
- def check_schema(cls, schema: dict) -> None:
- """
- Validate the given schema against the validator's `META_SCHEMA`.
-
- :raises: `jsonschema.exceptions.SchemaError` if the schema
- is invalid
- """
-
- def is_type(self, instance: Any, type: str) -> bool:
- """
- Check if the instance is of the given (JSON Schema) type.
-
- :type type: str
- :rtype: bool
- :raises: `jsonschema.exceptions.UnknownType` if ``type``
- is not a known type.
- """
-
- def is_valid(self, instance: dict) -> bool:
- """
- Check if the instance is valid under the current `schema`.
-
- :rtype: bool
-
- >>> schema = {"maxItems" : 2}
- >>> Draft3Validator(schema).is_valid([2, 3, 4])
- False
- """
-
- def iter_errors(self, instance: dict) -> Iterator[ValidationError]:
- r"""
- Lazily yield each of the validation errors in the given instance.
-
- :rtype: an `collections.abc.Iterable` of
- `jsonschema.exceptions.ValidationError`\s
-
- >>> schema = {
- ... "type" : "array",
- ... "items" : {"enum" : [1, 2, 3]},
- ... "maxItems" : 2,
- ... }
- >>> v = Draft3Validator(schema)
- >>> for error in sorted(v.iter_errors([2, 3, 4]), key=str):
- ... print(error.message)
- 4 is not one of [1, 2, 3]
- [2, 3, 4] is too long
- """
-
- def validate(self, instance: dict) -> None:
- """
- Check if the instance is valid under the current `schema`.
-
- :raises: `jsonschema.exceptions.ValidationError` if the
- instance is invalid
-
- >>> schema = {"maxItems" : 2}
- >>> Draft3Validator(schema).validate([2, 3, 4])
- Traceback (most recent call last):
- ...
- ValidationError: [2, 3, 4] is too long
- """
-
- def evolve(self, **kwargs) -> "Validator":
- """
- Create a new validator like this one, but with given changes.
-
- Preserves all other attributes, so can be used to e.g. create a
- validator with a different schema but with the same :validator:`$ref`
- resolution behavior.
-
- >>> validator = Draft202012Validator({})
- >>> validator.evolve(schema={"type": "number"})
- Draft202012Validator(schema={'type': 'number'}, format_checker=None)
- """
diff --git a/jsonschema/schemas/draft2019-09.json b/jsonschema/schemas/draft2019-09.json
deleted file mode 100644
index 2248a0c..0000000
--- a/jsonschema/schemas/draft2019-09.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "$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/draft2020-12.json b/jsonschema/schemas/draft2020-12.json
deleted file mode 100644
index d5e2d31..0000000
--- a/jsonschema/schemas/draft2020-12.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "$schema": "https://json-schema.org/draft/2020-12/schema",
- "$id": "https://json-schema.org/draft/2020-12/schema",
- "$vocabulary": {
- "https://json-schema.org/draft/2020-12/vocab/core": true,
- "https://json-schema.org/draft/2020-12/vocab/applicator": true,
- "https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
- "https://json-schema.org/draft/2020-12/vocab/validation": true,
- "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
- "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
- "https://json-schema.org/draft/2020-12/vocab/content": true
- },
- "$dynamicAnchor": "meta",
-
- "title": "Core and Validation specifications meta-schema",
- "allOf": [
- {"$ref": "meta/core"},
- {"$ref": "meta/applicator"},
- {"$ref": "meta/unevaluated"},
- {"$ref": "meta/validation"},
- {"$ref": "meta/meta-data"},
- {"$ref": "meta/format-annotation"},
- {"$ref": "meta/content"}
- ],
- "type": ["object", "boolean"],
- "$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.",
- "properties": {
- "definitions": {
- "$comment": "\"definitions\" has been replaced by \"$defs\".",
- "type": "object",
- "additionalProperties": { "$dynamicRef": "#meta" },
- "deprecated": true,
- "default": {}
- },
- "dependencies": {
- "$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.",
- "type": "object",
- "additionalProperties": {
- "anyOf": [
- { "$dynamicRef": "#meta" },
- { "$ref": "meta/validation#/$defs/stringArray" }
- ]
- },
- "deprecated": true,
- "default": {}
- },
- "$recursiveAnchor": {
- "$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".",
- "$ref": "meta/core#/$defs/anchorString",
- "deprecated": true
- },
- "$recursiveRef": {
- "$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".",
- "$ref": "meta/core#/$defs/uriReferenceString",
- "deprecated": true
- }
- }
-}
diff --git a/jsonschema/schemas/draft3.json b/jsonschema/schemas/draft3.json
deleted file mode 100644
index 23d59b6..0000000
--- a/jsonschema/schemas/draft3.json
+++ /dev/null
@@ -1,177 +0,0 @@
-{
- "$schema" : "http://json-schema.org/draft-03/schema#",
- "id" : "http://json-schema.org/draft-03/schema#",
- "type" : "object",
-
- "properties" : {
- "type" : {
- "type" : ["string", "array"],
- "items" : {
- "type" : ["string", {"$ref" : "#"}]
- },
- "uniqueItems" : true,
- "default" : "any"
- },
-
- "properties" : {
- "type" : "object",
- "additionalProperties" : {"$ref" : "#", "type" : "object"},
- "default" : {}
- },
-
- "patternProperties" : {
- "type" : "object",
- "additionalProperties" : {"$ref" : "#"},
- "default" : {}
- },
-
- "additionalProperties" : {
- "type" : [{"$ref" : "#"}, "boolean"],
- "default" : {}
- },
-
- "items" : {
- "type" : [{"$ref" : "#"}, "array"],
- "items" : {"$ref" : "#"},
- "default" : {}
- },
-
- "additionalItems" : {
- "type" : [{"$ref" : "#"}, "boolean"],
- "default" : {}
- },
-
- "required" : {
- "type" : "boolean",
- "default" : false
- },
-
- "dependencies" : {
- "type" : ["string", "array", "object"],
- "additionalProperties" : {
- "type" : ["string", "array", {"$ref" : "#"}],
- "items" : {
- "type" : "string"
- }
- },
- "default" : {}
- },
-
- "minimum" : {
- "type" : "number"
- },
-
- "maximum" : {
- "type" : "number"
- },
-
- "exclusiveMinimum" : {
- "type" : "boolean",
- "default" : false
- },
-
- "exclusiveMaximum" : {
- "type" : "boolean",
- "default" : false
- },
-
- "maxDecimal": {
- "minimum": 0,
- "type": "number"
- },
-
- "minItems" : {
- "type" : "integer",
- "minimum" : 0,
- "default" : 0
- },
-
- "maxItems" : {
- "type" : "integer",
- "minimum" : 0
- },
-
- "uniqueItems" : {
- "type" : "boolean",
- "default" : false
- },
-
- "pattern" : {
- "type" : "string",
- "format" : "regex"
- },
-
- "minLength" : {
- "type" : "integer",
- "minimum" : 0,
- "default" : 0
- },
-
- "maxLength" : {
- "type" : "integer"
- },
-
- "enum" : {
- "type" : "array"
- },
-
- "default" : {
- "type" : "any"
- },
-
- "title" : {
- "type" : "string"
- },
-
- "description" : {
- "type" : "string"
- },
-
- "format" : {
- "type" : "string"
- },
-
- "divisibleBy" : {
- "type" : "number",
- "minimum" : 0,
- "exclusiveMinimum" : true,
- "default" : 1
- },
-
- "disallow" : {
- "type" : ["string", "array"],
- "items" : {
- "type" : ["string", {"$ref" : "#"}]
- },
- "uniqueItems" : true
- },
-
- "extends" : {
- "type" : [{"$ref" : "#"}, "array"],
- "items" : {"$ref" : "#"},
- "default" : {}
- },
-
- "id" : {
- "type" : "string",
- "format" : "uri"
- },
-
- "$ref" : {
- "type" : "string",
- "format" : "uri"
- },
-
- "$schema" : {
- "type" : "string",
- "format" : "uri"
- }
- },
-
- "dependencies" : {
- "exclusiveMinimum" : "minimum",
- "exclusiveMaximum" : "maximum"
- },
-
- "default" : {}
-}
diff --git a/jsonschema/schemas/draft4.json b/jsonschema/schemas/draft4.json
deleted file mode 100644
index ba0c117..0000000
--- a/jsonschema/schemas/draft4.json
+++ /dev/null
@@ -1,149 +0,0 @@
-{
- "id": "http://json-schema.org/draft-04/schema#",
- "$schema": "http://json-schema.org/draft-04/schema#",
- "description": "Core schema meta-schema",
- "definitions": {
- "schemaArray": {
- "type": "array",
- "minItems": 1,
- "items": { "$ref": "#" }
- },
- "positiveInteger": {
- "type": "integer",
- "minimum": 0
- },
- "positiveIntegerDefault0": {
- "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
- },
- "simpleTypes": {
- "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
- },
- "stringArray": {
- "type": "array",
- "items": { "type": "string" },
- "minItems": 1,
- "uniqueItems": true
- }
- },
- "type": "object",
- "properties": {
- "id": {
- "format": "uri",
- "type": "string"
- },
- "$schema": {
- "type": "string",
- "format": "uri"
- },
- "title": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "default": {},
- "multipleOf": {
- "type": "number",
- "minimum": 0,
- "exclusiveMinimum": true
- },
- "maximum": {
- "type": "number"
- },
- "exclusiveMaximum": {
- "type": "boolean",
- "default": false
- },
- "minimum": {
- "type": "number"
- },
- "exclusiveMinimum": {
- "type": "boolean",
- "default": false
- },
- "maxLength": { "$ref": "#/definitions/positiveInteger" },
- "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
- "pattern": {
- "type": "string",
- "format": "regex"
- },
- "additionalItems": {
- "anyOf": [
- { "type": "boolean" },
- { "$ref": "#" }
- ],
- "default": {}
- },
- "items": {
- "anyOf": [
- { "$ref": "#" },
- { "$ref": "#/definitions/schemaArray" }
- ],
- "default": {}
- },
- "maxItems": { "$ref": "#/definitions/positiveInteger" },
- "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
- "uniqueItems": {
- "type": "boolean",
- "default": false
- },
- "maxProperties": { "$ref": "#/definitions/positiveInteger" },
- "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
- "required": { "$ref": "#/definitions/stringArray" },
- "additionalProperties": {
- "anyOf": [
- { "type": "boolean" },
- { "$ref": "#" }
- ],
- "default": {}
- },
- "definitions": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "default": {}
- },
- "properties": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "default": {}
- },
- "patternProperties": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "default": {}
- },
- "dependencies": {
- "type": "object",
- "additionalProperties": {
- "anyOf": [
- { "$ref": "#" },
- { "$ref": "#/definitions/stringArray" }
- ]
- }
- },
- "enum": {
- "type": "array"
- },
- "type": {
- "anyOf": [
- { "$ref": "#/definitions/simpleTypes" },
- {
- "type": "array",
- "items": { "$ref": "#/definitions/simpleTypes" },
- "minItems": 1,
- "uniqueItems": true
- }
- ]
- },
- "format": { "type": "string" },
- "allOf": { "$ref": "#/definitions/schemaArray" },
- "anyOf": { "$ref": "#/definitions/schemaArray" },
- "oneOf": { "$ref": "#/definitions/schemaArray" },
- "not": { "$ref": "#" }
- },
- "dependencies": {
- "exclusiveMaximum": [ "maximum" ],
- "exclusiveMinimum": [ "minimum" ]
- },
- "default": {}
-}
diff --git a/jsonschema/schemas/draft6.json b/jsonschema/schemas/draft6.json
deleted file mode 100644
index a0d2bf7..0000000
--- a/jsonschema/schemas/draft6.json
+++ /dev/null
@@ -1,153 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-06/schema#",
- "$id": "http://json-schema.org/draft-06/schema#",
- "title": "Core schema meta-schema",
- "definitions": {
- "schemaArray": {
- "type": "array",
- "minItems": 1,
- "items": { "$ref": "#" }
- },
- "nonNegativeInteger": {
- "type": "integer",
- "minimum": 0
- },
- "nonNegativeIntegerDefault0": {
- "allOf": [
- { "$ref": "#/definitions/nonNegativeInteger" },
- { "default": 0 }
- ]
- },
- "simpleTypes": {
- "enum": [
- "array",
- "boolean",
- "integer",
- "null",
- "number",
- "object",
- "string"
- ]
- },
- "stringArray": {
- "type": "array",
- "items": { "type": "string" },
- "uniqueItems": true,
- "default": []
- }
- },
- "type": ["object", "boolean"],
- "properties": {
- "$id": {
- "type": "string",
- "format": "uri-reference"
- },
- "$schema": {
- "type": "string",
- "format": "uri"
- },
- "$ref": {
- "type": "string",
- "format": "uri-reference"
- },
- "title": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "default": {},
- "examples": {
- "type": "array",
- "items": {}
- },
- "multipleOf": {
- "type": "number",
- "exclusiveMinimum": 0
- },
- "maximum": {
- "type": "number"
- },
- "exclusiveMaximum": {
- "type": "number"
- },
- "minimum": {
- "type": "number"
- },
- "exclusiveMinimum": {
- "type": "number"
- },
- "maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
- "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
- "pattern": {
- "type": "string",
- "format": "regex"
- },
- "additionalItems": { "$ref": "#" },
- "items": {
- "anyOf": [
- { "$ref": "#" },
- { "$ref": "#/definitions/schemaArray" }
- ],
- "default": {}
- },
- "maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
- "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
- "uniqueItems": {
- "type": "boolean",
- "default": false
- },
- "contains": { "$ref": "#" },
- "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
- "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
- "required": { "$ref": "#/definitions/stringArray" },
- "additionalProperties": { "$ref": "#" },
- "definitions": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "default": {}
- },
- "properties": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "default": {}
- },
- "patternProperties": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "propertyNames": { "format": "regex" },
- "default": {}
- },
- "dependencies": {
- "type": "object",
- "additionalProperties": {
- "anyOf": [
- { "$ref": "#" },
- { "$ref": "#/definitions/stringArray" }
- ]
- }
- },
- "propertyNames": { "$ref": "#" },
- "const": {},
- "enum": {
- "type": "array"
- },
- "type": {
- "anyOf": [
- { "$ref": "#/definitions/simpleTypes" },
- {
- "type": "array",
- "items": { "$ref": "#/definitions/simpleTypes" },
- "minItems": 1,
- "uniqueItems": true
- }
- ]
- },
- "format": { "type": "string" },
- "allOf": { "$ref": "#/definitions/schemaArray" },
- "anyOf": { "$ref": "#/definitions/schemaArray" },
- "oneOf": { "$ref": "#/definitions/schemaArray" },
- "not": { "$ref": "#" }
- },
- "default": {}
-}
diff --git a/jsonschema/schemas/draft7.json b/jsonschema/schemas/draft7.json
deleted file mode 100644
index 746cde9..0000000
--- a/jsonschema/schemas/draft7.json
+++ /dev/null
@@ -1,166 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "$id": "http://json-schema.org/draft-07/schema#",
- "title": "Core schema meta-schema",
- "definitions": {
- "schemaArray": {
- "type": "array",
- "minItems": 1,
- "items": { "$ref": "#" }
- },
- "nonNegativeInteger": {
- "type": "integer",
- "minimum": 0
- },
- "nonNegativeIntegerDefault0": {
- "allOf": [
- { "$ref": "#/definitions/nonNegativeInteger" },
- { "default": 0 }
- ]
- },
- "simpleTypes": {
- "enum": [
- "array",
- "boolean",
- "integer",
- "null",
- "number",
- "object",
- "string"
- ]
- },
- "stringArray": {
- "type": "array",
- "items": { "type": "string" },
- "uniqueItems": true,
- "default": []
- }
- },
- "type": ["object", "boolean"],
- "properties": {
- "$id": {
- "type": "string",
- "format": "uri-reference"
- },
- "$schema": {
- "type": "string",
- "format": "uri"
- },
- "$ref": {
- "type": "string",
- "format": "uri-reference"
- },
- "$comment": {
- "type": "string"
- },
- "title": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "default": true,
- "readOnly": {
- "type": "boolean",
- "default": false
- },
- "examples": {
- "type": "array",
- "items": true
- },
- "multipleOf": {
- "type": "number",
- "exclusiveMinimum": 0
- },
- "maximum": {
- "type": "number"
- },
- "exclusiveMaximum": {
- "type": "number"
- },
- "minimum": {
- "type": "number"
- },
- "exclusiveMinimum": {
- "type": "number"
- },
- "maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
- "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
- "pattern": {
- "type": "string",
- "format": "regex"
- },
- "additionalItems": { "$ref": "#" },
- "items": {
- "anyOf": [
- { "$ref": "#" },
- { "$ref": "#/definitions/schemaArray" }
- ],
- "default": true
- },
- "maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
- "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
- "uniqueItems": {
- "type": "boolean",
- "default": false
- },
- "contains": { "$ref": "#" },
- "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
- "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
- "required": { "$ref": "#/definitions/stringArray" },
- "additionalProperties": { "$ref": "#" },
- "definitions": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "default": {}
- },
- "properties": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "default": {}
- },
- "patternProperties": {
- "type": "object",
- "additionalProperties": { "$ref": "#" },
- "propertyNames": { "format": "regex" },
- "default": {}
- },
- "dependencies": {
- "type": "object",
- "additionalProperties": {
- "anyOf": [
- { "$ref": "#" },
- { "$ref": "#/definitions/stringArray" }
- ]
- }
- },
- "propertyNames": { "$ref": "#" },
- "const": true,
- "enum": {
- "type": "array",
- "items": true
- },
- "type": {
- "anyOf": [
- { "$ref": "#/definitions/simpleTypes" },
- {
- "type": "array",
- "items": { "$ref": "#/definitions/simpleTypes" },
- "minItems": 1,
- "uniqueItems": true
- }
- ]
- },
- "format": { "type": "string" },
- "contentMediaType": { "type": "string" },
- "contentEncoding": { "type": "string" },
- "if": {"$ref": "#"},
- "then": {"$ref": "#"},
- "else": {"$ref": "#"},
- "allOf": { "$ref": "#/definitions/schemaArray" },
- "anyOf": { "$ref": "#/definitions/schemaArray" },
- "oneOf": { "$ref": "#/definitions/schemaArray" },
- "not": { "$ref": "#" }
- },
- "default": true
-}
diff --git a/jsonschema/schemas/vocabularies.json b/jsonschema/schemas/vocabularies.json
deleted file mode 100644
index bca1705..0000000
--- a/jsonschema/schemas/vocabularies.json
+++ /dev/null
@@ -1 +0,0 @@
-{"https://json-schema.org/draft/2020-12/meta/content": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/content", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/content": true}, "$dynamicAnchor": "meta", "title": "Content vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"contentEncoding": {"type": "string"}, "contentMediaType": {"type": "string"}, "contentSchema": {"$dynamicRef": "#meta"}}}, "https://json-schema.org/draft/2020-12/meta/unevaluated": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/unevaluated", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/unevaluated": true}, "$dynamicAnchor": "meta", "title": "Unevaluated applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"unevaluatedItems": {"$dynamicRef": "#meta"}, "unevaluatedProperties": {"$dynamicRef": "#meta"}}}, "https://json-schema.org/draft/2020-12/meta/format-annotation": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/format-annotation", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/format-annotation": true}, "$dynamicAnchor": "meta", "title": "Format vocabulary meta-schema for annotation results", "type": ["object", "boolean"], "properties": {"format": {"type": "string"}}}, "https://json-schema.org/draft/2020-12/meta/applicator": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/applicator", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/applicator": true}, "$dynamicAnchor": "meta", "title": "Applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"prefixItems": {"$ref": "#/$defs/schemaArray"}, "items": {"$dynamicRef": "#meta"}, "contains": {"$dynamicRef": "#meta"}, "additionalProperties": {"$dynamicRef": "#meta"}, "properties": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}, "default": {}}, "patternProperties": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}, "propertyNames": {"format": "regex"}, "default": {}}, "dependentSchemas": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}, "default": {}}, "propertyNames": {"$dynamicRef": "#meta"}, "if": {"$dynamicRef": "#meta"}, "then": {"$dynamicRef": "#meta"}, "else": {"$dynamicRef": "#meta"}, "allOf": {"$ref": "#/$defs/schemaArray"}, "anyOf": {"$ref": "#/$defs/schemaArray"}, "oneOf": {"$ref": "#/$defs/schemaArray"}, "not": {"$dynamicRef": "#meta"}}, "$defs": {"schemaArray": {"type": "array", "minItems": 1, "items": {"$dynamicRef": "#meta"}}}}, "https://json-schema.org/draft/2020-12/meta/meta-data": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/meta-data", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/meta-data": true}, "$dynamicAnchor": "meta", "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}}}, "https://json-schema.org/draft/2020-12/meta/core": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/core", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/core": true}, "$dynamicAnchor": "meta", "title": "Core vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"$id": {"$ref": "#/$defs/uriReferenceString", "$comment": "Non-empty fragments not allowed.", "pattern": "^[^#]*#?$"}, "$schema": {"$ref": "#/$defs/uriString"}, "$ref": {"$ref": "#/$defs/uriReferenceString"}, "$anchor": {"$ref": "#/$defs/anchorString"}, "$dynamicRef": {"$ref": "#/$defs/uriReferenceString"}, "$dynamicAnchor": {"$ref": "#/$defs/anchorString"}, "$vocabulary": {"type": "object", "propertyNames": {"$ref": "#/$defs/uriString"}, "additionalProperties": {"type": "boolean"}}, "$comment": {"type": "string"}, "$defs": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}}}, "$defs": {"anchorString": {"type": "string", "pattern": "^[A-Za-z_][-A-Za-z0-9._]*$"}, "uriString": {"type": "string", "format": "uri"}, "uriReferenceString": {"type": "string", "format": "uri-reference"}}}, "https://json-schema.org/draft/2020-12/meta/validation": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/validation", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/validation": true}, "$dynamicAnchor": "meta", "title": "Validation vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"type": {"anyOf": [{"$ref": "#/$defs/simpleTypes"}, {"type": "array", "items": {"$ref": "#/$defs/simpleTypes"}, "minItems": 1, "uniqueItems": true}]}, "const": true, "enum": {"type": "array", "items": true}, "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"}}}, "$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": []}}}, "https://json-schema.org/draft/2019-09/meta/content": {"$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": "#"}}}, "https://json-schema.org/draft/2019-09/meta/applicator": {"$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": "#"}}}}, "https://json-schema.org/draft/2019-09/meta/meta-data": {"$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}}}, "https://json-schema.org/draft/2019-09/meta/core": {"$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": {}}}}, "https://json-schema.org/draft/2019-09/meta/validation": {"$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": []}}}, "https://json-schema.org/draft/2019-09/meta/hyper-schema": {"$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}"}]}, "https://json-schema.org/draft/2019-09/meta/format": {"$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/tests/__init__.py b/jsonschema/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/jsonschema/tests/__init__.py
+++ /dev/null
diff --git a/jsonschema/tests/_helpers.py b/jsonschema/tests/_helpers.py
deleted file mode 100644
index 70f291f..0000000
--- a/jsonschema/tests/_helpers.py
+++ /dev/null
@@ -1,5 +0,0 @@
-def bug(issue=None):
- message = "A known bug."
- if issue is not None:
- message += " See issue #{issue}.".format(issue=issue)
- return message
diff --git a/jsonschema/tests/_suite.py b/jsonschema/tests/_suite.py
deleted file mode 100644
index 61a8fc8..0000000
--- a/jsonschema/tests/_suite.py
+++ /dev/null
@@ -1,231 +0,0 @@
-"""
-Python representations of the JSON Schema Test Suite tests.
-"""
-
-from functools import partial
-from pathlib import Path
-import json
-import os
-import re
-import subprocess
-import sys
-import unittest
-
-import attr
-
-from jsonschema.validators import _VALIDATORS
-import jsonschema
-
-
-def _find_suite():
- root = os.environ.get("JSON_SCHEMA_TEST_SUITE")
- if root is not None:
- return Path(root)
-
- root = Path(jsonschema.__file__).parent.parent / "json"
- if not root.is_dir(): # pragma: no cover
- raise ValueError(
- (
- "Can't find the JSON-Schema-Test-Suite directory. "
- "Set the 'JSON_SCHEMA_TEST_SUITE' environment "
- "variable or run the tests from alongside a checkout "
- "of the suite."
- ),
- )
- return root
-
-
-@attr.s(hash=True)
-class Suite(object):
-
- _root = attr.ib(default=attr.Factory(_find_suite))
-
- def _remotes(self):
- jsonschema_suite = self._root.joinpath("bin", "jsonschema_suite")
- remotes = subprocess.check_output(
- [sys.executable, str(jsonschema_suite), "remotes"],
- )
- return {
- "http://localhost:1234/" + name.replace("\\", "/"): schema
- for name, schema in json.loads(remotes.decode("utf-8")).items()
- }
-
- def benchmark(self, runner): # pragma: no cover
- for name, Validator in _VALIDATORS.items():
- self.version(name=name).benchmark(
- runner=runner,
- Validator=Validator,
- )
-
- def version(self, name):
- return Version(
- name=name,
- path=self._root.joinpath("tests", name),
- remotes=self._remotes(),
- )
-
-
-@attr.s(hash=True)
-class Version(object):
-
- _path = attr.ib()
- _remotes = attr.ib()
-
- name = attr.ib()
-
- def benchmark(self, runner, **kwargs): # pragma: no cover
- for suite in self.tests():
- for test in suite:
- runner.bench_func(
- test.fully_qualified_name,
- partial(test.validate_ignoring_errors, **kwargs),
- )
-
- def tests(self):
- return (
- test
- for child in self._path.glob("*.json")
- for test in self._tests_in(
- subject=child.name[:-5],
- path=child,
- )
- )
-
- def format_tests(self):
- path = self._path.joinpath("optional", "format")
- return (
- test
- for child in path.glob("*.json")
- for test in self._tests_in(
- subject=child.name[:-5],
- path=child,
- )
- )
-
- def optional_tests_of(self, name):
- return self._tests_in(
- subject=name,
- path=self._path.joinpath("optional", name + ".json"),
- )
-
- def to_unittest_testcase(self, *suites, **kwargs):
- name = kwargs.pop("name", "Test" + self.name.title().replace("-", ""))
- methods = {
- test.method_name: test.to_unittest_method(**kwargs)
- for suite in suites
- for tests in suite
- for test in tests
- }
- cls = type(name, (unittest.TestCase,), methods)
-
- try:
- cls.__module__ = _someone_save_us_the_module_of_the_caller()
- except Exception: # pragma: no cover
- # We're doing crazy things, so if they go wrong, like a function
- # behaving differently on some other interpreter, just make them
- # not happen.
- pass
-
- return cls
-
- def _tests_in(self, subject, path):
- for each in json.loads(path.read_text(encoding="utf-8")):
- yield (
- _Test(
- version=self,
- subject=subject,
- case_description=each["description"],
- schema=each["schema"],
- remotes=self._remotes,
- **test,
- ) for test in each["tests"]
- )
-
-
-@attr.s(hash=True, repr=False)
-class _Test(object):
-
- version = attr.ib()
-
- subject = attr.ib()
- case_description = attr.ib()
- description = attr.ib()
-
- data = attr.ib()
- schema = attr.ib(repr=False)
-
- valid = attr.ib()
-
- _remotes = attr.ib()
-
- comment = attr.ib(default=None)
-
- def __repr__(self): # pragma: no cover
- return "<Test {}>".format(self.fully_qualified_name)
-
- @property
- def fully_qualified_name(self): # pragma: no cover
- return " > ".join(
- [
- self.version.name,
- self.subject,
- self.case_description,
- self.description,
- ],
- )
-
- @property
- def method_name(self):
- delimiters = r"[\W\- ]+"
- return "test_{}_{}_{}".format(
- re.sub(delimiters, "_", self.subject),
- re.sub(delimiters, "_", self.case_description),
- re.sub(delimiters, "_", self.description),
- )
-
- def to_unittest_method(self, skip=lambda test: None, **kwargs):
- if self.valid:
- def fn(this):
- self.validate(**kwargs)
- else:
- def fn(this):
- with this.assertRaises(jsonschema.ValidationError):
- self.validate(**kwargs)
-
- fn.__name__ = self.method_name
- reason = skip(self)
- return unittest.skipIf(reason is not None, reason)(fn)
-
- def validate(self, Validator, **kwargs):
- Validator.check_schema(self.schema)
- resolver = jsonschema.RefResolver.from_schema(
- schema=self.schema,
- store=self._remotes,
- id_of=Validator.ID_OF,
- )
- validator = Validator(schema=self.schema, resolver=resolver, **kwargs)
- if os.environ.get("JSON_SCHEMA_DEBUG", "0") != "0":
- breakpoint()
- validator.validate(instance=self.data)
-
- def validate_ignoring_errors(self, Validator): # pragma: no cover
- try:
- self.validate(Validator=Validator)
- except jsonschema.ValidationError:
- pass
-
-
-def _someone_save_us_the_module_of_the_caller():
- """
- The FQON of the module 2nd stack frames up from here.
-
- This is intended to allow us to dynamically return test case classes that
- are indistinguishable from being defined in the module that wants them.
-
- Otherwise, trial will mis-print the FQON, and copy pasting it won't re-run
- the class that really is running.
-
- Save us all, this is all so so so so so terrible.
- """
-
- return sys._getframe(2).f_globals["__name__"]
diff --git a/jsonschema/tests/fuzz_validate.py b/jsonschema/tests/fuzz_validate.py
deleted file mode 100644
index c12e88b..0000000
--- a/jsonschema/tests/fuzz_validate.py
+++ /dev/null
@@ -1,50 +0,0 @@
-"""
-Fuzzing setup for OSS-Fuzz.
-
-See https://github.com/google/oss-fuzz/tree/master/projects/jsonschema for the
-other half of the setup here.
-"""
-import sys
-
-from hypothesis import given, strategies
-
-import jsonschema
-
-PRIM = strategies.one_of(
- strategies.booleans(),
- strategies.integers(),
- strategies.floats(allow_nan=False, allow_infinity=False),
- strategies.text(),
-)
-DICT = strategies.recursive(
- base=strategies.one_of(
- strategies.booleans(),
- strategies.dictionaries(strategies.text(), PRIM),
- ),
- extend=lambda inner: strategies.dictionaries(strategies.text(), inner),
-)
-
-
-@given(obj1=DICT, obj2=DICT)
-def test_schemas(obj1, obj2):
- try:
- jsonschema.validate(instance=obj1, schema=obj2)
- except jsonschema.exceptions.ValidationError:
- pass
- except jsonschema.exceptions.SchemaError:
- pass
-
-
-def main():
- atheris.instrument_all()
- atheris.Setup(
- sys.argv,
- test_schemas.hypothesis.fuzz_one_input,
- enable_python_coverage=True,
- )
- atheris.Fuzz()
-
-
-if __name__ == "__main__":
- import atheris
- main()
diff --git a/jsonschema/tests/test_cli.py b/jsonschema/tests/test_cli.py
deleted file mode 100644
index 6d42af6..0000000
--- a/jsonschema/tests/test_cli.py
+++ /dev/null
@@ -1,911 +0,0 @@
-from contextlib import redirect_stderr, redirect_stdout
-from io import StringIO
-from json import JSONDecodeError
-from pathlib import Path
-from textwrap import dedent
-from unittest import TestCase
-import json
-import os
-import subprocess
-import sys
-import tempfile
-
-try: # pragma: no cover
- from importlib import metadata
-except ImportError: # pragma: no cover
- import importlib_metadata as metadata # type: ignore
-
-from pyrsistent import m
-
-from jsonschema import Draft4Validator, Draft202012Validator, cli
-from jsonschema.exceptions import (
- RefResolutionError,
- SchemaError,
- ValidationError,
-)
-from jsonschema.validators import _LATEST_VERSION, validate
-
-
-def fake_validator(*errors):
- errors = list(reversed(errors))
-
- class FakeValidator(object):
- def __init__(self, *args, **kwargs):
- pass
-
- def iter_errors(self, instance):
- if errors:
- return errors.pop()
- return [] # pragma: no cover
-
- @classmethod
- def check_schema(self, schema):
- pass
-
- return FakeValidator
-
-
-def fake_open(all_contents):
- def open(path):
- contents = all_contents.get(path)
- if contents is None:
- raise FileNotFoundError(path)
- return StringIO(contents)
- return open
-
-
-def _message_for(non_json):
- try:
- json.loads(non_json)
- except JSONDecodeError as error:
- return str(error)
- else: # pragma: no cover
- raise RuntimeError("Tried and failed to capture a JSON dump error.")
-
-
-class TestCLI(TestCase):
- def run_cli(
- self, argv, files=m(), stdin=StringIO(), exit_code=0, **override,
- ):
- arguments = cli.parse_args(argv)
- arguments.update(override)
-
- self.assertFalse(hasattr(cli, "open"))
- cli.open = fake_open(files)
- try:
- stdout, stderr = StringIO(), StringIO()
- actual_exit_code = cli.run(
- arguments,
- stdin=stdin,
- stdout=stdout,
- stderr=stderr,
- )
- finally:
- del cli.open
-
- self.assertEqual(
- actual_exit_code, exit_code, msg=dedent(
- """
- Expected an exit code of {} != {}.
-
- stdout: {}
-
- stderr: {}
- """.format(
- exit_code,
- actual_exit_code,
- stdout.getvalue(),
- stderr.getvalue(),
- ),
- ),
- )
- return stdout.getvalue(), stderr.getvalue()
-
- def assertOutputs(self, stdout="", stderr="", **kwargs):
- self.assertEqual(
- self.run_cli(**kwargs),
- (dedent(stdout), dedent(stderr)),
- )
-
- def test_invalid_instance(self):
- error = ValidationError("I am an error!", instance=12)
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_instance=json.dumps(error.instance),
- ),
- validator=fake_validator([error]),
-
- argv=["-i", "some_instance", "some_schema"],
-
- exit_code=1,
- stderr="12: I am an error!\n",
- )
-
- def test_invalid_instance_pretty_output(self):
- error = ValidationError("I am an error!", instance=12)
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_instance=json.dumps(error.instance),
- ),
- validator=fake_validator([error]),
-
- argv=["-i", "some_instance", "--output", "pretty", "some_schema"],
-
- exit_code=1,
- stderr="""\
- ===[ValidationError]===(some_instance)===
-
- I am an error!
- -----------------------------
- """,
- )
-
- def test_invalid_instance_explicit_plain_output(self):
- error = ValidationError("I am an error!", instance=12)
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_instance=json.dumps(error.instance),
- ),
- validator=fake_validator([error]),
-
- argv=["--output", "plain", "-i", "some_instance", "some_schema"],
-
- exit_code=1,
- stderr="12: I am an error!\n",
- )
-
- def test_invalid_instance_multiple_errors(self):
- instance = 12
- first = ValidationError("First error", instance=instance)
- second = ValidationError("Second error", instance=instance)
-
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_instance=json.dumps(instance),
- ),
- validator=fake_validator([first, second]),
-
- argv=["-i", "some_instance", "some_schema"],
-
- exit_code=1,
- stderr="""\
- 12: First error
- 12: Second error
- """,
- )
-
- def test_invalid_instance_multiple_errors_pretty_output(self):
- instance = 12
- first = ValidationError("First error", instance=instance)
- second = ValidationError("Second error", instance=instance)
-
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_instance=json.dumps(instance),
- ),
- validator=fake_validator([first, second]),
-
- argv=["-i", "some_instance", "--output", "pretty", "some_schema"],
-
- exit_code=1,
- stderr="""\
- ===[ValidationError]===(some_instance)===
-
- First error
- -----------------------------
- ===[ValidationError]===(some_instance)===
-
- Second error
- -----------------------------
- """,
- )
-
- def test_multiple_invalid_instances(self):
- first_instance = 12
- first_errors = [
- ValidationError("An error", instance=first_instance),
- ValidationError("Another error", instance=first_instance),
- ]
- second_instance = "foo"
- second_errors = [ValidationError("BOOM", instance=second_instance)]
-
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_first_instance=json.dumps(first_instance),
- some_second_instance=json.dumps(second_instance),
- ),
- validator=fake_validator(first_errors, second_errors),
-
- argv=[
- "-i", "some_first_instance",
- "-i", "some_second_instance",
- "some_schema",
- ],
-
- exit_code=1,
- stderr="""\
- 12: An error
- 12: Another error
- foo: BOOM
- """,
- )
-
- def test_multiple_invalid_instances_pretty_output(self):
- first_instance = 12
- first_errors = [
- ValidationError("An error", instance=first_instance),
- ValidationError("Another error", instance=first_instance),
- ]
- second_instance = "foo"
- second_errors = [ValidationError("BOOM", instance=second_instance)]
-
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_first_instance=json.dumps(first_instance),
- some_second_instance=json.dumps(second_instance),
- ),
- validator=fake_validator(first_errors, second_errors),
-
- argv=[
- "--output", "pretty",
- "-i", "some_first_instance",
- "-i", "some_second_instance",
- "some_schema",
- ],
-
- exit_code=1,
- stderr="""\
- ===[ValidationError]===(some_first_instance)===
-
- An error
- -----------------------------
- ===[ValidationError]===(some_first_instance)===
-
- Another error
- -----------------------------
- ===[ValidationError]===(some_second_instance)===
-
- BOOM
- -----------------------------
- """,
- )
-
- def test_custom_error_format(self):
- first_instance = 12
- first_errors = [
- ValidationError("An error", instance=first_instance),
- ValidationError("Another error", instance=first_instance),
- ]
- second_instance = "foo"
- second_errors = [ValidationError("BOOM", instance=second_instance)]
-
- self.assertOutputs(
- files=dict(
- some_schema='{"does not": "matter since it is stubbed"}',
- some_first_instance=json.dumps(first_instance),
- some_second_instance=json.dumps(second_instance),
- ),
- validator=fake_validator(first_errors, second_errors),
-
- argv=[
- "--error-format", ":{error.message}._-_.{error.instance}:",
- "-i", "some_first_instance",
- "-i", "some_second_instance",
- "some_schema",
- ],
-
- exit_code=1,
- stderr=":An error._-_.12::Another error._-_.12::BOOM._-_.foo:",
- )
-
- def test_invalid_schema(self):
- self.assertOutputs(
- files=dict(some_schema='{"type": 12}'),
- argv=["some_schema"],
-
- exit_code=1,
- stderr="""\
- 12: 12 is not valid under any of the given schemas
- """,
- )
-
- def test_invalid_schema_pretty_output(self):
- schema = {"type": 12}
-
- with self.assertRaises(SchemaError) as e:
- validate(schema=schema, instance="")
- error = str(e.exception)
-
- self.assertOutputs(
- files=dict(some_schema=json.dumps(schema)),
- argv=["--output", "pretty", "some_schema"],
-
- exit_code=1,
- stderr=(
- "===[SchemaError]===(some_schema)===\n\n"
- + str(error)
- + "\n-----------------------------\n"
- ),
- )
-
- def test_invalid_schema_multiple_errors(self):
- self.assertOutputs(
- files=dict(some_schema='{"type": 12, "items": 57}'),
- argv=["some_schema"],
-
- exit_code=1,
- stderr="""\
- 57: 57 is not of type 'object', 'boolean'
- """,
- )
-
- def test_invalid_schema_multiple_errors_pretty_output(self):
- schema = {"type": 12, "items": 57}
-
- with self.assertRaises(SchemaError) as e:
- validate(schema=schema, instance="")
- error = str(e.exception)
-
- self.assertOutputs(
- files=dict(some_schema=json.dumps(schema)),
- argv=["--output", "pretty", "some_schema"],
-
- exit_code=1,
- stderr=(
- "===[SchemaError]===(some_schema)===\n\n"
- + str(error)
- + "\n-----------------------------\n"
- ),
- )
-
- def test_invalid_schema_with_invalid_instance(self):
- """
- "Validating" an instance that's invalid under an invalid schema
- just shows the schema error.
- """
- self.assertOutputs(
- files=dict(
- some_schema='{"type": 12, "minimum": 30}',
- some_instance="13",
- ),
- argv=["-i", "some_instance", "some_schema"],
-
- exit_code=1,
- stderr="""\
- 12: 12 is not valid under any of the given schemas
- """,
- )
-
- def test_invalid_schema_with_invalid_instance_pretty_output(self):
- instance, schema = 13, {"type": 12, "minimum": 30}
-
- with self.assertRaises(SchemaError) as e:
- validate(schema=schema, instance=instance)
- error = str(e.exception)
-
- self.assertOutputs(
- files=dict(
- some_schema=json.dumps(schema),
- some_instance=json.dumps(instance),
- ),
- argv=["--output", "pretty", "-i", "some_instance", "some_schema"],
-
- exit_code=1,
- stderr=(
- "===[SchemaError]===(some_schema)===\n\n"
- + str(error)
- + "\n-----------------------------\n"
- ),
- )
-
- def test_invalid_instance_continues_with_the_rest(self):
- self.assertOutputs(
- files=dict(
- some_schema='{"minimum": 30}',
- first_instance="not valid JSON!",
- second_instance="12",
- ),
- argv=[
- "-i", "first_instance",
- "-i", "second_instance",
- "some_schema",
- ],
-
- exit_code=1,
- stderr="""\
- Failed to parse 'first_instance': {}
- 12: 12 is less than the minimum of 30
- """.format(_message_for("not valid JSON!")),
- )
-
- def test_custom_error_format_applies_to_schema_errors(self):
- instance, schema = 13, {"type": 12, "minimum": 30}
-
- with self.assertRaises(SchemaError):
- validate(schema=schema, instance=instance)
-
- self.assertOutputs(
- files=dict(some_schema=json.dumps(schema)),
-
- argv=[
- "--error-format", ":{error.message}._-_.{error.instance}:",
- "some_schema",
- ],
-
- exit_code=1,
- stderr=":12 is not valid under any of the given schemas._-_.12:",
- )
-
- def test_instance_is_invalid_JSON(self):
- instance = "not valid JSON!"
-
- self.assertOutputs(
- files=dict(some_schema="{}", some_instance=instance),
- argv=["-i", "some_instance", "some_schema"],
-
- exit_code=1,
- stderr="""\
- Failed to parse 'some_instance': {}
- """.format(_message_for(instance)),
- )
-
- def test_instance_is_invalid_JSON_pretty_output(self):
- stdout, stderr = self.run_cli(
- files=dict(
- some_schema="{}",
- some_instance="not valid JSON!",
- ),
-
- argv=["--output", "pretty", "-i", "some_instance", "some_schema"],
-
- exit_code=1,
- )
- self.assertFalse(stdout)
- self.assertIn(
- "(some_instance)===\n\nTraceback (most recent call last):\n",
- stderr,
- )
- self.assertNotIn("some_schema", stderr)
-
- def test_instance_is_invalid_JSON_on_stdin(self):
- instance = "not valid JSON!"
-
- self.assertOutputs(
- files=dict(some_schema="{}"),
- stdin=StringIO(instance),
-
- argv=["some_schema"],
-
- exit_code=1,
- stderr="""\
- Failed to parse <stdin>: {}
- """.format(_message_for(instance)),
- )
-
- def test_instance_is_invalid_JSON_on_stdin_pretty_output(self):
- stdout, stderr = self.run_cli(
- files=dict(some_schema="{}"),
- stdin=StringIO("not valid JSON!"),
-
- argv=["--output", "pretty", "some_schema"],
-
- exit_code=1,
- )
- self.assertFalse(stdout)
- self.assertIn(
- "(<stdin>)===\n\nTraceback (most recent call last):\n",
- stderr,
- )
- self.assertNotIn("some_schema", stderr)
-
- def test_schema_is_invalid_JSON(self):
- schema = "not valid JSON!"
-
- self.assertOutputs(
- files=dict(some_schema=schema),
-
- argv=["some_schema"],
-
- exit_code=1,
- stderr="""\
- Failed to parse 'some_schema': {}
- """.format(_message_for(schema)),
- )
-
- def test_schema_is_invalid_JSON_pretty_output(self):
- stdout, stderr = self.run_cli(
- files=dict(some_schema="not valid JSON!"),
-
- argv=["--output", "pretty", "some_schema"],
-
- exit_code=1,
- )
- self.assertFalse(stdout)
- self.assertIn(
- "(some_schema)===\n\nTraceback (most recent call last):\n",
- stderr,
- )
-
- def test_schema_and_instance_are_both_invalid_JSON(self):
- """
- Only the schema error is reported, as we abort immediately.
- """
- schema, instance = "not valid JSON!", "also not valid JSON!"
- self.assertOutputs(
- files=dict(some_schema=schema, some_instance=instance),
-
- argv=["some_schema"],
-
- exit_code=1,
- stderr="""\
- Failed to parse 'some_schema': {}
- """.format(_message_for(schema)),
- )
-
- def test_schema_and_instance_are_both_invalid_JSON_pretty_output(self):
- """
- Only the schema error is reported, as we abort immediately.
- """
- stdout, stderr = self.run_cli(
- files=dict(
- some_schema="not valid JSON!",
- some_instance="also not valid JSON!",
- ),
-
- argv=["--output", "pretty", "-i", "some_instance", "some_schema"],
-
- exit_code=1,
- )
- self.assertFalse(stdout)
- self.assertIn(
- "(some_schema)===\n\nTraceback (most recent call last):\n",
- stderr,
- )
- self.assertNotIn("some_instance", stderr)
-
- def test_instance_does_not_exist(self):
- self.assertOutputs(
- files=dict(some_schema="{}"),
- argv=["-i", "nonexisting_instance", "some_schema"],
-
- exit_code=1,
- stderr="""\
- 'nonexisting_instance' does not exist.
- """,
- )
-
- def test_instance_does_not_exist_pretty_output(self):
- self.assertOutputs(
- files=dict(some_schema="{}"),
- argv=[
- "--output", "pretty",
- "-i", "nonexisting_instance",
- "some_schema",
- ],
-
- exit_code=1,
- stderr="""\
- ===[FileNotFoundError]===(nonexisting_instance)===
-
- 'nonexisting_instance' does not exist.
- -----------------------------
- """,
- )
-
- def test_schema_does_not_exist(self):
- self.assertOutputs(
- argv=["nonexisting_schema"],
-
- exit_code=1,
- stderr="'nonexisting_schema' does not exist.\n",
- )
-
- def test_schema_does_not_exist_pretty_output(self):
- self.assertOutputs(
- argv=["--output", "pretty", "nonexisting_schema"],
-
- exit_code=1,
- stderr="""\
- ===[FileNotFoundError]===(nonexisting_schema)===
-
- 'nonexisting_schema' does not exist.
- -----------------------------
- """,
- )
-
- def test_neither_instance_nor_schema_exist(self):
- self.assertOutputs(
- argv=["-i", "nonexisting_instance", "nonexisting_schema"],
-
- exit_code=1,
- stderr="'nonexisting_schema' does not exist.\n",
- )
-
- def test_neither_instance_nor_schema_exist_pretty_output(self):
- self.assertOutputs(
- argv=[
- "--output", "pretty",
- "-i", "nonexisting_instance",
- "nonexisting_schema",
- ],
-
- exit_code=1,
- stderr="""\
- ===[FileNotFoundError]===(nonexisting_schema)===
-
- 'nonexisting_schema' does not exist.
- -----------------------------
- """,
- )
-
- def test_successful_validation(self):
- self.assertOutputs(
- files=dict(some_schema="{}", some_instance="{}"),
- argv=["-i", "some_instance", "some_schema"],
- stdout="",
- stderr="",
- )
-
- def test_successful_validation_pretty_output(self):
- self.assertOutputs(
- files=dict(some_schema="{}", some_instance="{}"),
- argv=["--output", "pretty", "-i", "some_instance", "some_schema"],
- stdout="===[SUCCESS]===(some_instance)===\n",
- stderr="",
- )
-
- def test_successful_validation_of_stdin(self):
- self.assertOutputs(
- files=dict(some_schema="{}"),
- stdin=StringIO("{}"),
- argv=["some_schema"],
- stdout="",
- stderr="",
- )
-
- def test_successful_validation_of_stdin_pretty_output(self):
- self.assertOutputs(
- files=dict(some_schema="{}"),
- stdin=StringIO("{}"),
- argv=["--output", "pretty", "some_schema"],
- stdout="===[SUCCESS]===(<stdin>)===\n",
- stderr="",
- )
-
- def test_successful_validation_of_just_the_schema(self):
- self.assertOutputs(
- files=dict(some_schema="{}", some_instance="{}"),
- argv=["-i", "some_instance", "some_schema"],
- stdout="",
- stderr="",
- )
-
- def test_successful_validation_of_just_the_schema_pretty_output(self):
- self.assertOutputs(
- files=dict(some_schema="{}", some_instance="{}"),
- argv=["--output", "pretty", "-i", "some_instance", "some_schema"],
- stdout="===[SUCCESS]===(some_instance)===\n",
- stderr="",
- )
-
- def test_successful_validation_via_explicit_base_uri(self):
- ref_schema_file = tempfile.NamedTemporaryFile(delete=False)
- self.addCleanup(os.remove, ref_schema_file.name)
-
- ref_path = Path(ref_schema_file.name)
- ref_path.write_text('{"definitions": {"num": {"type": "integer"}}}')
-
- schema = f'{{"$ref": "{ref_path.name}#definitions/num"}}'
-
- self.assertOutputs(
- files=dict(some_schema=schema, some_instance="1"),
- argv=[
- "-i", "some_instance",
- "--base-uri", ref_path.parent.as_uri() + "/",
- "some_schema",
- ],
- stdout="",
- stderr="",
- )
-
- def test_unsuccessful_validation_via_explicit_base_uri(self):
- ref_schema_file = tempfile.NamedTemporaryFile(delete=False)
- self.addCleanup(os.remove, ref_schema_file.name)
-
- ref_path = Path(ref_schema_file.name)
- ref_path.write_text('{"definitions": {"num": {"type": "integer"}}}')
-
- schema = f'{{"$ref": "{ref_path.name}#definitions/num"}}'
-
- self.assertOutputs(
- files=dict(some_schema=schema, some_instance='"1"'),
- argv=[
- "-i", "some_instance",
- "--base-uri", ref_path.parent.as_uri() + "/",
- "some_schema",
- ],
- exit_code=1,
- stdout="",
- stderr="1: '1' is not of type 'integer'\n",
- )
-
- def test_nonexistent_file_with_explicit_base_uri(self):
- schema = '{"$ref": "someNonexistentFile.json#definitions/num"}'
- instance = "1"
-
- with self.assertRaises(RefResolutionError) as e:
- self.assertOutputs(
- files=dict(
- some_schema=schema,
- some_instance=instance,
- ),
- argv=[
- "-i", "some_instance",
- "--base-uri", Path.cwd().as_uri(),
- "some_schema",
- ],
- )
- error = str(e.exception)
- self.assertIn(f"{os.sep}someNonexistentFile.json'", error)
-
- def test_invalid_exlicit_base_uri(self):
- schema = '{"$ref": "foo.json#definitions/num"}'
- instance = "1"
-
- with self.assertRaises(RefResolutionError) as e:
- self.assertOutputs(
- files=dict(
- some_schema=schema,
- some_instance=instance,
- ),
- argv=[
- "-i", "some_instance",
- "--base-uri", "not@UR1",
- "some_schema",
- ],
- )
- error = str(e.exception)
- self.assertEqual(
- error, "unknown url type: 'foo.json'",
- )
-
- def test_it_validates_using_the_latest_validator_when_unspecified(self):
- # There isn't a better way now I can think of to ensure that the
- # latest version was used, given that the call to validator_for
- # is hidden inside the CLI, so guard that that's the case, and
- # this test will have to be updated when versions change until
- # we can think of a better way to ensure this behavior.
- self.assertIs(Draft202012Validator, _LATEST_VERSION)
-
- self.assertOutputs(
- files=dict(some_schema='{"const": "check"}', some_instance='"a"'),
- argv=["-i", "some_instance", "some_schema"],
- exit_code=1,
- stdout="",
- stderr="a: 'check' was expected\n",
- )
-
- def test_it_validates_using_draft7_when_specified(self):
- """
- Specifically, `const` validation applies for Draft 7.
- """
- schema = """
- {
- "$schema": "http://json-schema.org/draft-07/schema#",
- "const": "check"
- }
- """
- instance = '"foo"'
- self.assertOutputs(
- files=dict(some_schema=schema, some_instance=instance),
- argv=["-i", "some_instance", "some_schema"],
- exit_code=1,
- stdout="",
- stderr="foo: 'check' was expected\n",
- )
-
- def test_it_validates_using_draft4_when_specified(self):
- """
- Specifically, `const` validation *does not* apply for Draft 4.
- """
- schema = """
- {
- "$schema": "http://json-schema.org/draft-04/schema#",
- "const": "check"
- }
- """
- instance = '"foo"'
- self.assertOutputs(
- files=dict(some_schema=schema, some_instance=instance),
- argv=["-i", "some_instance", "some_schema"],
- stdout="",
- stderr="",
- )
-
-
-class TestParser(TestCase):
-
- FakeValidator = fake_validator()
-
- def test_find_validator_by_fully_qualified_object_name(self):
- arguments = cli.parse_args(
- [
- "--validator",
- "jsonschema.tests.test_cli.TestParser.FakeValidator",
- "--instance", "mem://some/instance",
- "mem://some/schema",
- ],
- )
- self.assertIs(arguments["validator"], self.FakeValidator)
-
- def test_find_validator_in_jsonschema(self):
- arguments = cli.parse_args(
- [
- "--validator", "Draft4Validator",
- "--instance", "mem://some/instance",
- "mem://some/schema",
- ],
- )
- self.assertIs(arguments["validator"], Draft4Validator)
-
- def cli_output_for(self, *argv):
- stdout, stderr = StringIO(), StringIO()
- with redirect_stdout(stdout), redirect_stderr(stderr):
- with self.assertRaises(SystemExit):
- cli.parse_args(argv)
- return stdout.getvalue(), stderr.getvalue()
-
- def test_unknown_output(self):
- stdout, stderr = self.cli_output_for(
- "--output", "foo",
- "mem://some/schema",
- )
- self.assertIn("invalid choice: 'foo'", stderr)
- self.assertFalse(stdout)
-
- def test_useless_error_format(self):
- stdout, stderr = self.cli_output_for(
- "--output", "pretty",
- "--error-format", "foo",
- "mem://some/schema",
- )
- self.assertIn(
- "--error-format can only be used with --output plain",
- stderr,
- )
- self.assertFalse(stdout)
-
-
-class TestCLIIntegration(TestCase):
- def test_license(self):
- output = subprocess.check_output(
- [sys.executable, "-m", "pip", "show", "jsonschema"],
- stderr=subprocess.STDOUT,
- )
- self.assertIn(b"License: MIT", output)
-
- def test_version(self):
- version = subprocess.check_output(
- [sys.executable, "-m", "jsonschema", "--version"],
- stderr=subprocess.STDOUT,
- )
- version = version.decode("utf-8").strip()
- self.assertEqual(version, metadata.version("jsonschema"))
-
- def test_no_arguments_shows_usage_notes(self):
- output = subprocess.check_output(
- [sys.executable, "-m", "jsonschema"],
- stderr=subprocess.STDOUT,
- )
- output_for_help = subprocess.check_output(
- [sys.executable, "-m", "jsonschema", "--help"],
- stderr=subprocess.STDOUT,
- )
- self.assertEqual(output, output_for_help)
diff --git a/jsonschema/tests/test_deprecations.py b/jsonschema/tests/test_deprecations.py
deleted file mode 100644
index 58fd050..0000000
--- a/jsonschema/tests/test_deprecations.py
+++ /dev/null
@@ -1,123 +0,0 @@
-from unittest import TestCase
-
-from jsonschema import validators
-
-
-class TestDeprecations(TestCase):
- def test_version(self):
- """
- As of v4.0.0, __version__ is deprecated in favor of importlib.metadata.
- """
-
- with self.assertWarns(DeprecationWarning) as w:
- from jsonschema import __version__ # noqa
-
- self.assertEqual(w.filename, __file__)
- self.assertTrue(
- str(w.warning).startswith(
- "Accessing jsonschema.__version__ is deprecated",
- ),
- )
-
- def test_validators_ErrorTree(self):
- """
- As of v4.0.0, importing ErrorTree from jsonschema.validators is
- deprecated in favor of doing so from jsonschema.exceptions.
- """
-
- with self.assertWarns(DeprecationWarning) as w:
- from jsonschema.validators import ErrorTree # noqa
-
- self.assertEqual(w.filename, __file__)
- self.assertTrue(
- str(w.warning).startswith(
- "Importing ErrorTree from jsonschema.validators is deprecated",
- ),
- )
-
- def test_validators_validators(self):
- """
- As of v4.0.0, accessing jsonschema.validators.validators is
- deprecated.
- """
-
- with self.assertWarns(DeprecationWarning) as w:
- value = validators.validators
- self.assertEqual(value, validators._VALIDATORS)
-
- self.assertEqual(w.filename, __file__)
- self.assertTrue(
- str(w.warning).startswith(
- "Accessing jsonschema.validators.validators is deprecated",
- ),
- )
-
- def test_validators_meta_schemas(self):
- """
- As of v4.0.0, accessing jsonschema.validators.meta_schemas is
- deprecated.
- """
-
- with self.assertWarns(DeprecationWarning) as w:
- value = validators.meta_schemas
- self.assertEqual(value, validators._META_SCHEMAS)
-
- self.assertEqual(w.filename, __file__)
- self.assertTrue(
- str(w.warning).startswith(
- "Accessing jsonschema.validators.meta_schemas is deprecated",
- ),
- )
-
- def test_RefResolver_in_scope(self):
- """
- As of v4.0.0, RefResolver.in_scope is deprecated.
- """
-
- resolver = validators.RefResolver.from_schema({})
- with self.assertWarns(DeprecationWarning) as w:
- with resolver.in_scope("foo"):
- pass
-
- self.assertEqual(w.filename, __file__)
- self.assertTrue(
- str(w.warning).startswith(
- "jsonschema.RefResolver.in_scope is deprecated ",
- ),
- )
-
- def test_Validator_is_valid_two_arguments(self):
- """
- As of v4.0.0, calling is_valid with two arguments (to provide a
- different schema) is deprecated.
- """
-
- validator = validators.Draft7Validator({})
- with self.assertWarns(DeprecationWarning) as w:
- result = validator.is_valid("foo", {"type": "number"})
-
- self.assertFalse(result)
- self.assertEqual(w.filename, __file__)
- self.assertTrue(
- str(w.warning).startswith(
- "Passing a schema to Validator.is_valid is deprecated ",
- ),
- )
-
- def test_Validator_iter_errors_two_arguments(self):
- """
- As of v4.0.0, calling iter_errors with two arguments (to provide a
- different schema) is deprecated.
- """
-
- validator = validators.Draft7Validator({})
- with self.assertWarns(DeprecationWarning) as w:
- error, = validator.iter_errors("foo", {"type": "number"})
-
- self.assertEqual(error.validator, "type")
- self.assertEqual(w.filename, __file__)
- self.assertTrue(
- str(w.warning).startswith(
- "Passing a schema to Validator.iter_errors is deprecated ",
- ),
- )
diff --git a/jsonschema/tests/test_exceptions.py b/jsonschema/tests/test_exceptions.py
deleted file mode 100644
index c565daa..0000000
--- a/jsonschema/tests/test_exceptions.py
+++ /dev/null
@@ -1,588 +0,0 @@
-from unittest import TestCase
-import textwrap
-
-from jsonschema import exceptions
-from jsonschema.validators import _LATEST_VERSION
-
-
-class TestBestMatch(TestCase):
- def best_match_of(self, instance, schema):
- errors = list(_LATEST_VERSION(schema).iter_errors(instance))
- best = exceptions.best_match(iter(errors))
- reversed_best = exceptions.best_match(reversed(errors))
- self.assertEqual(
- best._contents(),
- reversed_best._contents(),
- f"No consistent best match!\nGot: {best}\n\nThen: {reversed_best}",
- )
- return best
-
- def test_shallower_errors_are_better_matches(self):
- schema = {
- "properties": {
- "foo": {
- "minProperties": 2,
- "properties": {"bar": {"type": "object"}},
- },
- },
- }
- best = self.best_match_of(instance={"foo": {"bar": []}}, schema=schema)
- self.assertEqual(best.validator, "minProperties")
-
- def test_oneOf_and_anyOf_are_weak_matches(self):
- """
- A property you *must* match is probably better than one you have to
- match a part of.
- """
-
- schema = {
- "minProperties": 2,
- "anyOf": [{"type": "string"}, {"type": "number"}],
- "oneOf": [{"type": "string"}, {"type": "number"}],
- }
- best = self.best_match_of(instance={}, schema=schema)
- self.assertEqual(best.validator, "minProperties")
-
- def test_if_the_most_relevant_error_is_anyOf_it_is_traversed(self):
- """
- If the most relevant error is an anyOf, then we traverse its context
- and select the otherwise *least* relevant error, since in this case
- that means the most specific, deep, error inside the instance.
-
- I.e. since only one of the schemas must match, we look for the most
- relevant one.
- """
-
- schema = {
- "properties": {
- "foo": {
- "anyOf": [
- {"type": "string"},
- {"properties": {"bar": {"type": "array"}}},
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": {"bar": 12}}, schema=schema)
- self.assertEqual(best.validator_value, "array")
-
- def test_no_anyOf_traversal_for_equally_relevant_errors(self):
- """
- We don't traverse into an anyOf (as above) if all of its context errors
- seem to be equally "wrong" against the instance.
- """
-
- schema = {
- "anyOf": [
- {"type": "string"},
- {"type": "integer"},
- {"type": "object"},
- ],
- }
- best = self.best_match_of(instance=[], schema=schema)
- self.assertEqual(best.validator, "anyOf")
-
- def test_anyOf_traversal_for_single_equally_relevant_error(self):
- """
- We *do* traverse anyOf with a single nested error, even though it is
- vacuously equally relevant to itself.
- """
-
- schema = {
- "anyOf": [
- {"type": "string"},
- ],
- }
- best = self.best_match_of(instance=[], schema=schema)
- self.assertEqual(best.validator, "type")
-
- def test_if_the_most_relevant_error_is_oneOf_it_is_traversed(self):
- """
- If the most relevant error is an oneOf, then we traverse its context
- and select the otherwise *least* relevant error, since in this case
- that means the most specific, deep, error inside the instance.
-
- I.e. since only one of the schemas must match, we look for the most
- relevant one.
- """
-
- schema = {
- "properties": {
- "foo": {
- "oneOf": [
- {"type": "string"},
- {"properties": {"bar": {"type": "array"}}},
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": {"bar": 12}}, schema=schema)
- self.assertEqual(best.validator_value, "array")
-
- def test_no_oneOf_traversal_for_equally_relevant_errors(self):
- """
- We don't traverse into an oneOf (as above) if all of its context errors
- seem to be equally "wrong" against the instance.
- """
-
- schema = {
- "oneOf": [
- {"type": "string"},
- {"type": "integer"},
- {"type": "object"},
- ],
- }
- best = self.best_match_of(instance=[], schema=schema)
- self.assertEqual(best.validator, "oneOf")
-
- def test_oneOf_traversal_for_single_equally_relevant_error(self):
- """
- We *do* traverse oneOf with a single nested error, even though it is
- vacuously equally relevant to itself.
- """
-
- schema = {
- "oneOf": [
- {"type": "string"},
- ],
- }
- best = self.best_match_of(instance=[], schema=schema)
- self.assertEqual(best.validator, "type")
-
- def test_if_the_most_relevant_error_is_allOf_it_is_traversed(self):
- """
- Now, if the error is allOf, we traverse but select the *most* relevant
- error from the context, because all schemas here must match anyways.
- """
-
- schema = {
- "properties": {
- "foo": {
- "allOf": [
- {"type": "string"},
- {"properties": {"bar": {"type": "array"}}},
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": {"bar": 12}}, schema=schema)
- self.assertEqual(best.validator_value, "string")
-
- def test_nested_context_for_oneOf(self):
- """
- We traverse into nested contexts (a oneOf containing an error in a
- nested oneOf here).
- """
-
- schema = {
- "properties": {
- "foo": {
- "oneOf": [
- {"type": "string"},
- {
- "oneOf": [
- {"type": "string"},
- {
- "properties": {
- "bar": {"type": "array"},
- },
- },
- ],
- },
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": {"bar": 12}}, schema=schema)
- self.assertEqual(best.validator_value, "array")
-
- def test_it_prioritizes_matching_types(self):
- schema = {
- "properties": {
- "foo": {
- "anyOf": [
- {"type": "array", "minItems": 2},
- {"type": "string", "minLength": 10},
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": "bar"}, schema=schema)
- self.assertEqual(best.validator, "minLength")
-
- reordered = {
- "properties": {
- "foo": {
- "anyOf": [
- {"type": "string", "minLength": 10},
- {"type": "array", "minItems": 2},
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": "bar"}, schema=reordered)
- self.assertEqual(best.validator, "minLength")
-
- def test_it_prioritizes_matching_union_types(self):
- schema = {
- "properties": {
- "foo": {
- "anyOf": [
- {"type": ["array", "object"], "minItems": 2},
- {"type": ["integer", "string"], "minLength": 10},
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": "bar"}, schema=schema)
- self.assertEqual(best.validator, "minLength")
-
- reordered = {
- "properties": {
- "foo": {
- "anyOf": [
- {"type": "string", "minLength": 10},
- {"type": "array", "minItems": 2},
- ],
- },
- },
- }
- best = self.best_match_of(instance={"foo": "bar"}, schema=reordered)
- self.assertEqual(best.validator, "minLength")
-
- def test_boolean_schemas(self):
- schema = {"properties": {"foo": False}}
- best = self.best_match_of(instance={"foo": "bar"}, schema=schema)
- self.assertIsNone(best.validator)
-
- def test_one_error(self):
- validator = _LATEST_VERSION({"minProperties": 2})
- error, = validator.iter_errors({})
- self.assertEqual(
- exceptions.best_match(validator.iter_errors({})).validator,
- "minProperties",
- )
-
- def test_no_errors(self):
- validator = _LATEST_VERSION({})
- self.assertIsNone(exceptions.best_match(validator.iter_errors({})))
-
-
-class TestByRelevance(TestCase):
- def test_short_paths_are_better_matches(self):
- shallow = exceptions.ValidationError("Oh no!", path=["baz"])
- deep = exceptions.ValidationError("Oh yes!", path=["foo", "bar"])
- match = max([shallow, deep], key=exceptions.relevance)
- self.assertIs(match, shallow)
-
- match = max([deep, shallow], key=exceptions.relevance)
- self.assertIs(match, shallow)
-
- def test_global_errors_are_even_better_matches(self):
- shallow = exceptions.ValidationError("Oh no!", path=[])
- deep = exceptions.ValidationError("Oh yes!", path=["foo"])
-
- errors = sorted([shallow, deep], key=exceptions.relevance)
- self.assertEqual(
- [list(error.path) for error in errors],
- [["foo"], []],
- )
-
- errors = sorted([deep, shallow], key=exceptions.relevance)
- self.assertEqual(
- [list(error.path) for error in errors],
- [["foo"], []],
- )
-
- def test_weak_validators_are_lower_priority(self):
- weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
- normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
-
- best_match = exceptions.by_relevance(weak="a")
-
- match = max([weak, normal], key=best_match)
- self.assertIs(match, normal)
-
- match = max([normal, weak], key=best_match)
- self.assertIs(match, normal)
-
- def test_strong_validators_are_higher_priority(self):
- weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
- normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
- strong = exceptions.ValidationError("Oh fine!", path=[], validator="c")
-
- best_match = exceptions.by_relevance(weak="a", strong="c")
-
- match = max([weak, normal, strong], key=best_match)
- self.assertIs(match, strong)
-
- match = max([strong, normal, weak], key=best_match)
- self.assertIs(match, strong)
-
-
-class TestErrorTree(TestCase):
- def test_it_knows_how_many_total_errors_it_contains(self):
- # FIXME: #442
- errors = [
- exceptions.ValidationError("Something", validator=i)
- for i in range(8)
- ]
- tree = exceptions.ErrorTree(errors)
- self.assertEqual(tree.total_errors, 8)
-
- def test_it_contains_an_item_if_the_item_had_an_error(self):
- errors = [exceptions.ValidationError("a message", path=["bar"])]
- tree = exceptions.ErrorTree(errors)
- self.assertIn("bar", tree)
-
- def test_it_does_not_contain_an_item_if_the_item_had_no_error(self):
- errors = [exceptions.ValidationError("a message", path=["bar"])]
- tree = exceptions.ErrorTree(errors)
- self.assertNotIn("foo", tree)
-
- def test_validators_that_failed_appear_in_errors_dict(self):
- error = exceptions.ValidationError("a message", validator="foo")
- tree = exceptions.ErrorTree([error])
- self.assertEqual(tree.errors, {"foo": error})
-
- def test_it_creates_a_child_tree_for_each_nested_path(self):
- errors = [
- exceptions.ValidationError("a bar message", path=["bar"]),
- exceptions.ValidationError("a bar -> 0 message", path=["bar", 0]),
- ]
- tree = exceptions.ErrorTree(errors)
- self.assertIn(0, tree["bar"])
- self.assertNotIn(1, tree["bar"])
-
- def test_children_have_their_errors_dicts_built(self):
- e1, e2 = (
- exceptions.ValidationError("1", validator="foo", path=["bar", 0]),
- exceptions.ValidationError("2", validator="quux", path=["bar", 0]),
- )
- tree = exceptions.ErrorTree([e1, e2])
- self.assertEqual(tree["bar"][0].errors, {"foo": e1, "quux": e2})
-
- def test_multiple_errors_with_instance(self):
- e1, e2 = (
- exceptions.ValidationError(
- "1",
- validator="foo",
- path=["bar", "bar2"],
- instance="i1"),
- exceptions.ValidationError(
- "2",
- validator="quux",
- path=["foobar", 2],
- instance="i2"),
- )
- exceptions.ErrorTree([e1, e2])
-
- def test_it_does_not_contain_subtrees_that_are_not_in_the_instance(self):
- error = exceptions.ValidationError("123", validator="foo", instance=[])
- tree = exceptions.ErrorTree([error])
-
- with self.assertRaises(IndexError):
- tree[0]
-
- def test_if_its_in_the_tree_anyhow_it_does_not_raise_an_error(self):
- """
- If a validator is dumb (like :validator:`required` in draft 3) and
- refers to a path that isn't in the instance, the tree still properly
- returns a subtree for that path.
- """
-
- error = exceptions.ValidationError(
- "a message", validator="foo", instance={}, path=["foo"],
- )
- tree = exceptions.ErrorTree([error])
- self.assertIsInstance(tree["foo"], exceptions.ErrorTree)
-
- def test_repr(self):
- e1, e2 = (
- exceptions.ValidationError(
- "1",
- validator="foo",
- path=["bar", "bar2"],
- instance="i1"),
- exceptions.ValidationError(
- "2",
- validator="quux",
- path=["foobar", 2],
- instance="i2"),
- )
- tree = exceptions.ErrorTree([e1, e2])
- self.assertEqual(repr(tree), "<ErrorTree (2 total errors)>")
-
-
-class TestErrorInitReprStr(TestCase):
- def make_error(self, **kwargs):
- defaults = dict(
- message="hello",
- validator="type",
- validator_value="string",
- instance=5,
- schema={"type": "string"},
- )
- defaults.update(kwargs)
- return exceptions.ValidationError(**defaults)
-
- def assertShows(self, expected, **kwargs):
- expected = textwrap.dedent(expected).rstrip("\n")
-
- error = self.make_error(**kwargs)
- message_line, _, rest = str(error).partition("\n")
- self.assertEqual(message_line, error.message)
- self.assertEqual(rest, expected)
-
- def test_it_calls_super_and_sets_args(self):
- error = self.make_error()
- self.assertGreater(len(error.args), 1)
-
- def test_repr(self):
- self.assertEqual(
- repr(exceptions.ValidationError(message="Hello!")),
- "<ValidationError: 'Hello!'>",
- )
-
- def test_unset_error(self):
- error = exceptions.ValidationError("message")
- self.assertEqual(str(error), "message")
-
- kwargs = {
- "validator": "type",
- "validator_value": "string",
- "instance": 5,
- "schema": {"type": "string"},
- }
- # Just the message should show if any of the attributes are unset
- for attr in kwargs:
- k = dict(kwargs)
- del k[attr]
- error = exceptions.ValidationError("message", **k)
- self.assertEqual(str(error), "message")
-
- def test_empty_paths(self):
- self.assertShows(
- """
- Failed validating 'type' in schema:
- {'type': 'string'}
-
- On instance:
- 5
- """,
- path=[],
- schema_path=[],
- )
-
- def test_one_item_paths(self):
- self.assertShows(
- """
- Failed validating 'type' in schema:
- {'type': 'string'}
-
- On instance[0]:
- 5
- """,
- path=[0],
- schema_path=["items"],
- )
-
- def test_multiple_item_paths(self):
- self.assertShows(
- """
- Failed validating 'type' in schema['items'][0]:
- {'type': 'string'}
-
- On instance[0]['a']:
- 5
- """,
- path=[0, "a"],
- schema_path=["items", 0, 1],
- )
-
- def test_uses_pprint(self):
- self.assertShows(
- """
- Failed validating 'maxLength' in schema:
- {0: 0,
- 1: 1,
- 2: 2,
- 3: 3,
- 4: 4,
- 5: 5,
- 6: 6,
- 7: 7,
- 8: 8,
- 9: 9,
- 10: 10,
- 11: 11,
- 12: 12,
- 13: 13,
- 14: 14,
- 15: 15,
- 16: 16,
- 17: 17,
- 18: 18,
- 19: 19}
-
- On instance:
- [0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 17,
- 18,
- 19,
- 20,
- 21,
- 22,
- 23,
- 24]
- """,
- instance=list(range(25)),
- schema=dict(zip(range(20), range(20))),
- validator="maxLength",
- )
-
- def test_str_works_with_instances_having_overriden_eq_operator(self):
- """
- Check for #164 which rendered exceptions unusable when a
- `ValidationError` involved instances with an `__eq__` method
- that returned truthy values.
- """
-
- class DontEQMeBro(object):
- def __eq__(this, other): # pragma: no cover
- self.fail("Don't!")
-
- def __ne__(this, other): # pragma: no cover
- self.fail("Don't!")
-
- instance = DontEQMeBro()
- error = exceptions.ValidationError(
- "a message",
- validator="foo",
- instance=instance,
- validator_value="some",
- schema="schema",
- )
- self.assertIn(repr(instance), str(error))
-
-
-class TestHashable(TestCase):
- def test_hashable(self):
- set([exceptions.ValidationError("")])
- set([exceptions.SchemaError("")])
diff --git a/jsonschema/tests/test_format.py b/jsonschema/tests/test_format.py
deleted file mode 100644
index 1846cb2..0000000
--- a/jsonschema/tests/test_format.py
+++ /dev/null
@@ -1,107 +0,0 @@
-"""
-Tests for the parts of jsonschema related to the :validator:`format` property.
-"""
-
-from unittest import TestCase
-
-from jsonschema import FormatChecker, FormatError, ValidationError
-from jsonschema.validators import Draft4Validator
-
-BOOM = ValueError("Boom!")
-BANG = ZeroDivisionError("Bang!")
-
-
-def boom(thing):
- if thing == "bang":
- raise BANG
- raise BOOM
-
-
-class TestFormatChecker(TestCase):
- def test_it_can_validate_no_formats(self):
- checker = FormatChecker(formats=())
- self.assertFalse(checker.checkers)
-
- def test_it_raises_a_key_error_for_unknown_formats(self):
- with self.assertRaises(KeyError):
- FormatChecker(formats=["o noes"])
-
- def test_it_can_register_cls_checkers(self):
- original = dict(FormatChecker.checkers)
- self.addCleanup(FormatChecker.checkers.pop, "boom")
- FormatChecker.cls_checks("boom")(boom)
- self.assertEqual(
- FormatChecker.checkers,
- dict(original, boom=(boom, ())),
- )
-
- def test_it_can_register_checkers(self):
- checker = FormatChecker()
- checker.checks("boom")(boom)
- self.assertEqual(
- checker.checkers,
- dict(FormatChecker.checkers, boom=(boom, ())),
- )
-
- def test_it_catches_registered_errors(self):
- checker = FormatChecker()
- checker.checks("boom", raises=type(BOOM))(boom)
-
- with self.assertRaises(FormatError) as cm:
- checker.check(instance=12, format="boom")
-
- self.assertIs(cm.exception.cause, BOOM)
- self.assertIs(cm.exception.__cause__, BOOM)
-
- # Unregistered errors should not be caught
- with self.assertRaises(type(BANG)):
- checker.check(instance="bang", format="boom")
-
- def test_format_error_causes_become_validation_error_causes(self):
- checker = FormatChecker()
- checker.checks("boom", raises=ValueError)(boom)
- validator = Draft4Validator({"format": "boom"}, format_checker=checker)
-
- with self.assertRaises(ValidationError) as cm:
- validator.validate("BOOM")
-
- self.assertIs(cm.exception.cause, BOOM)
- self.assertIs(cm.exception.__cause__, BOOM)
-
- def test_format_checkers_come_with_defaults(self):
- # This is bad :/ but relied upon.
- # The docs for quite awhile recommended people do things like
- # validate(..., format_checker=FormatChecker())
- # We should change that, but we can't without deprecation...
- checker = FormatChecker()
- with self.assertRaises(FormatError):
- checker.check(instance="not-an-ipv4", format="ipv4")
-
- def test_repr(self):
- checker = FormatChecker(formats=())
- checker.checks("foo")(lambda thing: True) # pragma: no cover
- checker.checks("bar")(lambda thing: True) # pragma: no cover
- checker.checks("baz")(lambda thing: True) # pragma: no cover
- self.assertEqual(
- repr(checker),
- "<FormatChecker checkers=['bar', 'baz', 'foo']>",
- )
-
- def test_duration_format(self):
- try:
- from jsonschema._format import is_duration # noqa: F401
- except ImportError: # pragma: no cover
- pass
- else:
- checker = FormatChecker()
- self.assertTrue(checker.conforms(1, "duration"))
- self.assertTrue(checker.conforms("P4Y", "duration"))
- self.assertFalse(checker.conforms("test", "duration"))
-
- def test_uuid_format(self):
- checker = FormatChecker()
- self.assertTrue(checker.conforms(1, "uuid"))
- self.assertTrue(
- checker.conforms("6e6659ec-4503-4428-9f03-2e2ea4d6c278", "uuid"),
- )
- self.assertFalse(checker.conforms("test", "uuid"))
diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py
deleted file mode 100644
index 96a6c80..0000000
--- a/jsonschema/tests/test_jsonschema_test_suite.py
+++ /dev/null
@@ -1,446 +0,0 @@
-"""
-Test runner for the JSON Schema official test suite
-
-Tests comprehensive correctness of each draft's validator.
-
-See https://github.com/json-schema-org/JSON-Schema-Test-Suite for details.
-"""
-
-import sys
-
-from jsonschema.tests._helpers import bug
-from jsonschema.tests._suite import Suite
-import jsonschema
-
-SUITE = Suite()
-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")
-
-
-def skip(message, **kwargs):
- def skipper(test):
- if all(value == getattr(test, attr) for attr, value in kwargs.items()):
- return message
- return skipper
-
-
-def missing_format(checker):
- def missing_format(test): # pragma: no cover
- schema = test.schema
- if (
- schema is True
- or schema is False
- or "format" not in schema
- or schema["format"] in checker.checkers
- or test.valid
- ):
- return
-
- return "Format checker {0!r} not found.".format(schema["format"])
- return missing_format
-
-
-def complex_email_validation(test):
- if test.subject != "email":
- return
-
- message = "Complex email validation is (intentionally) unsupported."
- return skip(
- message=message,
- description="an invalid domain",
- )(test) or skip(
- message=message,
- description="an invalid IPv4-address-literal",
- )(test) or skip(
- message=message,
- description="dot after local part is not valid",
- )(test) or skip(
- message=message,
- description="dot before local part is not valid",
- )(test) or skip(
- message=message,
- description="two subsequent dots inside local part are not valid",
- )(test)
-
-
-is_narrow_build = sys.maxunicode == 2 ** 16 - 1
-if is_narrow_build: # pragma: no cover
- message = "Not running surrogate Unicode case, this Python is narrow."
-
- def narrow_unicode_build(test): # pragma: no cover
- return skip(
- message=message,
- description=(
- "one supplementary Unicode code point is not long enough"
- ),
- )(test) or skip(
- message=message,
- description="two supplementary Unicode code points is long enough",
- )(test)
-else:
- def narrow_unicode_build(test): # pragma: no cover
- return
-
-
-if sys.version_info < (3, 9): # pragma: no cover
- message = "Rejecting leading zeros is 3.9+"
- allowed_leading_zeros = skip(
- message=message,
- subject="ipv4",
- description=(
- "leading zeroes should be rejected, as they are treated as octals"
- ),
- )
-else:
- def allowed_leading_zeros(test): # pragma: no cover
- return
-
-
-def leap_second(test):
- message = "Leap seconds are unsupported."
- return skip(
- message=message,
- subject="time",
- description="a valid time string with leap second",
- )(test) or skip(
- message=message,
- subject="time",
- description="a valid time string with leap second, Zulu",
- )(test) or skip(
- message=message,
- subject="time",
- description="a valid time string with leap second with offset",
- )(test) or skip(
- message=message,
- subject="time",
- description="valid leap second, positive time-offset",
- )(test) or skip(
- message=message,
- subject="time",
- description="valid leap second, negative time-offset",
- )(test) or skip(
- message=message,
- subject="time",
- description="valid leap second, large positive time-offset",
- )(test) or skip(
- message=message,
- subject="time",
- description="valid leap second, large negative time-offset",
- )(test) or skip(
- message=message,
- subject="time",
- description="valid leap second, zero time-offset",
- )(test) or skip(
- message=message,
- subject="date-time",
- description="a valid date-time with a leap second, UTC",
- )(test) or skip(
- message=message,
- subject="date-time",
- description="a valid date-time with a leap second, with minus offset",
- )(test)
-
-
-TestDraft3 = DRAFT3.to_unittest_testcase(
- DRAFT3.tests(),
- DRAFT3.format_tests(),
- DRAFT3.optional_tests_of(name="bignum"),
- DRAFT3.optional_tests_of(name="non-bmp-regex"),
- DRAFT3.optional_tests_of(name="zeroTerminatedFloats"),
- Validator=jsonschema.Draft3Validator,
- format_checker=jsonschema.draft3_format_checker,
- skip=lambda test: (
- narrow_unicode_build(test)
- or missing_format(jsonschema.draft3_format_checker)(test)
- or complex_email_validation(test)
- or skip(
- message=bug(371),
- subject="ref",
- case_description=(
- "$ref prevents a sibling id from changing the base uri"
- ),
- )(test)
- ),
-)
-
-
-TestDraft4 = DRAFT4.to_unittest_testcase(
- DRAFT4.tests(),
- DRAFT4.format_tests(),
- DRAFT4.optional_tests_of(name="bignum"),
- DRAFT4.optional_tests_of(name="float-overflow"),
- DRAFT4.optional_tests_of(name="non-bmp-regex"),
- DRAFT4.optional_tests_of(name="zeroTerminatedFloats"),
- Validator=jsonschema.Draft4Validator,
- format_checker=jsonschema.draft4_format_checker,
- skip=lambda test: (
- narrow_unicode_build(test)
- or allowed_leading_zeros(test)
- or leap_second(test)
- or missing_format(jsonschema.draft4_format_checker)(test)
- or complex_email_validation(test)
- or skip(
- message=bug(),
- subject="ref",
- case_description="Recursive references between schemas",
- )(test)
- or skip(
- message=bug(371),
- subject="ref",
- case_description=(
- "Location-independent identifier with "
- "base URI change in subschema"
- ),
- )(test)
- or skip(
- message=bug(371),
- subject="ref",
- case_description=(
- "$ref prevents a sibling id from changing the base uri"
- ),
- )(test)
- or skip(
- message=bug(371),
- subject="id",
- description="match $ref to id",
- )(test)
- or skip(
- message=bug(371),
- subject="id",
- description="no match on enum or $ref to id",
- )(test)
- or skip(
- message=bug(),
- subject="refRemote",
- case_description="base URI change - change folder in subschema",
- )(test)
- or skip(
- message=bug(),
- subject="ref",
- case_description=(
- "id must be resolved against nearest parent, "
- "not just immediate parent"
- ),
- )(test)
- ),
-)
-
-
-TestDraft6 = DRAFT6.to_unittest_testcase(
- DRAFT6.tests(),
- DRAFT6.format_tests(),
- DRAFT6.optional_tests_of(name="bignum"),
- DRAFT6.optional_tests_of(name="float-overflow"),
- DRAFT6.optional_tests_of(name="non-bmp-regex"),
- Validator=jsonschema.Draft6Validator,
- format_checker=jsonschema.draft6_format_checker,
- skip=lambda test: (
- narrow_unicode_build(test)
- or allowed_leading_zeros(test)
- or leap_second(test)
- or missing_format(jsonschema.draft6_format_checker)(test)
- or complex_email_validation(test)
- or skip(
- message="id is incorrectly finding non-ids",
- subject="id",
- description="const at const_not_anchor does not match",
- )(test)
- or skip(
- message="id is incorrectly finding non-ids",
- subject="id",
- description="const at const_not_id does not match",
- )(test)
- or skip(
- message=bug(),
- subject="refRemote",
- case_description="base URI change - change folder in subschema",
- )(test)
- or skip(
- message=bug(371),
- subject="ref",
- case_description=(
- "$ref prevents a sibling $id from changing the base uri"
- ),
- )(test)
- ),
-)
-
-
-TestDraft7 = DRAFT7.to_unittest_testcase(
- DRAFT7.tests(),
- DRAFT7.format_tests(),
- DRAFT7.optional_tests_of(name="bignum"),
- DRAFT7.optional_tests_of(name="content"),
- DRAFT7.optional_tests_of(name="float-overflow"),
- DRAFT7.optional_tests_of(name="non-bmp-regex"),
- Validator=jsonschema.Draft7Validator,
- format_checker=jsonschema.draft7_format_checker,
- skip=lambda test: (
- narrow_unicode_build(test)
- or allowed_leading_zeros(test)
- or leap_second(test)
- or missing_format(jsonschema.draft7_format_checker)(test)
- or complex_email_validation(test)
- or skip(
- message=bug(),
- subject="refRemote",
- case_description="base URI change - change folder in subschema",
- )(test)
- or skip(
- message=bug(371),
- subject="ref",
- case_description=(
- "$ref prevents a sibling $id from changing the base uri"
- ),
- )(test)
- or skip(
- message=bug(),
- subject="ref",
- case_description=(
- "$id must be resolved against nearest parent, "
- "not just immediate parent"
- ),
- )(test)
- or skip(
- message=bug(593),
- subject="content",
- valid=False,
- case_description=(
- "validation of string-encoded content based on media type"
- ),
- )(test)
- or skip(
- message=bug(593),
- subject="content",
- valid=False,
- case_description="validation of binary string-encoding",
- )(test)
- or skip(
- message=bug(593),
- subject="content",
- valid=False,
- case_description=(
- "validation of binary-encoded media type documents"
- ),
- )(test)
- ),
-)
-
-
-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=jsonschema.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)
- or skip(
- message="These tests depends on dynamicRef working.",
- subject="id",
- case_description=(
- "Invalid use of fragments in location-independent $id"
- ),
- )(test)
- or skip(
- message="These tests depends on dynamicRef working.",
- subject="defs",
- description="invalid definition schema",
- )(test)
- or skip(
- message="These tests depends on dynamicRef working.",
- subject="anchor",
- case_description="same $anchor with different base uri",
- )(test)
- or skip(
- message="Vocabulary support is not yet present.",
- subject="vocabulary",
- )(test)
- or skip(
- message=bug(),
- subject="ref",
- case_description=(
- "$id must be resolved against nearest parent, "
- "not just immediate parent"
- ),
- )(test)
- ),
-)
-
-
-TestDraft201909Format = DRAFT201909.to_unittest_testcase(
- DRAFT201909.format_tests(),
- Validator=jsonschema.Draft201909Validator,
- format_checker=jsonschema.draft201909_format_checker,
- skip=lambda test: (
- complex_email_validation(test)
- or allowed_leading_zeros(test)
- or leap_second(test)
- or missing_format(jsonschema.draft201909_format_checker)(test)
- or complex_email_validation(test)
- ),
-)
-
-
-TestDraft202012 = DRAFT202012.to_unittest_testcase(
- DRAFT202012.tests(),
- DRAFT202012.optional_tests_of(name="bignum"),
- DRAFT202012.optional_tests_of(name="float-overflow"),
- DRAFT202012.optional_tests_of(name="non-bmp-regex"),
- DRAFT202012.optional_tests_of(name="refOfUnknownKeyword"),
- Validator=jsonschema.Draft202012Validator,
- skip=lambda test: (
- narrow_unicode_build(test)
- or skip(
- message="dynamicRef support isn't working yet.",
- subject="dynamicRef",
- )(test)
- or skip(
- message="These tests depends on dynamicRef working.",
- subject="defs",
- )(test)
- or skip(
- message="These tests depends on dynamicRef working.",
- subject="anchor",
- case_description="same $anchor with different base uri",
- )(test)
- or skip(
- message="Vocabulary support is not yet present.",
- subject="vocabulary",
- )(test)
- or skip(
- message=bug(),
- subject="ref",
- case_description=(
- "$id must be resolved against nearest parent, "
- "not just immediate parent"
- ),
- )(test)
- ),
-)
-
-
-TestDraft202012Format = DRAFT202012.to_unittest_testcase(
- DRAFT202012.format_tests(),
- Validator=jsonschema.Draft202012Validator,
- format_checker=jsonschema.draft202012_format_checker,
- skip=lambda test: (
- complex_email_validation(test)
- or allowed_leading_zeros(test)
- or leap_second(test)
- or missing_format(jsonschema.draft202012_format_checker)(test)
- or complex_email_validation(test)
- ),
-)
diff --git a/jsonschema/tests/test_types.py b/jsonschema/tests/test_types.py
deleted file mode 100644
index 3fd1a70..0000000
--- a/jsonschema/tests/test_types.py
+++ /dev/null
@@ -1,217 +0,0 @@
-"""
-Tests for the `TypeChecker`-based type interface.
-
-The actual correctness of the type checking is handled in
-`test_jsonschema_test_suite`; these tests check that TypeChecker
-functions correctly at a more granular level.
-"""
-from collections import namedtuple
-from unittest import TestCase
-
-from jsonschema import ValidationError, _validators
-from jsonschema._types import TypeChecker
-from jsonschema.exceptions import UndefinedTypeCheck, UnknownType
-from jsonschema.validators import Draft202012Validator, extend
-
-
-def equals_2(checker, instance):
- return instance == 2
-
-
-def is_namedtuple(instance):
- return isinstance(instance, tuple) and getattr(instance, "_fields", None)
-
-
-def is_object_or_named_tuple(checker, instance):
- if Draft202012Validator.TYPE_CHECKER.is_type(instance, "object"):
- return True
- return is_namedtuple(instance)
-
-
-class TestTypeChecker(TestCase):
- def test_is_type(self):
- checker = TypeChecker({"two": equals_2})
- self.assertEqual(
- (
- checker.is_type(instance=2, type="two"),
- checker.is_type(instance="bar", type="two"),
- ),
- (True, False),
- )
-
- def test_is_unknown_type(self):
- with self.assertRaises(UndefinedTypeCheck) as e:
- TypeChecker().is_type(4, "foobar")
- self.assertIn(
- "'foobar' is unknown to this type checker",
- str(e.exception),
- )
- self.assertTrue(
- e.exception.__suppress_context__,
- msg="Expected the internal KeyError to be hidden.",
- )
-
- def test_checks_can_be_added_at_init(self):
- checker = TypeChecker({"two": equals_2})
- self.assertEqual(checker, TypeChecker().redefine("two", equals_2))
-
- def test_redefine_existing_type(self):
- self.assertEqual(
- TypeChecker().redefine("two", object()).redefine("two", equals_2),
- TypeChecker().redefine("two", equals_2),
- )
-
- def test_remove(self):
- self.assertEqual(
- TypeChecker({"two": equals_2}).remove("two"),
- TypeChecker(),
- )
-
- def test_remove_unknown_type(self):
- with self.assertRaises(UndefinedTypeCheck) as context:
- TypeChecker().remove("foobar")
- self.assertIn("foobar", str(context.exception))
-
- def test_redefine_many(self):
- self.assertEqual(
- TypeChecker().redefine_many({"foo": int, "bar": str}),
- TypeChecker().redefine("foo", int).redefine("bar", str),
- )
-
- def test_remove_multiple(self):
- self.assertEqual(
- TypeChecker({"foo": int, "bar": str}).remove("foo", "bar"),
- TypeChecker(),
- )
-
- def test_type_check_can_raise_key_error(self):
- """
- Make sure no one writes:
-
- try:
- self._type_checkers[type](...)
- except KeyError:
-
- ignoring the fact that the function itself can raise that.
- """
-
- error = KeyError("Stuff")
-
- def raises_keyerror(checker, instance):
- raise error
-
- with self.assertRaises(KeyError) as context:
- TypeChecker({"foo": raises_keyerror}).is_type(4, "foo")
-
- self.assertIs(context.exception, error)
-
-
-class TestCustomTypes(TestCase):
- def test_simple_type_can_be_extended(self):
- def int_or_str_int(checker, instance):
- if not isinstance(instance, (int, str)):
- return False
- try:
- int(instance)
- except ValueError:
- return False
- return True
-
- CustomValidator = extend(
- Draft202012Validator,
- type_checker=Draft202012Validator.TYPE_CHECKER.redefine(
- "integer", int_or_str_int,
- ),
- )
- validator = CustomValidator({"type": "integer"})
-
- validator.validate(4)
- validator.validate("4")
-
- with self.assertRaises(ValidationError):
- validator.validate(4.4)
-
- with self.assertRaises(ValidationError):
- validator.validate("foo")
-
- def test_object_can_be_extended(self):
- schema = {"type": "object"}
-
- Point = namedtuple("Point", ["x", "y"])
-
- type_checker = Draft202012Validator.TYPE_CHECKER.redefine(
- "object", is_object_or_named_tuple,
- )
-
- CustomValidator = extend(
- Draft202012Validator,
- type_checker=type_checker,
- )
- validator = CustomValidator(schema)
-
- validator.validate(Point(x=4, y=5))
-
- def test_object_extensions_require_custom_validators(self):
- schema = {"type": "object", "required": ["x"]}
-
- type_checker = Draft202012Validator.TYPE_CHECKER.redefine(
- "object", is_object_or_named_tuple,
- )
-
- CustomValidator = extend(
- Draft202012Validator,
- type_checker=type_checker,
- )
- validator = CustomValidator(schema)
-
- Point = namedtuple("Point", ["x", "y"])
- # Cannot handle required
- with self.assertRaises(ValidationError):
- validator.validate(Point(x=4, y=5))
-
- def test_object_extensions_can_handle_custom_validators(self):
- schema = {
- "type": "object",
- "required": ["x"],
- "properties": {"x": {"type": "integer"}},
- }
-
- type_checker = Draft202012Validator.TYPE_CHECKER.redefine(
- "object", is_object_or_named_tuple,
- )
-
- def coerce_named_tuple(fn):
- def coerced(validator, value, instance, schema):
- if is_namedtuple(instance):
- instance = instance._asdict()
- return fn(validator, value, instance, schema)
- return coerced
-
- required = coerce_named_tuple(_validators.required)
- properties = coerce_named_tuple(_validators.properties)
-
- CustomValidator = extend(
- Draft202012Validator,
- type_checker=type_checker,
- validators={"required": required, "properties": properties},
- )
-
- validator = CustomValidator(schema)
-
- Point = namedtuple("Point", ["x", "y"])
- # Can now process required and properties
- validator.validate(Point(x=4, y=5))
-
- with self.assertRaises(ValidationError):
- validator.validate(Point(x="not an integer", y=5))
-
- # As well as still handle objects.
- validator.validate({"x": 4, "y": 5})
-
- with self.assertRaises(ValidationError):
- validator.validate({"x": "not an integer", "y": 5})
-
- def test_unknown_type(self):
- with self.assertRaises(UnknownType) as e:
- Draft202012Validator({}).is_type(12, "some unknown type")
- self.assertIn("'some unknown type'", str(e.exception))
diff --git a/jsonschema/tests/test_utils.py b/jsonschema/tests/test_utils.py
deleted file mode 100644
index 4e542b9..0000000
--- a/jsonschema/tests/test_utils.py
+++ /dev/null
@@ -1,124 +0,0 @@
-from unittest import TestCase
-
-from jsonschema._utils import equal
-
-
-class TestEqual(TestCase):
- def test_none(self):
- self.assertTrue(equal(None, None))
-
-
-class TestDictEqual(TestCase):
- def test_equal_dictionaries(self):
- dict_1 = {"a": "b", "c": "d"}
- dict_2 = {"c": "d", "a": "b"}
- self.assertTrue(equal(dict_1, dict_2))
-
- def test_missing_key(self):
- dict_1 = {"a": "b", "c": "d"}
- dict_2 = {"c": "d", "x": "b"}
- self.assertFalse(equal(dict_1, dict_2))
-
- def test_additional_key(self):
- dict_1 = {"a": "b", "c": "d"}
- dict_2 = {"c": "d", "a": "b", "x": "x"}
- self.assertFalse(equal(dict_1, dict_2))
-
- def test_missing_value(self):
- dict_1 = {"a": "b", "c": "d"}
- dict_2 = {"c": "d", "a": "x"}
- self.assertFalse(equal(dict_1, dict_2))
-
- def test_empty_dictionaries(self):
- dict_1 = {}
- dict_2 = {}
- self.assertTrue(equal(dict_1, dict_2))
-
- def test_one_none(self):
- dict_1 = None
- dict_2 = {"a": "b", "c": "d"}
- self.assertFalse(equal(dict_1, dict_2))
-
- def test_same_item(self):
- dict_1 = {"a": "b", "c": "d"}
- self.assertTrue(equal(dict_1, dict_1))
-
- def test_nested_equal(self):
- dict_1 = {"a": {"a": "b", "c": "d"}, "c": "d"}
- dict_2 = {"c": "d", "a": {"a": "b", "c": "d"}}
- self.assertTrue(equal(dict_1, dict_2))
-
- def test_nested_dict_unequal(self):
- dict_1 = {"a": {"a": "b", "c": "d"}, "c": "d"}
- dict_2 = {"c": "d", "a": {"a": "b", "c": "x"}}
- self.assertFalse(equal(dict_1, dict_2))
-
- def test_mixed_nested_equal(self):
- dict_1 = {"a": ["a", "b", "c", "d"], "c": "d"}
- dict_2 = {"c": "d", "a": ["a", "b", "c", "d"]}
- self.assertTrue(equal(dict_1, dict_2))
-
- def test_nested_list_unequal(self):
- dict_1 = {"a": ["a", "b", "c", "d"], "c": "d"}
- dict_2 = {"c": "d", "a": ["b", "c", "d", "a"]}
- self.assertFalse(equal(dict_1, dict_2))
-
-
-class TestListEqual(TestCase):
- def test_equal_lists(self):
- list_1 = ["a", "b", "c"]
- list_2 = ["a", "b", "c"]
- self.assertTrue(equal(list_1, list_2))
-
- def test_unsorted_lists(self):
- list_1 = ["a", "b", "c"]
- list_2 = ["b", "b", "a"]
- self.assertFalse(equal(list_1, list_2))
-
- def test_first_list_larger(self):
- list_1 = ["a", "b", "c"]
- list_2 = ["a", "b"]
- self.assertFalse(equal(list_1, list_2))
-
- def test_second_list_larger(self):
- list_1 = ["a", "b"]
- list_2 = ["a", "b", "c"]
- self.assertFalse(equal(list_1, list_2))
-
- def test_list_with_none_unequal(self):
- list_1 = ["a", "b", None]
- list_2 = ["a", "b", "c"]
- self.assertFalse(equal(list_1, list_2))
-
- list_1 = ["a", "b", None]
- list_2 = [None, "b", "c"]
- self.assertFalse(equal(list_1, list_2))
-
- def test_list_with_none_equal(self):
- list_1 = ["a", None, "c"]
- list_2 = ["a", None, "c"]
- self.assertTrue(equal(list_1, list_2))
-
- def test_empty_list(self):
- list_1 = []
- list_2 = []
- self.assertTrue(equal(list_1, list_2))
-
- def test_one_none(self):
- list_1 = None
- list_2 = []
- self.assertFalse(equal(list_1, list_2))
-
- def test_same_list(self):
- list_1 = ["a", "b", "c"]
- self.assertTrue(equal(list_1, list_1))
-
- def test_equal_nested_lists(self):
- list_1 = ["a", ["b", "c"], "d"]
- list_2 = ["a", ["b", "c"], "d"]
- self.assertTrue(equal(list_1, list_2))
-
- def test_unequal_nested_lists(self):
- list_1 = ["a", ["b", "c"], "d"]
- list_2 = ["a", [], "c"]
- self.assertFalse(equal(list_1, list_2))
diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py
deleted file mode 100644
index 16fa9ec..0000000
--- a/jsonschema/tests/test_validators.py
+++ /dev/null
@@ -1,2183 +0,0 @@
-from __future__ import annotations
-
-from collections import deque, namedtuple
-from contextlib import contextmanager
-from decimal import Decimal
-from io import BytesIO
-from unittest import TestCase, mock
-from urllib.request import pathname2url
-import json
-import os
-import sys
-import tempfile
-import unittest
-import warnings
-
-import attr
-
-from jsonschema import (
- FormatChecker,
- TypeChecker,
- exceptions,
- protocols,
- validators,
-)
-from jsonschema.tests._helpers import bug
-
-
-def fail(validator, errors, instance, schema):
- for each in errors:
- each.setdefault("message", "You told me to fail!")
- yield exceptions.ValidationError(**each)
-
-
-class TestCreateAndExtend(TestCase):
- def setUp(self):
- self.addCleanup(
- self.assertEqual,
- validators._META_SCHEMAS,
- dict(validators._META_SCHEMAS),
- )
-
- self.meta_schema = {"$id": "some://meta/schema"}
- self.validators = {"fail": fail}
- self.type_checker = TypeChecker()
- self.Validator = validators.create(
- meta_schema=self.meta_schema,
- validators=self.validators,
- type_checker=self.type_checker,
- )
-
- def test_attrs(self):
- self.assertEqual(
- (
- self.Validator.VALIDATORS,
- self.Validator.META_SCHEMA,
- self.Validator.TYPE_CHECKER,
- ), (
- self.validators,
- self.meta_schema,
- self.type_checker,
- ),
- )
-
- def test_init(self):
- schema = {"fail": []}
- self.assertEqual(self.Validator(schema).schema, schema)
-
- def test_iter_errors_successful(self):
- schema = {"fail": []}
- validator = self.Validator(schema)
-
- errors = list(validator.iter_errors("hello"))
- self.assertEqual(errors, [])
-
- def test_iter_errors_one_error(self):
- schema = {"fail": [{"message": "Whoops!"}]}
- validator = self.Validator(schema)
-
- expected_error = exceptions.ValidationError(
- "Whoops!",
- instance="goodbye",
- schema=schema,
- validator="fail",
- validator_value=[{"message": "Whoops!"}],
- schema_path=deque(["fail"]),
- )
-
- errors = list(validator.iter_errors("goodbye"))
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0]._contents(), expected_error._contents())
-
- def test_iter_errors_multiple_errors(self):
- schema = {
- "fail": [
- {"message": "First"},
- {"message": "Second!", "validator": "asdf"},
- {"message": "Third"},
- ],
- }
- validator = self.Validator(schema)
-
- errors = list(validator.iter_errors("goodbye"))
- self.assertEqual(len(errors), 3)
-
- def test_if_a_version_is_provided_it_is_registered(self):
- Validator = validators.create(
- meta_schema={"$id": "something"},
- version="my version",
- )
- self.addCleanup(validators._META_SCHEMAS.pop, "something")
- self.assertEqual(Validator.__name__, "MyVersionValidator")
- self.assertEqual(Validator.__qualname__, "MyVersionValidator")
-
- def test_repr(self):
- Validator = validators.create(
- meta_schema={"$id": "something"},
- version="my version",
- )
- self.addCleanup(validators._META_SCHEMAS.pop, "something")
- self.assertEqual(
- repr(Validator({})),
- "MyVersionValidator(schema={}, format_checker=None)",
- )
-
- def test_long_repr(self):
- Validator = validators.create(
- meta_schema={"$id": "something"},
- version="my version",
- )
- self.addCleanup(validators._META_SCHEMAS.pop, "something")
- self.assertEqual(
- repr(Validator({"a": list(range(1000))})), (
- "MyVersionValidator(schema={'a': [0, 1, 2, 3, 4, 5, ...]}, "
- "format_checker=None)"
- ),
- )
-
- def test_repr_no_version(self):
- Validator = validators.create(meta_schema={})
- self.assertEqual(
- repr(Validator({})),
- "Validator(schema={}, format_checker=None)",
- )
-
- def test_dashes_are_stripped_from_validator_names(self):
- Validator = validators.create(
- meta_schema={"$id": "something"},
- version="foo-bar",
- )
- self.addCleanup(validators._META_SCHEMAS.pop, "something")
- self.assertEqual(Validator.__qualname__, "FooBarValidator")
-
- def test_if_a_version_is_not_provided_it_is_not_registered(self):
- original = dict(validators._META_SCHEMAS)
- validators.create(meta_schema={"id": "id"})
- self.assertEqual(validators._META_SCHEMAS, original)
-
- def test_validates_registers_meta_schema_id(self):
- meta_schema_key = "meta schema id"
- my_meta_schema = {"id": meta_schema_key}
-
- validators.create(
- meta_schema=my_meta_schema,
- version="my version",
- id_of=lambda s: s.get("id", ""),
- )
- self.addCleanup(validators._META_SCHEMAS.pop, meta_schema_key)
-
- self.assertIn(meta_schema_key, validators._META_SCHEMAS)
-
- def test_validates_registers_meta_schema_draft6_id(self):
- meta_schema_key = "meta schema $id"
- my_meta_schema = {"$id": meta_schema_key}
-
- validators.create(
- meta_schema=my_meta_schema,
- version="my version",
- )
- self.addCleanup(validators._META_SCHEMAS.pop, meta_schema_key)
-
- self.assertIn(meta_schema_key, validators._META_SCHEMAS)
-
- def test_create_default_types(self):
- Validator = validators.create(meta_schema={}, validators=())
- self.assertTrue(
- all(
- Validator({}).is_type(instance=instance, type=type)
- for type, instance in [
- ("array", []),
- ("boolean", True),
- ("integer", 12),
- ("null", None),
- ("number", 12.0),
- ("object", {}),
- ("string", "foo"),
- ]
- ),
- )
-
- def test_extend(self):
- original = dict(self.Validator.VALIDATORS)
- new = object()
-
- Extended = validators.extend(
- self.Validator,
- validators={"new": new},
- )
- self.assertEqual(
- (
- Extended.VALIDATORS,
- Extended.META_SCHEMA,
- Extended.TYPE_CHECKER,
- self.Validator.VALIDATORS,
- ), (
- dict(original, new=new),
- self.Validator.META_SCHEMA,
- self.Validator.TYPE_CHECKER,
- original,
- ),
- )
-
- def test_extend_idof(self):
- """
- Extending a validator preserves its notion of schema IDs.
- """
- def id_of(schema):
- return schema.get("__test__", self.Validator.ID_OF(schema))
- correct_id = "the://correct/id/"
- meta_schema = {
- "$id": "the://wrong/id/",
- "__test__": correct_id,
- }
- Original = validators.create(
- meta_schema=meta_schema,
- validators=self.validators,
- type_checker=self.type_checker,
- id_of=id_of,
- )
- self.assertEqual(Original.ID_OF(Original.META_SCHEMA), correct_id)
-
- Derived = validators.extend(Original)
- self.assertEqual(Derived.ID_OF(Derived.META_SCHEMA), correct_id)
-
-
-class TestValidationErrorMessages(TestCase):
- def message_for(self, instance, schema, *args, **kwargs):
- cls = kwargs.pop("cls", validators._LATEST_VERSION)
- cls.check_schema(schema)
- validator = cls(schema, *args, **kwargs)
- errors = list(validator.iter_errors(instance))
- self.assertTrue(errors, msg=f"No errors were raised for {instance!r}")
- self.assertEqual(
- len(errors),
- 1,
- msg=f"Expected exactly one error, found {errors!r}",
- )
- return errors[0].message
-
- def test_single_type_failure(self):
- message = self.message_for(instance=1, schema={"type": "string"})
- self.assertEqual(message, "1 is not of type 'string'")
-
- def test_single_type_list_failure(self):
- message = self.message_for(instance=1, schema={"type": ["string"]})
- self.assertEqual(message, "1 is not of type 'string'")
-
- def test_multiple_type_failure(self):
- types = "string", "object"
- message = self.message_for(instance=1, schema={"type": list(types)})
- self.assertEqual(message, "1 is not of type 'string', 'object'")
-
- def test_object_without_title_type_failure(self):
- type = {"type": [{"minimum": 3}]}
- message = self.message_for(
- instance=1,
- schema={"type": [type]},
- cls=validators.Draft3Validator,
- )
- self.assertEqual(
- message,
- "1 is not of type {'type': [{'minimum': 3}]}",
- )
-
- def test_object_with_named_type_failure(self):
- schema = {"type": [{"name": "Foo", "minimum": 3}]}
- message = self.message_for(
- instance=1,
- schema=schema,
- cls=validators.Draft3Validator,
- )
- self.assertEqual(message, "1 is not of type 'Foo'")
-
- def test_minimum(self):
- message = self.message_for(instance=1, schema={"minimum": 2})
- self.assertEqual(message, "1 is less than the minimum of 2")
-
- def test_maximum(self):
- message = self.message_for(instance=1, schema={"maximum": 0})
- self.assertEqual(message, "1 is greater than the maximum of 0")
-
- def test_dependencies_single_element(self):
- depend, on = "bar", "foo"
- schema = {"dependencies": {depend: on}}
- message = self.message_for(
- instance={"bar": 2},
- schema=schema,
- cls=validators.Draft3Validator,
- )
- self.assertEqual(message, "'foo' is a dependency of 'bar'")
-
- def test_dependencies_list_draft3(self):
- depend, on = "bar", "foo"
- schema = {"dependencies": {depend: [on]}}
- message = self.message_for(
- instance={"bar": 2},
- schema=schema,
- cls=validators.Draft3Validator,
- )
- self.assertEqual(message, "'foo' is a dependency of 'bar'")
-
- def test_dependencies_list_draft7(self):
- depend, on = "bar", "foo"
- schema = {"dependencies": {depend: [on]}}
- message = self.message_for(
- instance={"bar": 2},
- schema=schema,
- cls=validators.Draft7Validator,
- )
- self.assertEqual(message, "'foo' is a dependency of 'bar'")
-
- def test_additionalItems_single_failure(self):
- message = self.message_for(
- instance=[2],
- schema={"items": [], "additionalItems": False},
- cls=validators.Draft3Validator,
- )
- self.assertIn("(2 was unexpected)", message)
-
- def test_additionalItems_multiple_failures(self):
- message = self.message_for(
- instance=[1, 2, 3],
- schema={"items": [], "additionalItems": False},
- cls=validators.Draft3Validator,
- )
- self.assertIn("(1, 2, 3 were unexpected)", message)
-
- def test_additionalProperties_single_failure(self):
- additional = "foo"
- schema = {"additionalProperties": False}
- message = self.message_for(instance={additional: 2}, schema=schema)
- self.assertIn("('foo' was unexpected)", message)
-
- def test_additionalProperties_multiple_failures(self):
- schema = {"additionalProperties": False}
- message = self.message_for(
- instance=dict.fromkeys(["foo", "bar"]),
- schema=schema,
- )
-
- self.assertIn(repr("foo"), message)
- self.assertIn(repr("bar"), message)
- self.assertIn("were unexpected)", message)
-
- def test_const(self):
- schema = {"const": 12}
- message = self.message_for(
- instance={"foo": "bar"},
- schema=schema,
- )
- self.assertIn("12 was expected", message)
-
- def test_contains_draft_6(self):
- schema = {"contains": {"const": 12}}
- message = self.message_for(
- instance=[2, {}, []],
- schema=schema,
- cls=validators.Draft6Validator,
- )
- self.assertEqual(
- message,
- "None of [2, {}, []] are valid under the given schema",
- )
-
- def test_invalid_format_default_message(self):
- checker = FormatChecker(formats=())
- checker.checks("thing")(lambda value: False)
-
- schema = {"format": "thing"}
- message = self.message_for(
- instance="bla",
- schema=schema,
- format_checker=checker,
- )
-
- self.assertIn(repr("bla"), message)
- self.assertIn(repr("thing"), message)
- self.assertIn("is not a", message)
-
- def test_additionalProperties_false_patternProperties(self):
- schema = {"type": "object",
- "additionalProperties": False,
- "patternProperties": {
- "^abc$": {"type": "string"},
- "^def$": {"type": "string"},
- }}
- message = self.message_for(
- instance={"zebra": 123},
- schema=schema,
- cls=validators.Draft4Validator,
- )
- self.assertEqual(
- message,
- "{} does not match any of the regexes: {}, {}".format(
- repr("zebra"), repr("^abc$"), repr("^def$"),
- ),
- )
- message = self.message_for(
- instance={"zebra": 123, "fish": 456},
- schema=schema,
- cls=validators.Draft4Validator,
- )
- self.assertEqual(
- message,
- "{}, {} do not match any of the regexes: {}, {}".format(
- repr("fish"), repr("zebra"), repr("^abc$"), repr("^def$"),
- ),
- )
-
- def test_False_schema(self):
- message = self.message_for(
- instance="something",
- schema=False,
- )
- self.assertEqual(message, "False schema does not allow 'something'")
-
- def test_multipleOf(self):
- message = self.message_for(
- instance=3,
- schema={"multipleOf": 2},
- )
- self.assertEqual(message, "3 is not a multiple of 2")
-
- def test_minItems(self):
- message = self.message_for(instance=[], schema={"minItems": 2})
- self.assertEqual(message, "[] is too short")
-
- def test_maxItems(self):
- message = self.message_for(instance=[1, 2, 3], schema={"maxItems": 2})
- self.assertEqual(message, "[1, 2, 3] is too long")
-
- def test_prefixItems_with_items(self):
- message = self.message_for(
- instance=[1, 2, "foo", 5],
- schema={"items": False, "prefixItems": [{}, {}]},
- )
- self.assertEqual(message, "Expected at most 2 items, but found 4")
-
- def test_minLength(self):
- message = self.message_for(
- instance="",
- schema={"minLength": 2},
- )
- self.assertEqual(message, "'' is too short")
-
- def test_maxLength(self):
- message = self.message_for(
- instance="abc",
- schema={"maxLength": 2},
- )
- self.assertEqual(message, "'abc' is too long")
-
- def test_pattern(self):
- message = self.message_for(
- instance="bbb",
- schema={"pattern": "^a*$"},
- )
- self.assertEqual(message, "'bbb' does not match '^a*$'")
-
- def test_does_not_contain(self):
- message = self.message_for(
- instance=[],
- schema={"contains": {"type": "string"}},
- )
- self.assertEqual(
- message,
- "[] does not contain items matching the given schema",
- )
-
- def test_contains_too_few(self):
- message = self.message_for(
- instance=["foo", 1],
- schema={"contains": {"type": "string"}, "minContains": 2},
- )
- self.assertEqual(
- message,
- "Too few items match the given schema "
- "(expected at least 2 but only 1 matched)",
- )
-
- def test_contains_too_few_both_constrained(self):
- message = self.message_for(
- instance=["foo", 1],
- schema={
- "contains": {"type": "string"},
- "minContains": 2,
- "maxContains": 4,
- },
- )
- self.assertEqual(
- message,
- "Too few items match the given schema (expected at least 2 but "
- "only 1 matched)",
- )
-
- def test_contains_too_many(self):
- message = self.message_for(
- instance=["foo", "bar", "baz"],
- schema={"contains": {"type": "string"}, "maxContains": 2},
- )
- self.assertEqual(
- message,
- "Too many items match the given schema (expected at most 2)",
- )
-
- def test_contains_too_many_both_constrained(self):
- message = self.message_for(
- instance=["foo"] * 5,
- schema={
- "contains": {"type": "string"},
- "minContains": 2,
- "maxContains": 4,
- },
- )
- self.assertEqual(
- message,
- "Too many items match the given schema (expected at most 4)",
- )
-
- def test_exclusiveMinimum(self):
- message = self.message_for(
- instance=3,
- schema={"exclusiveMinimum": 5},
- )
- self.assertEqual(
- message,
- "3 is less than or equal to the minimum of 5",
- )
-
- def test_exclusiveMaximum(self):
- message = self.message_for(instance=3, schema={"exclusiveMaximum": 2})
- self.assertEqual(
- message,
- "3 is greater than or equal to the maximum of 2",
- )
-
- def test_required(self):
- message = self.message_for(instance={}, schema={"required": ["foo"]})
- self.assertEqual(message, "'foo' is a required property")
-
- def test_dependentRequired(self):
- message = self.message_for(
- instance={"foo": {}},
- schema={"dependentRequired": {"foo": ["bar"]}},
- )
- self.assertEqual(message, "'bar' is a dependency of 'foo'")
-
- def test_minProperties(self):
- message = self.message_for(instance={}, schema={"minProperties": 2})
- self.assertEqual(message, "{} does not have enough properties")
-
- def test_maxProperties(self):
- message = self.message_for(
- instance={"a": {}, "b": {}, "c": {}},
- schema={"maxProperties": 2},
- )
- self.assertEqual(
- message,
- "{'a': {}, 'b': {}, 'c': {}} has too many properties",
- )
-
- def test_oneOf_matches_none(self):
- message = self.message_for(instance={}, schema={"oneOf": [False]})
- self.assertEqual(
- message,
- "{} is not valid under any of the given schemas",
- )
-
- def test_oneOf_matches_too_many(self):
- message = self.message_for(instance={}, schema={"oneOf": [True, True]})
- self.assertEqual(message, "{} is valid under each of True, True")
-
- def test_unevaluated_items(self):
- schema = {"type": "array", "unevaluatedItems": False}
- message = self.message_for(instance=["foo", "bar"], schema=schema)
- self.assertIn(
- message,
- "Unevaluated items are not allowed ('bar', 'foo' were unexpected)",
- )
-
- def test_unevaluated_items_on_invalid_type(self):
- schema = {"type": "array", "unevaluatedItems": False}
- message = self.message_for(instance="foo", schema=schema)
- self.assertEqual(message, "'foo' is not of type 'array'")
-
- def test_unevaluated_properties(self):
- schema = {"type": "object", "unevaluatedProperties": False}
- message = self.message_for(
- instance={
- "foo": "foo",
- "bar": "bar",
- },
- schema=schema,
- )
- self.assertEqual(
- message,
- "Unevaluated properties are not allowed "
- "('bar', 'foo' were unexpected)",
- )
-
- def test_unevaluated_properties_on_invalid_type(self):
- schema = {"type": "object", "unevaluatedProperties": False}
- message = self.message_for(instance="foo", schema=schema)
- self.assertEqual(message, "'foo' is not of type 'object'")
-
-
-class TestValidationErrorDetails(TestCase):
- # TODO: These really need unit tests for each individual validator, rather
- # than just these higher level tests.
- def test_anyOf(self):
- instance = 5
- schema = {
- "anyOf": [
- {"minimum": 20},
- {"type": "string"},
- ],
- }
-
- validator = validators.Draft4Validator(schema)
- errors = list(validator.iter_errors(instance))
- self.assertEqual(len(errors), 1)
- e = errors[0]
-
- self.assertEqual(e.validator, "anyOf")
- self.assertEqual(e.validator_value, schema["anyOf"])
- self.assertEqual(e.instance, instance)
- self.assertEqual(e.schema, schema)
- self.assertIsNone(e.parent)
-
- self.assertEqual(e.path, deque([]))
- self.assertEqual(e.relative_path, deque([]))
- self.assertEqual(e.absolute_path, deque([]))
- self.assertEqual(e.json_path, "$")
-
- self.assertEqual(e.schema_path, deque(["anyOf"]))
- self.assertEqual(e.relative_schema_path, deque(["anyOf"]))
- self.assertEqual(e.absolute_schema_path, deque(["anyOf"]))
-
- self.assertEqual(len(e.context), 2)
-
- e1, e2 = sorted_errors(e.context)
-
- self.assertEqual(e1.validator, "minimum")
- self.assertEqual(e1.validator_value, schema["anyOf"][0]["minimum"])
- self.assertEqual(e1.instance, instance)
- self.assertEqual(e1.schema, schema["anyOf"][0])
- self.assertIs(e1.parent, e)
-
- self.assertEqual(e1.path, deque([]))
- self.assertEqual(e1.absolute_path, deque([]))
- self.assertEqual(e1.relative_path, deque([]))
- self.assertEqual(e1.json_path, "$")
-
- self.assertEqual(e1.schema_path, deque([0, "minimum"]))
- self.assertEqual(e1.relative_schema_path, deque([0, "minimum"]))
- self.assertEqual(
- e1.absolute_schema_path, deque(["anyOf", 0, "minimum"]),
- )
-
- self.assertFalse(e1.context)
-
- self.assertEqual(e2.validator, "type")
- self.assertEqual(e2.validator_value, schema["anyOf"][1]["type"])
- self.assertEqual(e2.instance, instance)
- self.assertEqual(e2.schema, schema["anyOf"][1])
- self.assertIs(e2.parent, e)
-
- self.assertEqual(e2.path, deque([]))
- self.assertEqual(e2.relative_path, deque([]))
- self.assertEqual(e2.absolute_path, deque([]))
- self.assertEqual(e2.json_path, "$")
-
- self.assertEqual(e2.schema_path, deque([1, "type"]))
- self.assertEqual(e2.relative_schema_path, deque([1, "type"]))
- self.assertEqual(e2.absolute_schema_path, deque(["anyOf", 1, "type"]))
-
- self.assertEqual(len(e2.context), 0)
-
- def test_type(self):
- instance = {"foo": 1}
- schema = {
- "type": [
- {"type": "integer"},
- {
- "type": "object",
- "properties": {"foo": {"enum": [2]}},
- },
- ],
- }
-
- validator = validators.Draft3Validator(schema)
- errors = list(validator.iter_errors(instance))
- self.assertEqual(len(errors), 1)
- e = errors[0]
-
- self.assertEqual(e.validator, "type")
- self.assertEqual(e.validator_value, schema["type"])
- self.assertEqual(e.instance, instance)
- self.assertEqual(e.schema, schema)
- self.assertIsNone(e.parent)
-
- self.assertEqual(e.path, deque([]))
- self.assertEqual(e.relative_path, deque([]))
- self.assertEqual(e.absolute_path, deque([]))
- self.assertEqual(e.json_path, "$")
-
- self.assertEqual(e.schema_path, deque(["type"]))
- self.assertEqual(e.relative_schema_path, deque(["type"]))
- self.assertEqual(e.absolute_schema_path, deque(["type"]))
-
- self.assertEqual(len(e.context), 2)
-
- e1, e2 = sorted_errors(e.context)
-
- self.assertEqual(e1.validator, "type")
- self.assertEqual(e1.validator_value, schema["type"][0]["type"])
- self.assertEqual(e1.instance, instance)
- self.assertEqual(e1.schema, schema["type"][0])
- self.assertIs(e1.parent, e)
-
- self.assertEqual(e1.path, deque([]))
- self.assertEqual(e1.relative_path, deque([]))
- self.assertEqual(e1.absolute_path, deque([]))
- self.assertEqual(e1.json_path, "$")
-
- self.assertEqual(e1.schema_path, deque([0, "type"]))
- self.assertEqual(e1.relative_schema_path, deque([0, "type"]))
- self.assertEqual(e1.absolute_schema_path, deque(["type", 0, "type"]))
-
- self.assertFalse(e1.context)
-
- self.assertEqual(e2.validator, "enum")
- self.assertEqual(e2.validator_value, [2])
- self.assertEqual(e2.instance, 1)
- self.assertEqual(e2.schema, {"enum": [2]})
- self.assertIs(e2.parent, e)
-
- self.assertEqual(e2.path, deque(["foo"]))
- self.assertEqual(e2.relative_path, deque(["foo"]))
- self.assertEqual(e2.absolute_path, deque(["foo"]))
- self.assertEqual(e2.json_path, "$.foo")
-
- self.assertEqual(
- e2.schema_path, deque([1, "properties", "foo", "enum"]),
- )
- self.assertEqual(
- e2.relative_schema_path, deque([1, "properties", "foo", "enum"]),
- )
- self.assertEqual(
- e2.absolute_schema_path,
- deque(["type", 1, "properties", "foo", "enum"]),
- )
-
- self.assertFalse(e2.context)
-
- def test_single_nesting(self):
- instance = {"foo": 2, "bar": [1], "baz": 15, "quux": "spam"}
- schema = {
- "properties": {
- "foo": {"type": "string"},
- "bar": {"minItems": 2},
- "baz": {"maximum": 10, "enum": [2, 4, 6, 8]},
- },
- }
-
- validator = validators.Draft3Validator(schema)
- errors = validator.iter_errors(instance)
- e1, e2, e3, e4 = sorted_errors(errors)
-
- self.assertEqual(e1.path, deque(["bar"]))
- self.assertEqual(e2.path, deque(["baz"]))
- self.assertEqual(e3.path, deque(["baz"]))
- self.assertEqual(e4.path, deque(["foo"]))
-
- self.assertEqual(e1.relative_path, deque(["bar"]))
- self.assertEqual(e2.relative_path, deque(["baz"]))
- self.assertEqual(e3.relative_path, deque(["baz"]))
- self.assertEqual(e4.relative_path, deque(["foo"]))
-
- self.assertEqual(e1.absolute_path, deque(["bar"]))
- self.assertEqual(e2.absolute_path, deque(["baz"]))
- self.assertEqual(e3.absolute_path, deque(["baz"]))
- self.assertEqual(e4.absolute_path, deque(["foo"]))
-
- self.assertEqual(e1.json_path, "$.bar")
- self.assertEqual(e2.json_path, "$.baz")
- self.assertEqual(e3.json_path, "$.baz")
- self.assertEqual(e4.json_path, "$.foo")
-
- self.assertEqual(e1.validator, "minItems")
- self.assertEqual(e2.validator, "enum")
- self.assertEqual(e3.validator, "maximum")
- self.assertEqual(e4.validator, "type")
-
- def test_multiple_nesting(self):
- instance = [1, {"foo": 2, "bar": {"baz": [1]}}, "quux"]
- schema = {
- "type": "string",
- "items": {
- "type": ["string", "object"],
- "properties": {
- "foo": {"enum": [1, 3]},
- "bar": {
- "type": "array",
- "properties": {
- "bar": {"required": True},
- "baz": {"minItems": 2},
- },
- },
- },
- },
- }
-
- validator = validators.Draft3Validator(schema)
- errors = validator.iter_errors(instance)
- e1, e2, e3, e4, e5, e6 = sorted_errors(errors)
-
- self.assertEqual(e1.path, deque([]))
- self.assertEqual(e2.path, deque([0]))
- self.assertEqual(e3.path, deque([1, "bar"]))
- self.assertEqual(e4.path, deque([1, "bar", "bar"]))
- self.assertEqual(e5.path, deque([1, "bar", "baz"]))
- self.assertEqual(e6.path, deque([1, "foo"]))
-
- self.assertEqual(e1.json_path, "$")
- self.assertEqual(e2.json_path, "$[0]")
- self.assertEqual(e3.json_path, "$[1].bar")
- self.assertEqual(e4.json_path, "$[1].bar.bar")
- self.assertEqual(e5.json_path, "$[1].bar.baz")
- self.assertEqual(e6.json_path, "$[1].foo")
-
- self.assertEqual(e1.schema_path, deque(["type"]))
- self.assertEqual(e2.schema_path, deque(["items", "type"]))
- self.assertEqual(
- list(e3.schema_path), ["items", "properties", "bar", "type"],
- )
- self.assertEqual(
- list(e4.schema_path),
- ["items", "properties", "bar", "properties", "bar", "required"],
- )
- self.assertEqual(
- list(e5.schema_path),
- ["items", "properties", "bar", "properties", "baz", "minItems"],
- )
- self.assertEqual(
- list(e6.schema_path), ["items", "properties", "foo", "enum"],
- )
-
- self.assertEqual(e1.validator, "type")
- self.assertEqual(e2.validator, "type")
- self.assertEqual(e3.validator, "type")
- self.assertEqual(e4.validator, "required")
- self.assertEqual(e5.validator, "minItems")
- self.assertEqual(e6.validator, "enum")
-
- def test_recursive(self):
- schema = {
- "definitions": {
- "node": {
- "anyOf": [{
- "type": "object",
- "required": ["name", "children"],
- "properties": {
- "name": {
- "type": "string",
- },
- "children": {
- "type": "object",
- "patternProperties": {
- "^.*$": {
- "$ref": "#/definitions/node",
- },
- },
- },
- },
- }],
- },
- },
- "type": "object",
- "required": ["root"],
- "properties": {"root": {"$ref": "#/definitions/node"}},
- }
-
- instance = {
- "root": {
- "name": "root",
- "children": {
- "a": {
- "name": "a",
- "children": {
- "ab": {
- "name": "ab",
- # missing "children"
- },
- },
- },
- },
- },
- }
- validator = validators.Draft4Validator(schema)
-
- e, = validator.iter_errors(instance)
- self.assertEqual(e.absolute_path, deque(["root"]))
- self.assertEqual(
- e.absolute_schema_path, deque(["properties", "root", "anyOf"]),
- )
- self.assertEqual(e.json_path, "$.root")
-
- e1, = e.context
- self.assertEqual(e1.absolute_path, deque(["root", "children", "a"]))
- self.assertEqual(
- e1.absolute_schema_path, deque(
- [
- "properties",
- "root",
- "anyOf",
- 0,
- "properties",
- "children",
- "patternProperties",
- "^.*$",
- "anyOf",
- ],
- ),
- )
- self.assertEqual(e1.json_path, "$.root.children.a")
-
- e2, = e1.context
- self.assertEqual(
- e2.absolute_path, deque(
- ["root", "children", "a", "children", "ab"],
- ),
- )
- self.assertEqual(
- e2.absolute_schema_path, deque(
- [
- "properties",
- "root",
- "anyOf",
- 0,
- "properties",
- "children",
- "patternProperties",
- "^.*$",
- "anyOf",
- 0,
- "properties",
- "children",
- "patternProperties",
- "^.*$",
- "anyOf",
- ],
- ),
- )
- self.assertEqual(e2.json_path, "$.root.children.a.children.ab")
-
- def test_additionalProperties(self):
- instance = {"bar": "bar", "foo": 2}
- schema = {"additionalProperties": {"type": "integer", "minimum": 5}}
-
- validator = validators.Draft3Validator(schema)
- errors = validator.iter_errors(instance)
- e1, e2 = sorted_errors(errors)
-
- self.assertEqual(e1.path, deque(["bar"]))
- self.assertEqual(e2.path, deque(["foo"]))
-
- self.assertEqual(e1.json_path, "$.bar")
- self.assertEqual(e2.json_path, "$.foo")
-
- self.assertEqual(e1.validator, "type")
- self.assertEqual(e2.validator, "minimum")
-
- def test_patternProperties(self):
- instance = {"bar": 1, "foo": 2}
- schema = {
- "patternProperties": {
- "bar": {"type": "string"},
- "foo": {"minimum": 5},
- },
- }
-
- validator = validators.Draft3Validator(schema)
- errors = validator.iter_errors(instance)
- e1, e2 = sorted_errors(errors)
-
- self.assertEqual(e1.path, deque(["bar"]))
- self.assertEqual(e2.path, deque(["foo"]))
-
- self.assertEqual(e1.json_path, "$.bar")
- self.assertEqual(e2.json_path, "$.foo")
-
- self.assertEqual(e1.validator, "type")
- self.assertEqual(e2.validator, "minimum")
-
- def test_additionalItems(self):
- instance = ["foo", 1]
- schema = {
- "items": [],
- "additionalItems": {"type": "integer", "minimum": 5},
- }
-
- validator = validators.Draft3Validator(schema)
- errors = validator.iter_errors(instance)
- e1, e2 = sorted_errors(errors)
-
- self.assertEqual(e1.path, deque([0]))
- self.assertEqual(e2.path, deque([1]))
-
- self.assertEqual(e1.json_path, "$[0]")
- self.assertEqual(e2.json_path, "$[1]")
-
- self.assertEqual(e1.validator, "type")
- self.assertEqual(e2.validator, "minimum")
-
- def test_additionalItems_with_items(self):
- instance = ["foo", "bar", 1]
- schema = {
- "items": [{}],
- "additionalItems": {"type": "integer", "minimum": 5},
- }
-
- validator = validators.Draft3Validator(schema)
- errors = validator.iter_errors(instance)
- e1, e2 = sorted_errors(errors)
-
- self.assertEqual(e1.path, deque([1]))
- self.assertEqual(e2.path, deque([2]))
-
- self.assertEqual(e1.json_path, "$[1]")
- self.assertEqual(e2.json_path, "$[2]")
-
- self.assertEqual(e1.validator, "type")
- self.assertEqual(e2.validator, "minimum")
-
- def test_propertyNames(self):
- instance = {"foo": 12}
- schema = {"propertyNames": {"not": {"const": "foo"}}}
-
- validator = validators.Draft7Validator(schema)
- error, = validator.iter_errors(instance)
-
- self.assertEqual(error.validator, "not")
- self.assertEqual(
- error.message,
- "'foo' should not be valid under {'const': 'foo'}",
- )
- self.assertEqual(error.path, deque([]))
- self.assertEqual(error.json_path, "$")
- self.assertEqual(error.schema_path, deque(["propertyNames", "not"]))
-
- def test_if_then(self):
- schema = {
- "if": {"const": 12},
- "then": {"const": 13},
- }
-
- validator = validators.Draft7Validator(schema)
- error, = validator.iter_errors(12)
-
- self.assertEqual(error.validator, "const")
- self.assertEqual(error.message, "13 was expected")
- self.assertEqual(error.path, deque([]))
- self.assertEqual(error.json_path, "$")
- self.assertEqual(error.schema_path, deque(["then", "const"]))
-
- def test_if_else(self):
- schema = {
- "if": {"const": 12},
- "else": {"const": 13},
- }
-
- validator = validators.Draft7Validator(schema)
- error, = validator.iter_errors(15)
-
- self.assertEqual(error.validator, "const")
- self.assertEqual(error.message, "13 was expected")
- self.assertEqual(error.path, deque([]))
- self.assertEqual(error.json_path, "$")
- self.assertEqual(error.schema_path, deque(["else", "const"]))
-
- def test_boolean_schema_False(self):
- validator = validators.Draft7Validator(False)
- error, = validator.iter_errors(12)
-
- self.assertEqual(
- (
- error.message,
- error.validator,
- error.validator_value,
- error.instance,
- error.schema,
- error.schema_path,
- error.json_path,
- ),
- (
- "False schema does not allow 12",
- None,
- None,
- 12,
- False,
- deque([]),
- "$",
- ),
- )
-
- def test_ref(self):
- ref, schema = "someRef", {"additionalProperties": {"type": "integer"}}
- validator = validators.Draft7Validator(
- {"$ref": ref},
- resolver=validators.RefResolver("", {}, store={ref: schema}),
- )
- error, = validator.iter_errors({"foo": "notAnInteger"})
-
- self.assertEqual(
- (
- error.message,
- error.validator,
- error.validator_value,
- error.instance,
- error.absolute_path,
- error.schema,
- error.schema_path,
- error.json_path,
- ),
- (
- "'notAnInteger' is not of type 'integer'",
- "type",
- "integer",
- "notAnInteger",
- deque(["foo"]),
- {"type": "integer"},
- deque(["additionalProperties", "type"]),
- "$.foo",
- ),
- )
-
- def test_prefixItems(self):
- schema = {"prefixItems": [{"type": "string"}, {}, {}, {"maximum": 3}]}
- validator = validators.Draft202012Validator(schema)
- type_error, min_error = validator.iter_errors([1, 2, "foo", 5])
- self.assertEqual(
- (
- type_error.message,
- type_error.validator,
- type_error.validator_value,
- type_error.instance,
- type_error.absolute_path,
- type_error.schema,
- type_error.schema_path,
- type_error.json_path,
- ),
- (
- "1 is not of type 'string'",
- "type",
- "string",
- 1,
- deque([0]),
- {"type": "string"},
- deque(["prefixItems", 0, "type"]),
- "$[0]",
- ),
- )
- self.assertEqual(
- (
- min_error.message,
- min_error.validator,
- min_error.validator_value,
- min_error.instance,
- min_error.absolute_path,
- min_error.schema,
- min_error.schema_path,
- min_error.json_path,
- ),
- (
- "5 is greater than the maximum of 3",
- "maximum",
- 3,
- 5,
- deque([3]),
- {"maximum": 3},
- deque(["prefixItems", 3, "maximum"]),
- "$[3]",
- ),
- )
-
- def test_prefixItems_with_items(self):
- schema = {
- "items": {"type": "string"},
- "prefixItems": [{}],
- }
- validator = validators.Draft202012Validator(schema)
- e1, e2 = validator.iter_errors(["foo", 2, "bar", 4, "baz"])
- self.assertEqual(
- (
- e1.message,
- e1.validator,
- e1.validator_value,
- e1.instance,
- e1.absolute_path,
- e1.schema,
- e1.schema_path,
- e1.json_path,
- ),
- (
- "2 is not of type 'string'",
- "type",
- "string",
- 2,
- deque([1]),
- {"type": "string"},
- deque(["items", "type"]),
- "$[1]",
- ),
- )
- self.assertEqual(
- (
- e2.message,
- e2.validator,
- e2.validator_value,
- e2.instance,
- e2.absolute_path,
- e2.schema,
- e2.schema_path,
- e2.json_path,
- ),
- (
- "4 is not of type 'string'",
- "type",
- "string",
- 4,
- deque([3]),
- {"type": "string"},
- deque(["items", "type"]),
- "$[3]",
- ),
- )
-
- def test_contains_too_many(self):
- """
- `contains` + `maxContains` produces only one error, even if there are
- many more incorrectly matching elements.
- """
- schema = {"contains": {"type": "string"}, "maxContains": 2}
- validator = validators.Draft202012Validator(schema)
- error, = validator.iter_errors(["foo", 2, "bar", 4, "baz", "quux"])
- self.assertEqual(
- (
- error.message,
- error.validator,
- error.validator_value,
- error.instance,
- error.absolute_path,
- error.schema,
- error.schema_path,
- error.json_path,
- ),
- (
- "Too many items match the given schema (expected at most 2)",
- "maxContains",
- 2,
- ["foo", 2, "bar", 4, "baz", "quux"],
- deque([]),
- {"contains": {"type": "string"}, "maxContains": 2},
- deque(["contains"]),
- "$",
- ),
- )
-
- def test_contains_too_few(self):
- schema = {"contains": {"type": "string"}, "minContains": 2}
- validator = validators.Draft202012Validator(schema)
- error, = validator.iter_errors(["foo", 2, 4])
- self.assertEqual(
- (
- error.message,
- error.validator,
- error.validator_value,
- error.instance,
- error.absolute_path,
- error.schema,
- error.schema_path,
- error.json_path,
- ),
- (
- (
- "Too few items match the given schema "
- "(expected at least 2 but only 1 matched)"
- ),
- "minContains",
- 2,
- ["foo", 2, 4],
- deque([]),
- {"contains": {"type": "string"}, "minContains": 2},
- deque(["contains"]),
- "$",
- ),
- )
-
- def test_contains_none(self):
- schema = {"contains": {"type": "string"}, "minContains": 2}
- validator = validators.Draft202012Validator(schema)
- error, = validator.iter_errors([2, 4])
- self.assertEqual(
- (
- error.message,
- error.validator,
- error.validator_value,
- error.instance,
- error.absolute_path,
- error.schema,
- error.schema_path,
- error.json_path,
- ),
- (
- "[2, 4] does not contain items matching the given schema",
- "contains",
- {"type": "string"},
- [2, 4],
- deque([]),
- {"contains": {"type": "string"}, "minContains": 2},
- deque(["contains"]),
- "$",
- ),
- )
-
- def test_ref_sibling(self):
- schema = {
- "$defs": {"foo": {"required": ["bar"]}},
- "properties": {
- "aprop": {
- "$ref": "#/$defs/foo",
- "required": ["baz"],
- },
- },
- }
-
- validator = validators.Draft202012Validator(schema)
- e1, e2 = validator.iter_errors({"aprop": {}})
- self.assertEqual(
- (
- e1.message,
- e1.validator,
- e1.validator_value,
- e1.instance,
- e1.absolute_path,
- e1.schema,
- e1.schema_path,
- e1.relative_schema_path,
- e1.json_path,
- ),
- (
- "'bar' is a required property",
- "required",
- ["bar"],
- {},
- deque(["aprop"]),
- {"required": ["bar"]},
- deque(["properties", "aprop", "required"]),
- deque(["properties", "aprop", "required"]),
- "$.aprop",
- ),
- )
- self.assertEqual(
- (
- e2.message,
- e2.validator,
- e2.validator_value,
- e2.instance,
- e2.absolute_path,
- e2.schema,
- e2.schema_path,
- e2.relative_schema_path,
- e2.json_path,
- ),
- (
- "'baz' is a required property",
- "required",
- ["baz"],
- {},
- deque(["aprop"]),
- {"$ref": "#/$defs/foo", "required": ["baz"]},
- deque(["properties", "aprop", "required"]),
- deque(["properties", "aprop", "required"]),
- "$.aprop",
- ),
- )
-
-
-class MetaSchemaTestsMixin(object):
- # TODO: These all belong upstream
- def test_invalid_properties(self):
- with self.assertRaises(exceptions.SchemaError):
- self.Validator.check_schema({"properties": 12})
-
- def test_minItems_invalid_string(self):
- with self.assertRaises(exceptions.SchemaError):
- # needs to be an integer
- self.Validator.check_schema({"minItems": "1"})
-
- def test_enum_allows_empty_arrays(self):
- """
- Technically, all the spec says is they SHOULD have elements, not MUST.
-
- See #529.
- """
- self.Validator.check_schema({"enum": []})
-
- def test_enum_allows_non_unique_items(self):
- """
- Technically, all the spec says is they SHOULD be unique, not MUST.
-
- See #529.
- """
- self.Validator.check_schema({"enum": [12, 12]})
-
-
-class ValidatorTestMixin(MetaSchemaTestsMixin, object):
- def test_it_implements_the_validator_protocol(self):
- self.assertIsInstance(self.Validator({}), protocols.Validator)
-
- def test_valid_instances_are_valid(self):
- schema, instance = self.valid
- self.assertTrue(self.Validator(schema).is_valid(instance))
-
- def test_invalid_instances_are_not_valid(self):
- schema, instance = self.invalid
- self.assertFalse(self.Validator(schema).is_valid(instance))
-
- def test_non_existent_properties_are_ignored(self):
- self.Validator({object(): object()}).validate(instance=object())
-
- def test_it_creates_a_ref_resolver_if_not_provided(self):
- self.assertIsInstance(
- self.Validator({}).resolver,
- validators.RefResolver,
- )
-
- def test_it_delegates_to_a_ref_resolver(self):
- ref, schema = "someCoolRef", {"type": "integer"}
- resolver = validators.RefResolver("", {}, store={ref: schema})
- validator = self.Validator({"$ref": ref}, resolver=resolver)
-
- with self.assertRaises(exceptions.ValidationError):
- validator.validate(None)
-
- def test_it_delegates_to_a_legacy_ref_resolver(self):
- """
- Legacy RefResolvers support only the context manager form of
- resolution.
- """
-
- class LegacyRefResolver(object):
- @contextmanager
- def resolving(this, ref):
- self.assertEqual(ref, "the ref")
- yield {"type": "integer"}
-
- resolver = LegacyRefResolver()
- schema = {"$ref": "the ref"}
-
- with self.assertRaises(exceptions.ValidationError):
- self.Validator(schema, resolver=resolver).validate(None)
-
- def test_is_type_is_true_for_valid_type(self):
- self.assertTrue(self.Validator({}).is_type("foo", "string"))
-
- def test_is_type_is_false_for_invalid_type(self):
- self.assertFalse(self.Validator({}).is_type("foo", "array"))
-
- def test_is_type_evades_bool_inheriting_from_int(self):
- self.assertFalse(self.Validator({}).is_type(True, "integer"))
- self.assertFalse(self.Validator({}).is_type(True, "number"))
-
- def test_it_can_validate_with_decimals(self):
- schema = {"items": {"type": "number"}}
- Validator = validators.extend(
- self.Validator,
- type_checker=self.Validator.TYPE_CHECKER.redefine(
- "number",
- lambda checker, thing: isinstance(
- thing, (int, float, Decimal),
- ) and not isinstance(thing, bool),
- ),
- )
-
- validator = Validator(schema)
- validator.validate([1, 1.1, Decimal(1) / Decimal(8)])
-
- invalid = ["foo", {}, [], True, None]
- self.assertEqual(
- [error.instance for error in validator.iter_errors(invalid)],
- invalid,
- )
-
- def test_it_returns_true_for_formats_it_does_not_know_about(self):
- validator = self.Validator(
- {"format": "carrot"}, format_checker=FormatChecker(),
- )
- validator.validate("bugs")
-
- def test_it_does_not_validate_formats_by_default(self):
- validator = self.Validator({})
- self.assertIsNone(validator.format_checker)
-
- def test_it_validates_formats_if_a_checker_is_provided(self):
- checker = FormatChecker()
- bad = ValueError("Bad!")
-
- @checker.checks("foo", raises=ValueError)
- def check(value):
- if value == "good":
- return True
- elif value == "bad":
- raise bad
- else: # pragma: no cover
- self.fail("What is {}? [Baby Don't Hurt Me]".format(value))
-
- validator = self.Validator(
- {"format": "foo"}, format_checker=checker,
- )
-
- validator.validate("good")
- with self.assertRaises(exceptions.ValidationError) as cm:
- validator.validate("bad")
-
- # Make sure original cause is attached
- self.assertIs(cm.exception.cause, bad)
-
- def test_non_string_custom_type(self):
- non_string_type = object()
- schema = {"type": [non_string_type]}
- Crazy = validators.extend(
- self.Validator,
- type_checker=self.Validator.TYPE_CHECKER.redefine(
- non_string_type,
- lambda checker, thing: isinstance(thing, int),
- ),
- )
- Crazy(schema).validate(15)
-
- def test_it_properly_formats_tuples_in_errors(self):
- """
- A tuple instance properly formats validation errors for uniqueItems.
-
- See #224
- """
- TupleValidator = validators.extend(
- self.Validator,
- type_checker=self.Validator.TYPE_CHECKER.redefine(
- "array",
- lambda checker, thing: isinstance(thing, tuple),
- ),
- )
- with self.assertRaises(exceptions.ValidationError) as e:
- TupleValidator({"uniqueItems": True}).validate((1, 1))
- self.assertIn("(1, 1) has non-unique elements", str(e.exception))
-
- def test_check_redefined_sequence(self):
- """
- Allow array to validate against another defined sequence type
- """
- schema = {"type": "array", "uniqueItems": True}
- MyMapping = namedtuple("MyMapping", "a, b")
- Validator = validators.extend(
- self.Validator,
- type_checker=self.Validator.TYPE_CHECKER.redefine_many(
- {
- "array": lambda checker, thing: isinstance(
- thing, (list, deque),
- ),
- "object": lambda checker, thing: isinstance(
- thing, (dict, MyMapping),
- ),
- },
- ),
- )
- validator = Validator(schema)
-
- valid_instances = [
- deque(["a", None, "1", "", True]),
- deque([[False], [0]]),
- [deque([False]), deque([0])],
- [[deque([False])], [deque([0])]],
- [[[[[deque([False])]]]], [[[[deque([0])]]]]],
- [deque([deque([False])]), deque([deque([0])])],
- [MyMapping("a", 0), MyMapping("a", False)],
- [
- MyMapping("a", [deque([0])]),
- MyMapping("a", [deque([False])]),
- ],
- [
- MyMapping("a", [MyMapping("a", deque([0]))]),
- MyMapping("a", [MyMapping("a", deque([False]))]),
- ],
- [deque(deque(deque([False]))), deque(deque(deque([0])))],
- ]
-
- for instance in valid_instances:
- validator.validate(instance)
-
- invalid_instances = [
- deque(["a", "b", "a"]),
- deque([[False], [False]]),
- [deque([False]), deque([False])],
- [[deque([False])], [deque([False])]],
- [[[[[deque([False])]]]], [[[[deque([False])]]]]],
- [deque([deque([False])]), deque([deque([False])])],
- [MyMapping("a", False), MyMapping("a", False)],
- [
- MyMapping("a", [deque([False])]),
- MyMapping("a", [deque([False])]),
- ],
- [
- MyMapping("a", [MyMapping("a", deque([False]))]),
- MyMapping("a", [MyMapping("a", deque([False]))]),
- ],
- [deque(deque(deque([False]))), deque(deque(deque([False])))],
- ]
-
- for instance in invalid_instances:
- with self.assertRaises(exceptions.ValidationError):
- validator.validate(instance)
-
-
-class AntiDraft6LeakMixin(object):
- """
- Make sure functionality from draft 6 doesn't leak backwards in time.
- """
-
- def test_True_is_not_a_schema(self):
- with self.assertRaises(exceptions.SchemaError) as e:
- self.Validator.check_schema(True)
- self.assertIn("True is not of type", str(e.exception))
-
- def test_False_is_not_a_schema(self):
- with self.assertRaises(exceptions.SchemaError) as e:
- self.Validator.check_schema(False)
- self.assertIn("False is not of type", str(e.exception))
-
- @unittest.skip(bug(523))
- def test_True_is_not_a_schema_even_if_you_forget_to_check(self):
- resolver = validators.RefResolver("", {})
- with self.assertRaises(Exception) as e:
- self.Validator(True, resolver=resolver).validate(12)
- self.assertNotIsInstance(e.exception, exceptions.ValidationError)
-
- @unittest.skip(bug(523))
- def test_False_is_not_a_schema_even_if_you_forget_to_check(self):
- resolver = validators.RefResolver("", {})
- with self.assertRaises(Exception) as e:
- self.Validator(False, resolver=resolver).validate(12)
- self.assertNotIsInstance(e.exception, exceptions.ValidationError)
-
-
-class TestDraft3Validator(AntiDraft6LeakMixin, ValidatorTestMixin, TestCase):
- Validator = validators.Draft3Validator
- valid: tuple[dict, dict] = ({}, {})
- invalid = {"type": "integer"}, "foo"
-
- def test_any_type_is_valid_for_type_any(self):
- validator = self.Validator({"type": "any"})
- validator.validate(object())
-
- def test_any_type_is_redefinable(self):
- """
- Sigh, because why not.
- """
- Crazy = validators.extend(
- self.Validator,
- type_checker=self.Validator.TYPE_CHECKER.redefine(
- "any", lambda checker, thing: isinstance(thing, int),
- ),
- )
- validator = Crazy({"type": "any"})
- validator.validate(12)
- with self.assertRaises(exceptions.ValidationError):
- validator.validate("foo")
-
- def test_is_type_is_true_for_any_type(self):
- self.assertTrue(self.Validator({"type": "any"}).is_valid(object()))
-
- def test_is_type_does_not_evade_bool_if_it_is_being_tested(self):
- self.assertTrue(self.Validator({}).is_type(True, "boolean"))
- self.assertTrue(self.Validator({"type": "any"}).is_valid(True))
-
-
-class TestDraft4Validator(AntiDraft6LeakMixin, ValidatorTestMixin, TestCase):
- Validator = validators.Draft4Validator
- valid: tuple[dict, dict] = ({}, {})
- invalid = {"type": "integer"}, "foo"
-
-
-class TestDraft6Validator(ValidatorTestMixin, TestCase):
- Validator = validators.Draft6Validator
- valid: tuple[dict, dict] = ({}, {})
- invalid = {"type": "integer"}, "foo"
-
-
-class TestDraft7Validator(ValidatorTestMixin, TestCase):
- Validator = validators.Draft7Validator
- valid: tuple[dict, dict] = ({}, {})
- invalid = {"type": "integer"}, "foo"
-
-
-class TestDraft201909Validator(ValidatorTestMixin, TestCase):
- Validator = validators.Draft201909Validator
- valid: tuple[dict, dict] = ({}, {})
- invalid = {"type": "integer"}, "foo"
-
-
-class TestDraft202012Validator(ValidatorTestMixin, TestCase):
- Validator = validators.Draft202012Validator
- valid: tuple[dict, dict] = ({}, {})
- invalid = {"type": "integer"}, "foo"
-
-
-class TestValidatorFor(TestCase):
- def test_draft_3(self):
- schema = {"$schema": "http://json-schema.org/draft-03/schema"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft3Validator,
- )
-
- schema = {"$schema": "http://json-schema.org/draft-03/schema#"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft3Validator,
- )
-
- def test_draft_4(self):
- schema = {"$schema": "http://json-schema.org/draft-04/schema"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft4Validator,
- )
-
- schema = {"$schema": "http://json-schema.org/draft-04/schema#"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft4Validator,
- )
-
- def test_draft_6(self):
- schema = {"$schema": "http://json-schema.org/draft-06/schema"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft6Validator,
- )
-
- schema = {"$schema": "http://json-schema.org/draft-06/schema#"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft6Validator,
- )
-
- def test_draft_7(self):
- schema = {"$schema": "http://json-schema.org/draft-07/schema"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft7Validator,
- )
-
- schema = {"$schema": "http://json-schema.org/draft-07/schema#"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft7Validator,
- )
-
- def test_draft_201909(self):
- schema = {"$schema": "https://json-schema.org/draft/2019-09/schema"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft201909Validator,
- )
-
- schema = {"$schema": "https://json-schema.org/draft/2019-09/schema#"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft201909Validator,
- )
-
- def test_draft_202012(self):
- schema = {"$schema": "https://json-schema.org/draft/2020-12/schema"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft202012Validator,
- )
-
- schema = {"$schema": "https://json-schema.org/draft/2020-12/schema#"}
- self.assertIs(
- validators.validator_for(schema),
- validators.Draft202012Validator,
- )
-
- def test_True(self):
- self.assertIs(
- validators.validator_for(True),
- validators._LATEST_VERSION,
- )
-
- def test_False(self):
- self.assertIs(
- validators.validator_for(False),
- validators._LATEST_VERSION,
- )
-
- def test_custom_validator(self):
- Validator = validators.create(
- meta_schema={"id": "meta schema id"},
- version="12",
- id_of=lambda s: s.get("id", ""),
- )
- schema = {"$schema": "meta schema id"}
- self.assertIs(
- validators.validator_for(schema),
- Validator,
- )
-
- def test_custom_validator_draft6(self):
- Validator = validators.create(
- meta_schema={"$id": "meta schema $id"},
- version="13",
- )
- schema = {"$schema": "meta schema $id"}
- self.assertIs(
- validators.validator_for(schema),
- Validator,
- )
-
- def test_validator_for_jsonschema_default(self):
- self.assertIs(validators.validator_for({}), validators._LATEST_VERSION)
-
- def test_validator_for_custom_default(self):
- self.assertIs(validators.validator_for({}, default=None), None)
-
- def test_warns_if_meta_schema_specified_was_not_found(self):
- with self.assertWarns(DeprecationWarning) as cm:
- validators.validator_for(schema={"$schema": "unknownSchema"})
-
- self.assertEqual(cm.filename, __file__)
- self.assertEqual(
- str(cm.warning),
- "The metaschema specified by $schema was not found. "
- "Using the latest draft to validate, but this will raise "
- "an error in the future.",
- )
-
- def test_does_not_warn_if_meta_schema_is_unspecified(self):
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
- validators.validator_for(schema={}, default={})
- self.assertFalse(w)
-
-
-class TestValidate(TestCase):
- def assertUses(self, schema, Validator):
- result = []
- with mock.patch.object(Validator, "check_schema", result.append):
- validators.validate({}, schema)
- self.assertEqual(result, [schema])
-
- def test_draft3_validator_is_chosen(self):
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-03/schema#"},
- Validator=validators.Draft3Validator,
- )
- # Make sure it works without the empty fragment
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-03/schema"},
- Validator=validators.Draft3Validator,
- )
-
- def test_draft4_validator_is_chosen(self):
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-04/schema#"},
- Validator=validators.Draft4Validator,
- )
- # Make sure it works without the empty fragment
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-04/schema"},
- Validator=validators.Draft4Validator,
- )
-
- def test_draft6_validator_is_chosen(self):
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-06/schema#"},
- Validator=validators.Draft6Validator,
- )
- # Make sure it works without the empty fragment
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-06/schema"},
- Validator=validators.Draft6Validator,
- )
-
- def test_draft7_validator_is_chosen(self):
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-07/schema#"},
- Validator=validators.Draft7Validator,
- )
- # Make sure it works without the empty fragment
- self.assertUses(
- schema={"$schema": "http://json-schema.org/draft-07/schema"},
- Validator=validators.Draft7Validator,
- )
-
- def test_draft202012_validator_is_chosen(self):
- self.assertUses(
- schema={
- "$schema": "https://json-schema.org/draft/2020-12/schema#",
- },
- Validator=validators.Draft202012Validator,
- )
- # Make sure it works without the empty fragment
- self.assertUses(
- schema={
- "$schema": "https://json-schema.org/draft/2020-12/schema",
- },
- Validator=validators.Draft202012Validator,
- )
-
- def test_draft202012_validator_is_the_default(self):
- self.assertUses(schema={}, Validator=validators.Draft202012Validator)
-
- def test_validation_error_message(self):
- with self.assertRaises(exceptions.ValidationError) as e:
- validators.validate(12, {"type": "string"})
- self.assertRegex(
- str(e.exception),
- "(?s)Failed validating '.*' in schema.*On instance",
- )
-
- def test_schema_error_message(self):
- with self.assertRaises(exceptions.SchemaError) as e:
- validators.validate(12, {"type": 12})
- self.assertRegex(
- str(e.exception),
- "(?s)Failed validating '.*' in metaschema.*On schema",
- )
-
- def test_it_uses_best_match(self):
- schema = {
- "oneOf": [
- {"type": "number", "minimum": 20},
- {"type": "array"},
- ],
- }
- with self.assertRaises(exceptions.ValidationError) as e:
- validators.validate(12, schema)
- self.assertIn("12 is less than the minimum of 20", str(e.exception))
-
-
-class TestRefResolver(TestCase):
-
- base_uri = ""
- stored_uri = "foo://stored"
- stored_schema = {"stored": "schema"}
-
- def setUp(self):
- self.referrer = {}
- self.store = {self.stored_uri: self.stored_schema}
- self.resolver = validators.RefResolver(
- self.base_uri, self.referrer, self.store,
- )
-
- def test_it_does_not_retrieve_schema_urls_from_the_network(self):
- ref = validators.Draft3Validator.META_SCHEMA["id"]
- with mock.patch.object(self.resolver, "resolve_remote") as patched:
- with self.resolver.resolving(ref) as resolved:
- pass
- self.assertEqual(resolved, validators.Draft3Validator.META_SCHEMA)
- self.assertFalse(patched.called)
-
- def test_it_resolves_local_refs(self):
- ref = "#/properties/foo"
- self.referrer["properties"] = {"foo": object()}
- with self.resolver.resolving(ref) as resolved:
- self.assertEqual(resolved, self.referrer["properties"]["foo"])
-
- def test_it_resolves_local_refs_with_id(self):
- schema = {"id": "http://bar/schema#", "a": {"foo": "bar"}}
- resolver = validators.RefResolver.from_schema(
- schema,
- id_of=lambda schema: schema.get("id", ""),
- )
- with resolver.resolving("#/a") as resolved:
- self.assertEqual(resolved, schema["a"])
- with resolver.resolving("http://bar/schema#/a") as resolved:
- self.assertEqual(resolved, schema["a"])
-
- def test_it_retrieves_stored_refs(self):
- with self.resolver.resolving(self.stored_uri) as resolved:
- self.assertIs(resolved, self.stored_schema)
-
- self.resolver.store["cached_ref"] = {"foo": 12}
- with self.resolver.resolving("cached_ref#/foo") as resolved:
- self.assertEqual(resolved, 12)
-
- def test_it_retrieves_unstored_refs_via_requests(self):
- ref = "http://bar#baz"
- schema = {"baz": 12}
-
- if "requests" in sys.modules:
- self.addCleanup(
- sys.modules.__setitem__, "requests", sys.modules["requests"],
- )
- sys.modules["requests"] = ReallyFakeRequests({"http://bar": schema})
-
- with self.resolver.resolving(ref) as resolved:
- self.assertEqual(resolved, 12)
-
- def test_it_retrieves_unstored_refs_via_urlopen(self):
- ref = "http://bar#baz"
- schema = {"baz": 12}
-
- if "requests" in sys.modules:
- self.addCleanup(
- sys.modules.__setitem__, "requests", sys.modules["requests"],
- )
- sys.modules["requests"] = None
-
- @contextmanager
- def fake_urlopen(url):
- self.assertEqual(url, "http://bar")
- yield BytesIO(json.dumps(schema).encode("utf8"))
-
- self.addCleanup(setattr, validators, "urlopen", validators.urlopen)
- validators.urlopen = fake_urlopen
-
- with self.resolver.resolving(ref) as resolved:
- pass
- self.assertEqual(resolved, 12)
-
- def test_it_retrieves_local_refs_via_urlopen(self):
- with tempfile.NamedTemporaryFile(delete=False, mode="wt") as tempf:
- self.addCleanup(os.remove, tempf.name)
- json.dump({"foo": "bar"}, tempf)
-
- ref = "file://{}#foo".format(pathname2url(tempf.name))
- with self.resolver.resolving(ref) as resolved:
- self.assertEqual(resolved, "bar")
-
- def test_it_can_construct_a_base_uri_from_a_schema(self):
- schema = {"id": "foo"}
- resolver = validators.RefResolver.from_schema(
- schema,
- id_of=lambda schema: schema.get("id", ""),
- )
- self.assertEqual(resolver.base_uri, "foo")
- self.assertEqual(resolver.resolution_scope, "foo")
- with resolver.resolving("") as resolved:
- self.assertEqual(resolved, schema)
- with resolver.resolving("#") as resolved:
- self.assertEqual(resolved, schema)
- with resolver.resolving("foo") as resolved:
- self.assertEqual(resolved, schema)
- with resolver.resolving("foo#") as resolved:
- self.assertEqual(resolved, schema)
-
- def test_it_can_construct_a_base_uri_from_a_schema_without_id(self):
- schema = {}
- resolver = validators.RefResolver.from_schema(schema)
- self.assertEqual(resolver.base_uri, "")
- self.assertEqual(resolver.resolution_scope, "")
- with resolver.resolving("") as resolved:
- self.assertEqual(resolved, schema)
- with resolver.resolving("#") as resolved:
- self.assertEqual(resolved, schema)
-
- def test_custom_uri_scheme_handlers(self):
- def handler(url):
- self.assertEqual(url, ref)
- return schema
-
- schema = {"foo": "bar"}
- ref = "foo://bar"
- resolver = validators.RefResolver("", {}, handlers={"foo": handler})
- with resolver.resolving(ref) as resolved:
- self.assertEqual(resolved, schema)
-
- def test_cache_remote_on(self):
- response = [object()]
-
- def handler(url):
- try:
- return response.pop()
- except IndexError: # pragma: no cover
- self.fail("Response must not have been cached!")
-
- ref = "foo://bar"
- resolver = validators.RefResolver(
- "", {}, cache_remote=True, handlers={"foo": handler},
- )
- with resolver.resolving(ref):
- pass
- with resolver.resolving(ref):
- pass
-
- def test_cache_remote_off(self):
- response = [object()]
-
- def handler(url):
- try:
- return response.pop()
- except IndexError: # pragma: no cover
- self.fail("Handler called twice!")
-
- ref = "foo://bar"
- resolver = validators.RefResolver(
- "", {}, cache_remote=False, handlers={"foo": handler},
- )
- with resolver.resolving(ref):
- pass
-
- def test_if_you_give_it_junk_you_get_a_resolution_error(self):
- error = ValueError("Oh no! What's this?")
-
- def handler(url):
- raise error
-
- ref = "foo://bar"
- resolver = validators.RefResolver("", {}, handlers={"foo": handler})
- with self.assertRaises(exceptions.RefResolutionError) as err:
- with resolver.resolving(ref):
- self.fail("Shouldn't get this far!") # pragma: no cover
- self.assertEqual(err.exception, exceptions.RefResolutionError(error))
-
- def test_helpful_error_message_on_failed_pop_scope(self):
- resolver = validators.RefResolver("", {})
- resolver.pop_scope()
- with self.assertRaises(exceptions.RefResolutionError) as exc:
- resolver.pop_scope()
- self.assertIn("Failed to pop the scope", str(exc.exception))
-
-
-def sorted_errors(errors):
- def key(error):
- return (
- [str(e) for e in error.path],
- [str(e) for e in error.schema_path],
- )
- return sorted(errors, key=key)
-
-
-@attr.s
-class ReallyFakeRequests(object):
-
- _responses = attr.ib()
-
- def get(self, url):
- response = self._responses.get(url)
- if url is None: # pragma: no cover
- raise ValueError("Unknown URL: " + repr(url))
- return _ReallyFakeJSONResponse(json.dumps(response))
-
-
-@attr.s
-class _ReallyFakeJSONResponse(object):
-
- _response = attr.ib()
-
- def json(self):
- return json.loads(self._response)
diff --git a/jsonschema/validators.py b/jsonschema/validators.py
deleted file mode 100644
index 9ead094..0000000
--- a/jsonschema/validators.py
+++ /dev/null
@@ -1,1099 +0,0 @@
-"""
-Creation and extension of validators, with implementations for existing drafts.
-"""
-from __future__ import annotations
-
-from collections import deque
-from collections.abc import Sequence
-from functools import lru_cache
-from operator import methodcaller
-from urllib.parse import unquote, urldefrag, urljoin, urlsplit
-from urllib.request import urlopen
-from warnings import warn
-import contextlib
-import json
-import reprlib
-import typing
-import warnings
-
-import attr
-
-from jsonschema import (
- _format,
- _legacy_validators,
- _types,
- _utils,
- _validators,
- exceptions,
-)
-
-_VALIDATORS: dict[str, typing.Any] = {}
-_META_SCHEMAS = _utils.URIDict()
-_VOCABULARIES: list[tuple[str, typing.Any]] = []
-
-
-def __getattr__(name):
- if name == "ErrorTree":
- warnings.warn(
- "Importing ErrorTree from jsonschema.validators is deprecated. "
- "Instead import it from jsonschema.exceptions.",
- DeprecationWarning,
- stacklevel=2,
- )
- from jsonschema.exceptions import ErrorTree
- return ErrorTree
- elif name == "validators":
- warnings.warn(
- "Accessing jsonschema.validators.validators is deprecated. "
- "Use jsonschema.validators.validator_for with a given schema.",
- DeprecationWarning,
- stacklevel=2,
- )
- return _VALIDATORS
- elif name == "meta_schemas":
- warnings.warn(
- "Accessing jsonschema.validators.meta_schemas is deprecated. "
- "Use jsonschema.validators.validator_for with a given schema.",
- DeprecationWarning,
- stacklevel=2,
- )
- return _META_SCHEMAS
- raise AttributeError(f"module {__name__} has no attribute {name}")
-
-
-def validates(version):
- """
- Register the decorated validator for a ``version`` of the specification.
-
- Registered validators and their meta schemas will be considered when
- parsing ``$schema`` properties' URIs.
-
- Arguments:
-
- version (str):
-
- An identifier to use as the version's name
-
- Returns:
-
- collections.abc.Callable:
-
- a class decorator to decorate the validator with the version
- """
-
- def _validates(cls):
- _VALIDATORS[version] = cls
- meta_schema_id = cls.ID_OF(cls.META_SCHEMA)
- _META_SCHEMAS[meta_schema_id] = cls
- return cls
- return _validates
-
-
-def _id_of(schema):
- """
- Return the ID of a schema for recent JSON Schema drafts.
- """
- if schema is True or schema is False:
- return ""
- return schema.get("$id", "")
-
-
-def _store_schema_list():
- if not _VOCABULARIES:
- _VOCABULARIES.extend(_utils.load_schema("vocabularies").items())
- return [
- (id, validator.META_SCHEMA) for id, validator in _META_SCHEMAS.items()
- ] + _VOCABULARIES
-
-
-def create(
- meta_schema,
- validators=(),
- version=None,
- type_checker=_types.draft202012_type_checker,
- format_checker=_format.draft202012_format_checker,
- id_of=_id_of,
- applicable_validators=methodcaller("items"),
-):
- """
- Create a new validator class.
-
- Arguments:
-
- meta_schema (collections.abc.Mapping):
-
- the meta schema for the new validator class
-
- validators (collections.abc.Mapping):
-
- a mapping from names to callables, where each callable will
- validate the schema property with the given name.
-
- Each callable should take 4 arguments:
-
- 1. a validator instance,
- 2. the value of the property being validated within the
- instance
- 3. the instance
- 4. the schema
-
- version (str):
-
- an identifier for the version that this validator class will
- validate. If provided, the returned validator class will
- have its ``__name__`` set to include the version, and also
- will have `jsonschema.validators.validates` automatically
- called for the given version.
-
- type_checker (jsonschema.TypeChecker):
-
- a type checker, used when applying the :validator:`type` validator.
-
- If unprovided, a `jsonschema.TypeChecker` will be created
- with a set of default types typical of JSON Schema drafts.
-
- format_checker (jsonschema.FormatChecker):
-
- a format checker, used when applying the :validator:`format`
- validator.
-
- If unprovided, a `jsonschema.FormatChecker` will be created
- with a set of default formats typical of JSON Schema drafts.
-
- id_of (collections.abc.Callable):
-
- A function that given a schema, returns its ID.
-
- applicable_validators (collections.abc.Callable):
-
- A function that given a schema, returns the list of applicable
- validators (names and callables) which will be called to
- validate the instance.
-
- Returns:
-
- a new `jsonschema.protocols.Validator` class
- """
- # preemptively don't shadow the `Validator.format_checker` local
- format_checker_arg = format_checker
-
- @attr.s
- class Validator:
-
- VALIDATORS = dict(validators)
- META_SCHEMA = dict(meta_schema)
- TYPE_CHECKER = type_checker
- FORMAT_CHECKER = format_checker_arg
- ID_OF = staticmethod(id_of)
-
- schema = attr.ib(repr=reprlib.repr)
- resolver = attr.ib(default=None, repr=False)
- format_checker = attr.ib(default=None)
- evolve = attr.evolve
-
- def __attrs_post_init__(self):
- if self.resolver is None:
- self.resolver = RefResolver.from_schema(
- self.schema,
- id_of=id_of,
- )
-
- @classmethod
- def check_schema(cls, schema):
- for error in cls(cls.META_SCHEMA).iter_errors(schema):
- raise exceptions.SchemaError.create_from(error)
-
- def iter_errors(self, instance, _schema=None):
- if _schema is not None:
- warnings.warn(
- (
- "Passing a schema to Validator.iter_errors "
- "is deprecated and will be removed in a future "
- "release. Call validator.evolve(schema=new_schema)."
- "iter_errors(...) instead."
- ),
- DeprecationWarning,
- stacklevel=2,
- )
- else:
- _schema = self.schema
-
- if _schema is True:
- return
- elif _schema is False:
- yield exceptions.ValidationError(
- f"False schema does not allow {instance!r}",
- validator=None,
- validator_value=None,
- instance=instance,
- schema=_schema,
- )
- return
-
- scope = id_of(_schema)
- if scope:
- self.resolver.push_scope(scope)
- try:
- for k, v in applicable_validators(_schema):
- validator = self.VALIDATORS.get(k)
- if validator is None:
- continue
-
- errors = validator(self, v, instance, _schema) or ()
- for error in errors:
- # set details if not already set by the called fn
- error._set(
- validator=k,
- validator_value=v,
- instance=instance,
- schema=_schema,
- type_checker=self.TYPE_CHECKER,
- )
- if k not in {"if", "$ref"}:
- error.schema_path.appendleft(k)
- yield error
- finally:
- if scope:
- self.resolver.pop_scope()
-
- def descend(self, instance, schema, path=None, schema_path=None):
- for error in self.evolve(schema=schema).iter_errors(instance):
- if path is not None:
- error.path.appendleft(path)
- if schema_path is not None:
- error.schema_path.appendleft(schema_path)
- yield error
-
- def validate(self, *args, **kwargs):
- for error in self.iter_errors(*args, **kwargs):
- raise error
-
- def is_type(self, instance, type):
- try:
- return self.TYPE_CHECKER.is_type(instance, type)
- except exceptions.UndefinedTypeCheck:
- raise exceptions.UnknownType(type, instance, self.schema)
-
- def is_valid(self, instance, _schema=None):
- if _schema is not None:
- warnings.warn(
- (
- "Passing a schema to Validator.is_valid is deprecated "
- "and will be removed in a future release. Call "
- "validator.evolve(schema=new_schema).is_valid(...) "
- "instead."
- ),
- DeprecationWarning,
- stacklevel=2,
- )
- self = self.evolve(schema=_schema)
-
- error = next(self.iter_errors(instance), None)
- return error is None
-
- if version is not None:
- safe = version.title().replace(" ", "").replace("-", "")
- Validator.__name__ = Validator.__qualname__ = f"{safe}Validator"
- Validator = validates(version)(Validator)
-
- return Validator
-
-
-def extend(
- validator,
- validators=(),
- version=None,
- type_checker=None,
- format_checker=None,
-):
- """
- Create a new validator class by extending an existing one.
-
- Arguments:
-
- validator (jsonschema.protocols.Validator):
-
- an existing validator class
-
- validators (collections.abc.Mapping):
-
- a mapping of new validator callables to extend with, whose
- structure is as in `create`.
-
- .. note::
-
- Any validator callables with the same name as an
- existing one will (silently) replace the old validator
- callable entirely, effectively overriding any validation
- done in the "parent" validator class.
-
- If you wish to instead extend the behavior of a parent's
- validator callable, delegate and call it directly in
- the new validator function by retrieving it using
- ``OldValidator.VALIDATORS["validator_name"]``.
-
- version (str):
-
- a version for the new validator class
-
- type_checker (jsonschema.TypeChecker):
-
- a type checker, used when applying the :validator:`type` validator.
-
- If unprovided, the type checker of the extended
- `jsonschema.protocols.Validator` will be carried along.
-
- format_checker (jsonschema.FormatChecker):
-
- a format checker, used when applying the :validator:`format`
- validator.
-
- If unprovided, the format checker of the extended
- `jsonschema.protocols.Validator` will be carried along.
-
- Returns:
-
- a new `jsonschema.protocols.Validator` class extending the one
- provided
-
- .. note:: Meta Schemas
-
- The new validator class will have its parent's meta schema.
-
- If you wish to change or extend the meta schema in the new
- validator class, modify ``META_SCHEMA`` directly on the returned
- class. Note that no implicit copying is done, so a copy should
- likely be made before modifying it, in order to not affect the
- old validator.
- """
-
- all_validators = dict(validator.VALIDATORS)
- all_validators.update(validators)
-
- if type_checker is None:
- type_checker = validator.TYPE_CHECKER
- if format_checker is None:
- format_checker = validator.FORMAT_CHECKER
- return create(
- meta_schema=validator.META_SCHEMA,
- validators=all_validators,
- version=version,
- type_checker=type_checker,
- format_checker=format_checker,
- id_of=validator.ID_OF,
- )
-
-
-Draft3Validator = create(
- meta_schema=_utils.load_schema("draft3"),
- validators={
- "$ref": _validators.ref,
- "additionalItems": _validators.additionalItems,
- "additionalProperties": _validators.additionalProperties,
- "dependencies": _legacy_validators.dependencies_draft3,
- "disallow": _legacy_validators.disallow_draft3,
- "divisibleBy": _validators.multipleOf,
- "enum": _validators.enum,
- "extends": _legacy_validators.extends_draft3,
- "format": _validators.format,
- "items": _legacy_validators.items_draft3_draft4,
- "maxItems": _validators.maxItems,
- "maxLength": _validators.maxLength,
- "maximum": _legacy_validators.maximum_draft3_draft4,
- "minItems": _validators.minItems,
- "minLength": _validators.minLength,
- "minimum": _legacy_validators.minimum_draft3_draft4,
- "pattern": _validators.pattern,
- "patternProperties": _validators.patternProperties,
- "properties": _legacy_validators.properties_draft3,
- "type": _legacy_validators.type_draft3,
- "uniqueItems": _validators.uniqueItems,
- },
- type_checker=_types.draft3_type_checker,
- format_checker=_format.draft3_format_checker,
- version="draft3",
- id_of=lambda schema: schema.get("id", ""),
- applicable_validators=_legacy_validators.ignore_ref_siblings,
-)
-
-Draft4Validator = create(
- meta_schema=_utils.load_schema("draft4"),
- validators={
- "$ref": _validators.ref,
- "additionalItems": _validators.additionalItems,
- "additionalProperties": _validators.additionalProperties,
- "allOf": _validators.allOf,
- "anyOf": _validators.anyOf,
- "dependencies": _legacy_validators.dependencies_draft4_draft6_draft7,
- "enum": _validators.enum,
- "format": _validators.format,
- "items": _legacy_validators.items_draft3_draft4,
- "maxItems": _validators.maxItems,
- "maxLength": _validators.maxLength,
- "maxProperties": _validators.maxProperties,
- "maximum": _legacy_validators.maximum_draft3_draft4,
- "minItems": _validators.minItems,
- "minLength": _validators.minLength,
- "minProperties": _validators.minProperties,
- "minimum": _legacy_validators.minimum_draft3_draft4,
- "multipleOf": _validators.multipleOf,
- "not": _validators.not_,
- "oneOf": _validators.oneOf,
- "pattern": _validators.pattern,
- "patternProperties": _validators.patternProperties,
- "properties": _validators.properties,
- "required": _validators.required,
- "type": _validators.type,
- "uniqueItems": _validators.uniqueItems,
- },
- type_checker=_types.draft4_type_checker,
- format_checker=_format.draft4_format_checker,
- version="draft4",
- id_of=lambda schema: schema.get("id", ""),
- applicable_validators=_legacy_validators.ignore_ref_siblings,
-)
-
-Draft6Validator = create(
- meta_schema=_utils.load_schema("draft6"),
- validators={
- "$ref": _validators.ref,
- "additionalItems": _validators.additionalItems,
- "additionalProperties": _validators.additionalProperties,
- "allOf": _validators.allOf,
- "anyOf": _validators.anyOf,
- "const": _validators.const,
- "contains": _legacy_validators.contains_draft6_draft7,
- "dependencies": _legacy_validators.dependencies_draft4_draft6_draft7,
- "enum": _validators.enum,
- "exclusiveMaximum": _validators.exclusiveMaximum,
- "exclusiveMinimum": _validators.exclusiveMinimum,
- "format": _validators.format,
- "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,
- "uniqueItems": _validators.uniqueItems,
- },
- type_checker=_types.draft6_type_checker,
- format_checker=_format.draft6_format_checker,
- version="draft6",
- applicable_validators=_legacy_validators.ignore_ref_siblings,
-)
-
-Draft7Validator = create(
- meta_schema=_utils.load_schema("draft7"),
- validators={
- "$ref": _validators.ref,
- "additionalItems": _validators.additionalItems,
- "additionalProperties": _validators.additionalProperties,
- "allOf": _validators.allOf,
- "anyOf": _validators.anyOf,
- "const": _validators.const,
- "contains": _legacy_validators.contains_draft6_draft7,
- "dependencies": _legacy_validators.dependencies_draft4_draft6_draft7,
- "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,
- "uniqueItems": _validators.uniqueItems,
- },
- type_checker=_types.draft7_type_checker,
- format_checker=_format.draft7_format_checker,
- version="draft7",
- applicable_validators=_legacy_validators.ignore_ref_siblings,
-)
-
-Draft201909Validator = create(
- meta_schema=_utils.load_schema("draft2019-09"),
- validators={
- "$recursiveRef": _legacy_validators.recursiveRef,
- "$ref": _validators.ref,
- "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,
- format_checker=_format.draft201909_format_checker,
- version="draft2019-09",
-)
-
-Draft202012Validator = create(
- meta_schema=_utils.load_schema("draft2020-12"),
- validators={
- "$dynamicRef": _validators.dynamicRef,
- "$ref": _validators.ref,
- "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": _validators.items,
- "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,
- "prefixItems": _validators.prefixItems,
- "properties": _validators.properties,
- "propertyNames": _validators.propertyNames,
- "required": _validators.required,
- "type": _validators.type,
- "unevaluatedItems": _validators.unevaluatedItems,
- "unevaluatedProperties": _validators.unevaluatedProperties,
- "uniqueItems": _validators.uniqueItems,
- },
- type_checker=_types.draft202012_type_checker,
- format_checker=_format.draft202012_format_checker,
- version="draft2020-12",
-)
-
-_LATEST_VERSION = Draft202012Validator
-
-
-class RefResolver(object):
- """
- Resolve JSON References.
-
- Arguments:
-
- base_uri (str):
-
- The URI of the referring document
-
- referrer:
-
- The actual referring document
-
- store (dict):
-
- A mapping from URIs to documents to cache
-
- cache_remote (bool):
-
- Whether remote refs should be cached after first resolution
-
- handlers (dict):
-
- A mapping from URI schemes to functions that should be used
- to retrieve them
-
- urljoin_cache (:func:`functools.lru_cache`):
-
- A cache that will be used for caching the results of joining
- the resolution scope to subscopes.
-
- remote_cache (:func:`functools.lru_cache`):
-
- A cache that will be used for caching the results of
- resolved remote URLs.
-
- Attributes:
-
- cache_remote (bool):
-
- Whether remote refs should be cached after first resolution
- """
-
- def __init__(
- self,
- base_uri,
- referrer,
- store=(),
- cache_remote=True,
- handlers=(),
- urljoin_cache=None,
- remote_cache=None,
- ):
- if urljoin_cache is None:
- urljoin_cache = lru_cache(1024)(urljoin)
- if remote_cache is None:
- remote_cache = lru_cache(1024)(self.resolve_from_url)
-
- self.referrer = referrer
- self.cache_remote = cache_remote
- self.handlers = dict(handlers)
-
- self._scopes_stack = [base_uri]
- self.store = _utils.URIDict(_store_schema_list())
- self.store.update(store)
- self.store[base_uri] = referrer
-
- self._urljoin_cache = urljoin_cache
- self._remote_cache = remote_cache
-
- @classmethod
- def from_schema(cls, schema, id_of=_id_of, *args, **kwargs):
- """
- Construct a resolver from a JSON schema object.
-
- Arguments:
-
- schema:
-
- the referring schema
-
- Returns:
-
- `RefResolver`
- """
-
- return cls(base_uri=id_of(schema), referrer=schema, *args, **kwargs)
-
- def push_scope(self, scope):
- """
- Enter a given sub-scope.
-
- Treats further dereferences as being performed underneath the
- given scope.
- """
- self._scopes_stack.append(
- self._urljoin_cache(self.resolution_scope, scope),
- )
-
- def pop_scope(self):
- """
- Exit the most recent entered scope.
-
- Treats further dereferences as being performed underneath the
- original scope.
-
- Don't call this method more times than `push_scope` has been
- called.
- """
- try:
- self._scopes_stack.pop()
- except IndexError:
- raise exceptions.RefResolutionError(
- "Failed to pop the scope from an empty stack. "
- "`pop_scope()` should only be called once for every "
- "`push_scope()`",
- )
-
- @property
- def resolution_scope(self):
- """
- Retrieve the current resolution scope.
- """
- return self._scopes_stack[-1]
-
- @property
- def base_uri(self):
- """
- Retrieve the current base URI, not including any fragment.
- """
- uri, _ = urldefrag(self.resolution_scope)
- return uri
-
- @contextlib.contextmanager
- def in_scope(self, scope):
- """
- Temporarily enter the given scope for the duration of the context.
- """
- warnings.warn(
- "jsonschema.RefResolver.in_scope is deprecated and will be "
- "removed in a future release.",
- DeprecationWarning,
- stacklevel=3,
- )
- self.push_scope(scope)
- try:
- yield
- finally:
- self.pop_scope()
-
- @contextlib.contextmanager
- def resolving(self, ref):
- """
- Resolve the given ``ref`` and enter its resolution scope.
-
- Exits the scope on exit of this context manager.
-
- Arguments:
-
- ref (str):
-
- The reference to resolve
- """
-
- url, resolved = self.resolve(ref)
- self.push_scope(url)
- try:
- yield resolved
- finally:
- self.pop_scope()
-
- def _find_in_referrer(self, key):
- return self._get_subschemas_cache()[key]
-
- @lru_cache() # noqa: B019
- def _get_subschemas_cache(self):
- cache = {key: [] for key in _SUBSCHEMAS_KEYWORDS}
- for keyword, subschema in _search_schema(
- self.referrer, _match_subschema_keywords,
- ):
- cache[keyword].append(subschema)
- return cache
-
- @lru_cache() # noqa: B019
- def _find_in_subschemas(self, url):
- subschemas = self._get_subschemas_cache()["$id"]
- if not subschemas:
- return None
- uri, fragment = urldefrag(url)
- for subschema in subschemas:
- target_uri = self._urljoin_cache(
- self.resolution_scope, subschema["$id"],
- )
- if target_uri.rstrip("/") == uri.rstrip("/"):
- if fragment:
- subschema = self.resolve_fragment(subschema, fragment)
- return url, subschema
- return None
-
- def resolve(self, ref):
- """
- Resolve the given reference.
- """
- url = self._urljoin_cache(self.resolution_scope, ref).rstrip("/")
-
- match = self._find_in_subschemas(url)
- if match is not None:
- return match
-
- return url, self._remote_cache(url)
-
- def resolve_from_url(self, url):
- """
- Resolve the given URL.
- """
- url, fragment = urldefrag(url)
- if url:
- try:
- document = self.store[url]
- except KeyError:
- try:
- document = self.resolve_remote(url)
- except Exception as exc:
- raise exceptions.RefResolutionError(exc)
- else:
- document = self.referrer
-
- return self.resolve_fragment(document, fragment)
-
- def resolve_fragment(self, document, fragment):
- """
- Resolve a ``fragment`` within the referenced ``document``.
-
- Arguments:
-
- document:
-
- The referent document
-
- fragment (str):
-
- a URI fragment to resolve within it
- """
-
- fragment = fragment.lstrip("/")
-
- if not fragment:
- return document
-
- if document is self.referrer:
- find = self._find_in_referrer
- else:
-
- def find(key):
- yield from _search_schema(document, _match_keyword(key))
-
- for keyword in ["$anchor", "$dynamicAnchor"]:
- for subschema in find(keyword):
- if fragment == subschema[keyword]:
- return subschema
- for keyword in ["id", "$id"]:
- for subschema in find(keyword):
- if "#" + fragment == subschema[keyword]:
- return subschema
-
- # Resolve via path
- parts = unquote(fragment).split("/") if fragment else []
- for part in parts:
- part = part.replace("~1", "/").replace("~0", "~")
-
- if isinstance(document, Sequence):
- # Array indexes should be turned into integers
- try:
- part = int(part)
- except ValueError:
- pass
- try:
- document = document[part]
- except (TypeError, LookupError):
- raise exceptions.RefResolutionError(
- f"Unresolvable JSON pointer: {fragment!r}",
- )
-
- return document
-
- def resolve_remote(self, uri):
- """
- Resolve a remote ``uri``.
-
- If called directly, does not check the store first, but after
- retrieving the document at the specified URI it will be saved in
- the store if :attr:`cache_remote` is True.
-
- .. note::
-
- If the requests_ library is present, ``jsonschema`` will use it to
- request the remote ``uri``, so that the correct encoding is
- detected and used.
-
- If it isn't, or if the scheme of the ``uri`` is not ``http`` or
- ``https``, UTF-8 is assumed.
-
- Arguments:
-
- uri (str):
-
- The URI to resolve
-
- Returns:
-
- The retrieved document
-
- .. _requests: https://pypi.org/project/requests/
- """
- try:
- import requests
- except ImportError:
- requests = None
-
- scheme = urlsplit(uri).scheme
-
- if scheme in self.handlers:
- result = self.handlers[scheme](uri)
- elif scheme in ["http", "https"] and requests:
- # Requests has support for detecting the correct encoding of
- # json over http
- result = requests.get(uri).json()
- else:
- # Otherwise, pass off to urllib and assume utf-8
- with urlopen(uri) as url:
- result = json.loads(url.read().decode("utf-8"))
-
- if self.cache_remote:
- self.store[uri] = result
- return result
-
-
-_SUBSCHEMAS_KEYWORDS = ("$id", "id", "$anchor", "$dynamicAnchor")
-
-
-def _match_keyword(keyword):
-
- def matcher(value):
- if keyword in value:
- yield value
-
- return matcher
-
-
-def _match_subschema_keywords(value):
- for keyword in _SUBSCHEMAS_KEYWORDS:
- if keyword in value:
- yield keyword, value
-
-
-def _search_schema(schema, matcher):
- """Breadth-first search routine."""
- values = deque([schema])
- while values:
- value = values.pop()
- if not isinstance(value, dict):
- continue
- yield from matcher(value)
- values.extendleft(value.values())
-
-
-def validate(instance, schema, cls=None, *args, **kwargs):
- """
- Validate an instance under the given schema.
-
- >>> validate([2, 3, 4], {"maxItems": 2})
- Traceback (most recent call last):
- ...
- ValidationError: [2, 3, 4] is too long
-
- :func:`validate` will first verify that the provided schema is
- itself valid, since not doing so can lead to less obvious error
- messages and fail in less obvious or consistent ways.
-
- If you know you have a valid schema already, especially if you
- intend to validate multiple instances with the same schema, you
- likely would prefer using the `Validator.validate` method directly
- on a specific validator (e.g. ``Draft7Validator.validate``).
-
-
- Arguments:
-
- instance:
-
- The instance to validate
-
- schema:
-
- The schema to validate with
-
- cls (Validator):
-
- The class that will be used to validate the instance.
-
- If the ``cls`` argument is not provided, two things will happen
- in accordance with the specification. First, if the schema has a
- :validator:`$schema` property containing a known meta-schema [#]_
- then the proper validator will be used. The specification recommends
- that all schemas contain :validator:`$schema` properties for this
- reason. If no :validator:`$schema` property is found, the default
- validator class is the latest released draft.
-
- Any other provided positional and keyword arguments will be passed
- on when instantiating the ``cls``.
-
- Raises:
-
- `jsonschema.exceptions.ValidationError` if the instance
- is invalid
-
- `jsonschema.exceptions.SchemaError` if the schema itself
- is invalid
-
- .. rubric:: Footnotes
- .. [#] known by a validator registered with
- `jsonschema.validators.validates`
- """
- if cls is None:
- cls = validator_for(schema)
-
- cls.check_schema(schema)
- validator = cls(schema, *args, **kwargs)
- error = exceptions.best_match(validator.iter_errors(instance))
- if error is not None:
- raise error
-
-
-def validator_for(schema, default=_LATEST_VERSION):
- """
- Retrieve the validator class appropriate for validating the given schema.
-
- Uses the :validator:`$schema` property that should be present in the
- given schema to look up the appropriate validator class.
-
- Arguments:
-
- schema (collections.abc.Mapping or bool):
-
- the schema to look at
-
- default:
-
- the default to return if the appropriate validator class
- cannot be determined.
-
- If unprovided, the default is to return the latest supported
- draft.
- """
- if schema is True or schema is False or "$schema" not in schema:
- return default
- if schema["$schema"] not in _META_SCHEMAS:
- warn(
- (
- "The metaschema specified by $schema was not found. "
- "Using the latest draft to validate, but this will raise "
- "an error in the future."
- ),
- DeprecationWarning,
- stacklevel=2,
- )
- return _META_SCHEMAS.get(schema["$schema"], _LATEST_VERSION)
diff --git a/json/package.json b/package.json
index 75da9e2..75da9e2 100644
--- a/json/package.json
+++ b/package.json
diff --git a/pyproject.toml b/pyproject.toml
deleted file mode 100644
index 5041a10..0000000
--- a/pyproject.toml
+++ /dev/null
@@ -1,99 +0,0 @@
-[build-system]
-requires = ["hatchling", "hatch-vcs"]
-build-backend = "hatchling.build"
-
-[tool.hatch.version]
-source = "vcs"
-
-[project]
-name = "jsonschema"
-description = "An implementation of JSON Schema validation for Python"
-readme = "README.rst"
-requires-python = ">=3.7"
-license = {text = "MIT"}
-keywords = ["validation", "data validation", "jsonschema", "json"]
-authors = [
- {email = "Julian+jsonschema@GrayVines.com"},
- {name = "Julian Berman"},
-]
-classifiers = [
- "Development Status :: 5 - Production/Stable",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: MIT License",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- "Programming Language :: Python :: 3.7",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
- "Programming Language :: Python :: 3.10",
- "Programming Language :: Python :: 3.11",
- "Programming Language :: Python :: Implementation :: CPython",
- "Programming Language :: Python :: Implementation :: PyPy",
-]
-dynamic = ["version"]
-
-dependencies = [
- "attrs>=17.4.0",
- "pyrsistent>=0.14.0,!=0.17.0,!=0.17.1,!=0.17.2",
-
- "importlib_metadata;python_version<'3.8'",
- "typing_extensions;python_version<'3.8'",
-
- "importlib_resources>=1.4.0;python_version<'3.9'",
- "pkgutil_resolve_name>=1.3.10;python_version<'3.9'",
-]
-
-[project.optional-dependencies]
-format = [
- "fqdn",
- "idna",
- "isoduration",
- "jsonpointer>1.13",
- "rfc3339-validator",
- "rfc3987",
- "uri_template",
- "webcolors>=1.11",
-]
-format-nongpl = [
- "fqdn",
- "idna",
- "isoduration",
- "jsonpointer>1.13",
- "rfc3339-validator",
- "rfc3986-validator>0.1.0",
- "uri_template",
- "webcolors>=1.11",
-]
-
-[project.scripts]
-jsonschema = "jsonschema.cli:main"
-
-[project.urls]
-Homepage = "https://github.com/python-jsonschema/jsonschema"
-Documentation = "https://python-jsonschema.readthedocs.io/"
-Issues = "https://github.com/python-jsonschema/jsonschema/issues/"
-Funding = "https://github.com/sponsors/Julian"
-Tidelift = "https://tidelift.com/subscription/pkg/pypi-jsonschema?utm_source=pypi-jsonschema&utm_medium=referral&utm_campaign=pypi-link"
-Changelog = "https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst"
-Source = "https://github.com/python-jsonschema/jsonschema"
-
-[tool.isort]
-from_first = true
-include_trailing_comma = true
-multi_line_output = 3
-
-[tool.mypy]
-ignore_missing_imports = true
-
-[tool.pydocstyle]
-match = "(?!(test_|_|compat|cli)).*\\.py" # see PyCQA/pydocstyle#323
-add-select = [
- "D410", # Trailing whitespace plz
-]
-add-ignore = [
- "D107", # Hah, no
- "D200", # 1-line docstrings don't need to be on one line
- "D202", # One line is fine.
- "D412", # Trailing whitespace plz
- "D413", # No trailing whitespace plz
-]
diff --git a/json/remotes/baseUriChange/folderInteger.json b/remotes/baseUriChange/folderInteger.json
index 8b50ea3..8b50ea3 100644
--- a/json/remotes/baseUriChange/folderInteger.json
+++ b/remotes/baseUriChange/folderInteger.json
diff --git a/json/remotes/baseUriChangeFolder/folderInteger.json b/remotes/baseUriChangeFolder/folderInteger.json
index 8b50ea3..8b50ea3 100644
--- a/json/remotes/baseUriChangeFolder/folderInteger.json
+++ b/remotes/baseUriChangeFolder/folderInteger.json
diff --git a/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json b/remotes/baseUriChangeFolderInSubschema/folderInteger.json
index 8b50ea3..8b50ea3 100644
--- a/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json
+++ b/remotes/baseUriChangeFolderInSubschema/folderInteger.json
diff --git a/json/remotes/draft-next/format-assertion-false.json b/remotes/draft-next/format-assertion-false.json
index 1a55fed..1a55fed 100644
--- a/json/remotes/draft-next/format-assertion-false.json
+++ b/remotes/draft-next/format-assertion-false.json
diff --git a/json/remotes/draft-next/format-assertion-true.json b/remotes/draft-next/format-assertion-true.json
index 5862dfe..5862dfe 100644
--- a/json/remotes/draft-next/format-assertion-true.json
+++ b/remotes/draft-next/format-assertion-true.json
diff --git a/json/remotes/draft-next/metaschema-no-validation.json b/remotes/draft-next/metaschema-no-validation.json
index 2b50c05..2b50c05 100644
--- a/json/remotes/draft-next/metaschema-no-validation.json
+++ b/remotes/draft-next/metaschema-no-validation.json
diff --git a/json/remotes/draft2019-09/metaschema-no-validation.json b/remotes/draft2019-09/metaschema-no-validation.json
index 9a54944..9a54944 100644
--- a/json/remotes/draft2019-09/metaschema-no-validation.json
+++ b/remotes/draft2019-09/metaschema-no-validation.json
diff --git a/json/remotes/draft2020-12/format-assertion-false.json b/remotes/draft2020-12/format-assertion-false.json
index f1c64d2..f1c64d2 100644
--- a/json/remotes/draft2020-12/format-assertion-false.json
+++ b/remotes/draft2020-12/format-assertion-false.json
diff --git a/json/remotes/draft2020-12/format-assertion-true.json b/remotes/draft2020-12/format-assertion-true.json
index e3d12c8..e3d12c8 100644
--- a/json/remotes/draft2020-12/format-assertion-true.json
+++ b/remotes/draft2020-12/format-assertion-true.json
diff --git a/json/remotes/draft2020-12/metaschema-no-validation.json b/remotes/draft2020-12/metaschema-no-validation.json
index d71f440..d71f440 100644
--- a/json/remotes/draft2020-12/metaschema-no-validation.json
+++ b/remotes/draft2020-12/metaschema-no-validation.json
diff --git a/json/remotes/extendible-dynamic-ref.json b/remotes/extendible-dynamic-ref.json
index d0bcd37..d0bcd37 100644
--- a/json/remotes/extendible-dynamic-ref.json
+++ b/remotes/extendible-dynamic-ref.json
diff --git a/json/remotes/integer.json b/remotes/integer.json
index 8b50ea3..8b50ea3 100644
--- a/json/remotes/integer.json
+++ b/remotes/integer.json
diff --git a/json/remotes/locationIndependentIdentifier.json b/remotes/locationIndependentIdentifier.json
index 96b17c3..96b17c3 100644
--- a/json/remotes/locationIndependentIdentifier.json
+++ b/remotes/locationIndependentIdentifier.json
diff --git a/json/remotes/locationIndependentIdentifierDraft4.json b/remotes/locationIndependentIdentifierDraft4.json
index eeff1eb..eeff1eb 100644
--- a/json/remotes/locationIndependentIdentifierDraft4.json
+++ b/remotes/locationIndependentIdentifierDraft4.json
diff --git a/json/remotes/locationIndependentIdentifierPre2019.json b/remotes/locationIndependentIdentifierPre2019.json
index e72815c..e72815c 100644
--- a/json/remotes/locationIndependentIdentifierPre2019.json
+++ b/remotes/locationIndependentIdentifierPre2019.json
diff --git a/json/remotes/name-defs.json b/remotes/name-defs.json
index 1dab4a4..1dab4a4 100644
--- a/json/remotes/name-defs.json
+++ b/remotes/name-defs.json
diff --git a/json/remotes/name.json b/remotes/name.json
index fceacb8..fceacb8 100644
--- a/json/remotes/name.json
+++ b/remotes/name.json
diff --git a/json/remotes/nested/foo-ref-string.json b/remotes/nested/foo-ref-string.json
index 9cd2527..9cd2527 100644
--- a/json/remotes/nested/foo-ref-string.json
+++ b/remotes/nested/foo-ref-string.json
diff --git a/json/remotes/nested/string.json b/remotes/nested/string.json
index c2d48c0..c2d48c0 100644
--- a/json/remotes/nested/string.json
+++ b/remotes/nested/string.json
diff --git a/json/remotes/ref-and-definitions.json b/remotes/ref-and-definitions.json
index e0ee802..e0ee802 100644
--- a/json/remotes/ref-and-definitions.json
+++ b/remotes/ref-and-definitions.json
diff --git a/json/remotes/ref-and-defs.json b/remotes/ref-and-defs.json
index 85d06c3..85d06c3 100644
--- a/json/remotes/ref-and-defs.json
+++ b/remotes/ref-and-defs.json
diff --git a/json/remotes/subSchemas-defs.json b/remotes/subSchemas-defs.json
index 50b7b6d..50b7b6d 100644
--- a/json/remotes/subSchemas-defs.json
+++ b/remotes/subSchemas-defs.json
diff --git a/json/remotes/subSchemas.json b/remotes/subSchemas.json
index 9f8030b..9f8030b 100644
--- a/json/remotes/subSchemas.json
+++ b/remotes/subSchemas.json
diff --git a/json/remotes/tree.json b/remotes/tree.json
index a12d98b..a12d98b 100644
--- a/json/remotes/tree.json
+++ b/remotes/tree.json
diff --git a/json/test-schema.json b/test-schema.json
index 5d25031..5d25031 100644
--- a/json/test-schema.json
+++ b/test-schema.json
diff --git a/json/tests/draft-next/additionalProperties.json b/tests/draft-next/additionalProperties.json
index 98b8842..98b8842 100644
--- a/json/tests/draft-next/additionalProperties.json
+++ b/tests/draft-next/additionalProperties.json
diff --git a/json/tests/draft-next/allOf.json b/tests/draft-next/allOf.json
index ec9319e..ec9319e 100644
--- a/json/tests/draft-next/allOf.json
+++ b/tests/draft-next/allOf.json
diff --git a/json/tests/draft-next/anchor.json b/tests/draft-next/anchor.json
index f0fcf02..9744a3c 100644
--- a/json/tests/draft-next/anchor.json
+++ b/tests/draft-next/anchor.json
@@ -159,12 +159,12 @@
},
"tests": [
{
- "description": "$ref should resolve to /$defs/A/allOf/1",
+ "description": "$ref resolves to /$defs/A/allOf/1",
"data": "a",
"valid": true
},
{
- "description": "$ref should not resolve to /$defs/A/allOf/0",
+ "description": "$ref does not resolve to /$defs/A/allOf/0",
"data": 1,
"valid": false
}
diff --git a/json/tests/draft-next/anyOf.json b/tests/draft-next/anyOf.json
index ab5eb38..ab5eb38 100644
--- a/json/tests/draft-next/anyOf.json
+++ b/tests/draft-next/anyOf.json
diff --git a/json/tests/draft-next/boolean_schema.json b/tests/draft-next/boolean_schema.json
index 6d40f23..6d40f23 100644
--- a/json/tests/draft-next/boolean_schema.json
+++ b/tests/draft-next/boolean_schema.json
diff --git a/json/tests/draft-next/const.json b/tests/draft-next/const.json
index 1c2cafc..1c2cafc 100644
--- a/json/tests/draft-next/const.json
+++ b/tests/draft-next/const.json
diff --git a/json/tests/draft-next/contains.json b/tests/draft-next/contains.json
index 5f3d05a..5f3d05a 100644
--- a/json/tests/draft-next/contains.json
+++ b/tests/draft-next/contains.json
diff --git a/json/tests/draft-next/content.json b/tests/draft-next/content.json
index 44688e8..44688e8 100644
--- a/json/tests/draft-next/content.json
+++ b/tests/draft-next/content.json
diff --git a/json/tests/draft-next/default.json b/tests/draft-next/default.json
index 289a9b6..289a9b6 100644
--- a/json/tests/draft-next/default.json
+++ b/tests/draft-next/default.json
diff --git a/json/tests/draft-next/defs.json b/tests/draft-next/defs.json
index 1282164..1282164 100644
--- a/json/tests/draft-next/defs.json
+++ b/tests/draft-next/defs.json
diff --git a/json/tests/draft-next/dependentRequired.json b/tests/draft-next/dependentRequired.json
index c817120..c817120 100644
--- a/json/tests/draft-next/dependentRequired.json
+++ b/tests/draft-next/dependentRequired.json
diff --git a/json/tests/draft-next/dependentSchemas.json b/tests/draft-next/dependentSchemas.json
index 2ba1a75..2ba1a75 100644
--- a/json/tests/draft-next/dependentSchemas.json
+++ b/tests/draft-next/dependentSchemas.json
diff --git a/json/tests/draft-next/dynamicRef.json b/tests/draft-next/dynamicRef.json
index d022856..79f04b5 100644
--- a/json/tests/draft-next/dynamicRef.json
+++ b/tests/draft-next/dynamicRef.json
@@ -374,7 +374,7 @@
]
},
{
- "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.",
+ "description": "$ref and $dynamicAnchor are independent of order - $defs first",
"schema": {
"$id": "http://localhost:1234/strict-extendible-allof-defs-first.json",
"allOf": [
@@ -424,7 +424,7 @@
]
},
{
- "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.",
+ "description": "$ref and $dynamicAnchor are independent of order - $ref first",
"schema": {
"$id": "http://localhost:1234/strict-extendible-allof-ref-first.json",
"allOf": [
diff --git a/json/tests/draft-next/enum.json b/tests/draft-next/enum.json
index f085097..f085097 100644
--- a/json/tests/draft-next/enum.json
+++ b/tests/draft-next/enum.json
diff --git a/json/tests/draft-next/exclusiveMaximum.json b/tests/draft-next/exclusiveMaximum.json
index dc3cd70..dc3cd70 100644
--- a/json/tests/draft-next/exclusiveMaximum.json
+++ b/tests/draft-next/exclusiveMaximum.json
diff --git a/json/tests/draft-next/exclusiveMinimum.json b/tests/draft-next/exclusiveMinimum.json
index b38d7ec..b38d7ec 100644
--- a/json/tests/draft-next/exclusiveMinimum.json
+++ b/tests/draft-next/exclusiveMinimum.json
diff --git a/json/tests/draft-next/format.json b/tests/draft-next/format.json
index a4b51d2..a4b51d2 100644
--- a/json/tests/draft-next/format.json
+++ b/tests/draft-next/format.json
diff --git a/json/tests/draft-next/id.json b/tests/draft-next/id.json
index db7afaf..db7afaf 100644
--- a/json/tests/draft-next/id.json
+++ b/tests/draft-next/id.json
diff --git a/json/tests/draft-next/if-then-else.json b/tests/draft-next/if-then-else.json
index 284e919..284e919 100644
--- a/json/tests/draft-next/if-then-else.json
+++ b/tests/draft-next/if-then-else.json
diff --git a/json/tests/draft-next/infinite-loop-detection.json b/tests/draft-next/infinite-loop-detection.json
index 9c3c362..9c3c362 100644
--- a/json/tests/draft-next/infinite-loop-detection.json
+++ b/tests/draft-next/infinite-loop-detection.json
diff --git a/json/tests/draft-next/items.json b/tests/draft-next/items.json
index 1f0bdcf..01f20e6 100644
--- a/json/tests/draft-next/items.json
+++ b/tests/draft-next/items.json
@@ -214,7 +214,7 @@
]
},
{
- "description": "items should not look in applicators, valid case",
+ "description": "items does not look in applicators, valid case",
"schema": {
"allOf": [
{ "prefixItems": [ { "minimum": 3 } ] }
@@ -223,12 +223,12 @@
},
"tests": [
{
- "description": "prefixItems in allOf should not constrain items, invalid case",
+ "description": "prefixItems in allOf does not constrain items, invalid case",
"data": [ 3, 5 ],
"valid": false
},
{
- "description": "prefixItems in allOf should not constrain items, valid case",
+ "description": "prefixItems in allOf does not constrain items, valid case",
"data": [ 5, 5 ],
"valid": true
}
@@ -254,7 +254,7 @@
]
},
{
- "description": "items should properly handle null data",
+ "description": "items with null",
"schema": {
"items": {
"type": "null"
@@ -262,7 +262,7 @@
},
"tests": [
{
- "description": "null items allowed",
+ "description": "allows null elements",
"data": [ null ],
"valid": true
}
diff --git a/json/tests/draft-next/maxContains.json b/tests/draft-next/maxContains.json
index 7ed1dcf..7ed1dcf 100644
--- a/json/tests/draft-next/maxContains.json
+++ b/tests/draft-next/maxContains.json
diff --git a/json/tests/draft-next/maxItems.json b/tests/draft-next/maxItems.json
index f0c36ab..f0c36ab 100644
--- a/json/tests/draft-next/maxItems.json
+++ b/tests/draft-next/maxItems.json
diff --git a/json/tests/draft-next/maxLength.json b/tests/draft-next/maxLength.json
index 748b4da..748b4da 100644
--- a/json/tests/draft-next/maxLength.json
+++ b/tests/draft-next/maxLength.json
diff --git a/json/tests/draft-next/maxProperties.json b/tests/draft-next/maxProperties.json
index acec142..acec142 100644
--- a/json/tests/draft-next/maxProperties.json
+++ b/tests/draft-next/maxProperties.json
diff --git a/json/tests/draft-next/maximum.json b/tests/draft-next/maximum.json
index 6844a39..6844a39 100644
--- a/json/tests/draft-next/maximum.json
+++ b/tests/draft-next/maximum.json
diff --git a/json/tests/draft-next/minContains.json b/tests/draft-next/minContains.json
index b83d1bd..b83d1bd 100644
--- a/json/tests/draft-next/minContains.json
+++ b/tests/draft-next/minContains.json
diff --git a/json/tests/draft-next/minItems.json b/tests/draft-next/minItems.json
index d3b1872..d3b1872 100644
--- a/json/tests/draft-next/minItems.json
+++ b/tests/draft-next/minItems.json
diff --git a/json/tests/draft-next/minLength.json b/tests/draft-next/minLength.json
index 64db948..64db948 100644
--- a/json/tests/draft-next/minLength.json
+++ b/tests/draft-next/minLength.json
diff --git a/json/tests/draft-next/minProperties.json b/tests/draft-next/minProperties.json
index 9f74f78..9f74f78 100644
--- a/json/tests/draft-next/minProperties.json
+++ b/tests/draft-next/minProperties.json
diff --git a/json/tests/draft-next/minimum.json b/tests/draft-next/minimum.json
index 21ae50e..21ae50e 100644
--- a/json/tests/draft-next/minimum.json
+++ b/tests/draft-next/minimum.json
diff --git a/json/tests/draft-next/multipleOf.json b/tests/draft-next/multipleOf.json
index faa87cf..faa87cf 100644
--- a/json/tests/draft-next/multipleOf.json
+++ b/tests/draft-next/multipleOf.json
diff --git a/json/tests/draft-next/not.json b/tests/draft-next/not.json
index 98de0ed..98de0ed 100644
--- a/json/tests/draft-next/not.json
+++ b/tests/draft-next/not.json
diff --git a/json/tests/draft-next/oneOf.json b/tests/draft-next/oneOf.json
index eeb7ae8..eeb7ae8 100644
--- a/json/tests/draft-next/oneOf.json
+++ b/tests/draft-next/oneOf.json
diff --git a/json/tests/draft2020-12/optional/bignum.json b/tests/draft-next/optional/bignum.json
index 3f49226..94b4a4e 100644
--- a/json/tests/draft2020-12/optional/bignum.json
+++ b/tests/draft-next/optional/bignum.json
@@ -43,7 +43,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "maximum integer comparison",
"schema": { "maximum": 18446744073709551615 },
"tests": [
{
@@ -67,7 +67,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "minimum integer comparison",
"schema": { "minimum": -18446744073709551615 },
"tests": [
{
diff --git a/json/tests/draft-next/optional/dependencies-compatibility.json b/tests/draft-next/optional/dependencies-compatibility.json
index 6eafaf0..6eafaf0 100644
--- a/json/tests/draft-next/optional/dependencies-compatibility.json
+++ b/tests/draft-next/optional/dependencies-compatibility.json
diff --git a/json/tests/draft-next/optional/ecmascript-regex.json b/tests/draft-next/optional/ecmascript-regex.json
index 5bbfc45..9f79d42 100644
--- a/json/tests/draft-next/optional/ecmascript-regex.json
+++ b/tests/draft-next/optional/ecmascript-regex.json
@@ -7,12 +7,12 @@
},
"tests": [
{
- "description": "matches in Python, but should not in jsonschema",
+ "description": "matches in Python, but not in ECMA 262",
"data": "abc\\n",
"valid": false
},
{
- "description": "should match",
+ "description": "matches",
"data": "abc",
"valid": true
}
@@ -342,7 +342,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "pattern with ASCII ranges",
"schema": { "pattern": "[a-z]cole" },
"tests": [
{
@@ -395,7 +395,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "pattern with non-ASCII digits",
"schema": { "pattern": "^\\p{digit}+$" },
"tests": [
{
@@ -480,7 +480,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "patternProperties with ASCII ranges",
"schema": {
"type": "object",
"patternProperties": {
@@ -534,7 +534,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "patternProperties with non-ASCII digits",
"schema": {
"type": "object",
"patternProperties": {
diff --git a/json/tests/draft-next/optional/float-overflow.json b/tests/draft-next/optional/float-overflow.json
index 52ff982..52ff982 100644
--- a/json/tests/draft-next/optional/float-overflow.json
+++ b/tests/draft-next/optional/float-overflow.json
diff --git a/json/tests/draft-next/optional/format-assertion.json b/tests/draft-next/optional/format-assertion.json
index ede922a..ede922a 100644
--- a/json/tests/draft-next/optional/format-assertion.json
+++ b/tests/draft-next/optional/format-assertion.json
diff --git a/json/tests/draft2020-12/optional/format/date-time.json b/tests/draft-next/optional/format/date-time.json
index f4f9933..0911273 100644
--- a/json/tests/draft2020-12/optional/format/date-time.json
+++ b/tests/draft-next/optional/format/date-time.json
@@ -119,12 +119,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the date portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion",
"data": "1963-06-1৪T00:00:00Z",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the time portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion",
"data": "1963-06-11T0৪:00:00Z",
"valid": false
}
diff --git a/json/tests/draft2019-09/optional/format/date.json b/tests/draft-next/optional/format/date.json
index b4f61ee..06c9ea0 100644
--- a/json/tests/draft2019-09/optional/format/date.json
+++ b/tests/draft-next/optional/format/date.json
@@ -214,7 +214,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1963-06-1৪",
"valid": false
}
diff --git a/json/tests/draft2019-09/optional/format/duration.json b/tests/draft-next/optional/format/duration.json
index 741348a..a6acdc1 100644
--- a/json/tests/draft2019-09/optional/format/duration.json
+++ b/tests/draft-next/optional/format/duration.json
@@ -119,7 +119,7 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "P২Y",
"valid": false
}
diff --git a/json/tests/draft-next/optional/format/email.json b/tests/draft-next/optional/format/email.json
index 5ce1c70..5ce1c70 100644
--- a/json/tests/draft-next/optional/format/email.json
+++ b/tests/draft-next/optional/format/email.json
diff --git a/json/tests/draft-next/optional/format/hostname.json b/tests/draft-next/optional/format/hostname.json
index 8a67fda..8a67fda 100644
--- a/json/tests/draft-next/optional/format/hostname.json
+++ b/tests/draft-next/optional/format/hostname.json
diff --git a/json/tests/draft-next/optional/format/idn-email.json b/tests/draft-next/optional/format/idn-email.json
index 6e21374..6e21374 100644
--- a/json/tests/draft-next/optional/format/idn-email.json
+++ b/tests/draft-next/optional/format/idn-email.json
diff --git a/json/tests/draft-next/optional/format/idn-hostname.json b/tests/draft-next/optional/format/idn-hostname.json
index 6c8f86a..6c8f86a 100644
--- a/json/tests/draft-next/optional/format/idn-hostname.json
+++ b/tests/draft-next/optional/format/idn-hostname.json
diff --git a/json/tests/draft2019-09/optional/format/ipv4.json b/tests/draft-next/optional/format/ipv4.json
index 6b166c7..4706581 100644
--- a/json/tests/draft2019-09/optional/format/ipv4.json
+++ b/tests/draft-next/optional/format/ipv4.json
@@ -64,7 +64,7 @@
"valid": false
},
{
- "description": "leading zeroes should be rejected, as they are treated as octals",
+ "description": "invalid leading zeroes, as they are treated as octals",
"comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
"data": "087.10.0.1",
"valid": false
@@ -75,7 +75,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২7.0.0.1",
"valid": false
}
diff --git a/json/tests/draft-next/optional/format/ipv6.json b/tests/draft-next/optional/format/ipv6.json
index 6379927..94368f2 100644
--- a/json/tests/draft-next/optional/format/ipv6.json
+++ b/tests/draft-next/optional/format/ipv6.json
@@ -194,12 +194,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1:2:3:4:5:6:7:৪",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the ipv4 portion also",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion",
"data": "1:2::192.16৪.0.1",
"valid": false
}
diff --git a/json/tests/draft-next/optional/format/iri-reference.json b/tests/draft-next/optional/format/iri-reference.json
index c6b4c22..c6b4c22 100644
--- a/json/tests/draft-next/optional/format/iri-reference.json
+++ b/tests/draft-next/optional/format/iri-reference.json
diff --git a/json/tests/draft-next/optional/format/iri.json b/tests/draft-next/optional/format/iri.json
index a0d12ae..a0d12ae 100644
--- a/json/tests/draft-next/optional/format/iri.json
+++ b/tests/draft-next/optional/format/iri.json
diff --git a/json/tests/draft-next/optional/format/json-pointer.json b/tests/draft-next/optional/format/json-pointer.json
index a0346b5..a0346b5 100644
--- a/json/tests/draft-next/optional/format/json-pointer.json
+++ b/tests/draft-next/optional/format/json-pointer.json
diff --git a/json/tests/draft-next/optional/format/regex.json b/tests/draft-next/optional/format/regex.json
index 3449177..3449177 100644
--- a/json/tests/draft-next/optional/format/regex.json
+++ b/tests/draft-next/optional/format/regex.json
diff --git a/json/tests/draft-next/optional/format/relative-json-pointer.json b/tests/draft-next/optional/format/relative-json-pointer.json
index 9309986..9309986 100644
--- a/json/tests/draft-next/optional/format/relative-json-pointer.json
+++ b/tests/draft-next/optional/format/relative-json-pointer.json
diff --git a/json/tests/draft2020-12/optional/format/time.json b/tests/draft-next/optional/format/time.json
index 5011d78..3142587 100644
--- a/json/tests/draft2020-12/optional/format/time.json
+++ b/tests/draft-next/optional/format/time.json
@@ -189,7 +189,7 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২:00:00Z",
"valid": false
}
diff --git a/json/tests/draft-next/optional/format/uri-reference.json b/tests/draft-next/optional/format/uri-reference.json
index 7cdf228..7cdf228 100644
--- a/json/tests/draft-next/optional/format/uri-reference.json
+++ b/tests/draft-next/optional/format/uri-reference.json
diff --git a/json/tests/draft-next/optional/format/uri-template.json b/tests/draft-next/optional/format/uri-template.json
index df355c5..df355c5 100644
--- a/json/tests/draft-next/optional/format/uri-template.json
+++ b/tests/draft-next/optional/format/uri-template.json
diff --git a/json/tests/draft-next/optional/format/uri.json b/tests/draft-next/optional/format/uri.json
index 792d71a..792d71a 100644
--- a/json/tests/draft-next/optional/format/uri.json
+++ b/tests/draft-next/optional/format/uri.json
diff --git a/json/tests/draft-next/optional/format/uuid.json b/tests/draft-next/optional/format/uuid.json
index e54cbc0..e54cbc0 100644
--- a/json/tests/draft-next/optional/format/uuid.json
+++ b/tests/draft-next/optional/format/uuid.json
diff --git a/json/tests/draft-next/optional/non-bmp-regex.json b/tests/draft-next/optional/non-bmp-regex.json
index dd67af2..dd67af2 100644
--- a/json/tests/draft-next/optional/non-bmp-regex.json
+++ b/tests/draft-next/optional/non-bmp-regex.json
diff --git a/json/tests/draft-next/optional/refOfUnknownKeyword.json b/tests/draft-next/optional/refOfUnknownKeyword.json
index 5b150df..5b150df 100644
--- a/json/tests/draft-next/optional/refOfUnknownKeyword.json
+++ b/tests/draft-next/optional/refOfUnknownKeyword.json
diff --git a/json/tests/draft-next/pattern.json b/tests/draft-next/pattern.json
index 92db0f9..92db0f9 100644
--- a/json/tests/draft-next/pattern.json
+++ b/tests/draft-next/pattern.json
diff --git a/json/tests/draft-next/patternProperties.json b/tests/draft-next/patternProperties.json
index 34b2e85..34b2e85 100644
--- a/json/tests/draft-next/patternProperties.json
+++ b/tests/draft-next/patternProperties.json
diff --git a/json/tests/draft2020-12/prefixItems.json b/tests/draft-next/prefixItems.json
index f72da11..8dc58ed 100644
--- a/json/tests/draft2020-12/prefixItems.json
+++ b/tests/draft-next/prefixItems.json
@@ -79,7 +79,7 @@
]
},
{
- "description": "prefixItems should properly handle null data",
+ "description": "prefixItems properly handles null data",
"schema": {
"prefixItems": [
{
diff --git a/json/tests/draft-next/properties.json b/tests/draft-next/properties.json
index 8c3ed35..8c3ed35 100644
--- a/json/tests/draft-next/properties.json
+++ b/tests/draft-next/properties.json
diff --git a/json/tests/draft-next/propertyNames.json b/tests/draft-next/propertyNames.json
index 8423690..8423690 100644
--- a/json/tests/draft-next/propertyNames.json
+++ b/tests/draft-next/propertyNames.json
diff --git a/json/tests/draft-next/ref.json b/tests/draft-next/ref.json
index 05fea36..189eb41 100644
--- a/json/tests/draft-next/ref.json
+++ b/tests/draft-next/ref.json
@@ -567,12 +567,12 @@
},
"tests": [
{
- "description": "number should pass",
+ "description": "number is valid",
"data": 1,
"valid": true
},
{
- "description": "non-number should fail",
+ "description": "non-number is invalid",
"data": "a",
"valid": false
}
diff --git a/json/tests/draft-next/refRemote.json b/tests/draft-next/refRemote.json
index a844039..a844039 100644
--- a/json/tests/draft-next/refRemote.json
+++ b/tests/draft-next/refRemote.json
diff --git a/json/tests/draft-next/required.json b/tests/draft-next/required.json
index abf18f3..abf18f3 100644
--- a/json/tests/draft-next/required.json
+++ b/tests/draft-next/required.json
diff --git a/json/tests/draft-next/type.json b/tests/draft-next/type.json
index 8304647..8304647 100644
--- a/json/tests/draft-next/type.json
+++ b/tests/draft-next/type.json
diff --git a/json/tests/draft-next/unevaluatedItems.json b/tests/draft-next/unevaluatedItems.json
index eedb19f..eedb19f 100644
--- a/json/tests/draft-next/unevaluatedItems.json
+++ b/tests/draft-next/unevaluatedItems.json
diff --git a/json/tests/draft-next/unevaluatedProperties.json b/tests/draft-next/unevaluatedProperties.json
index e7865d1..e7865d1 100644
--- a/json/tests/draft-next/unevaluatedProperties.json
+++ b/tests/draft-next/unevaluatedProperties.json
diff --git a/json/tests/draft-next/uniqueItems.json b/tests/draft-next/uniqueItems.json
index 85c619d..85c619d 100644
--- a/json/tests/draft-next/uniqueItems.json
+++ b/tests/draft-next/uniqueItems.json
diff --git a/json/tests/draft-next/unknownKeyword.json b/tests/draft-next/unknownKeyword.json
index e46657d..e46657d 100644
--- a/json/tests/draft-next/unknownKeyword.json
+++ b/tests/draft-next/unknownKeyword.json
diff --git a/json/tests/draft-next/vocabulary.json b/tests/draft-next/vocabulary.json
index 65b81ea..65b81ea 100644
--- a/json/tests/draft-next/vocabulary.json
+++ b/tests/draft-next/vocabulary.json
diff --git a/json/tests/draft2019-09/additionalItems.json b/tests/draft2019-09/additionalItems.json
index 454142b..454142b 100644
--- a/json/tests/draft2019-09/additionalItems.json
+++ b/tests/draft2019-09/additionalItems.json
diff --git a/json/tests/draft2019-09/additionalProperties.json b/tests/draft2019-09/additionalProperties.json
index 98b8842..98b8842 100644
--- a/json/tests/draft2019-09/additionalProperties.json
+++ b/tests/draft2019-09/additionalProperties.json
diff --git a/json/tests/draft2019-09/allOf.json b/tests/draft2019-09/allOf.json
index ec9319e..ec9319e 100644
--- a/json/tests/draft2019-09/allOf.json
+++ b/tests/draft2019-09/allOf.json
diff --git a/json/tests/draft2019-09/anchor.json b/tests/draft2019-09/anchor.json
index 4143d1f..7a9e32d 100644
--- a/json/tests/draft2019-09/anchor.json
+++ b/tests/draft2019-09/anchor.json
@@ -159,12 +159,12 @@
},
"tests": [
{
- "description": "$ref should resolve to /$defs/A/allOf/1",
+ "description": "$ref resolves to /$defs/A/allOf/1",
"data": "a",
"valid": true
},
{
- "description": "$ref should not resolve to /$defs/A/allOf/0",
+ "description": "$ref does not resolve to /$defs/A/allOf/0",
"data": 1,
"valid": false
}
diff --git a/json/tests/draft2019-09/anyOf.json b/tests/draft2019-09/anyOf.json
index ab5eb38..ab5eb38 100644
--- a/json/tests/draft2019-09/anyOf.json
+++ b/tests/draft2019-09/anyOf.json
diff --git a/json/tests/draft2019-09/boolean_schema.json b/tests/draft2019-09/boolean_schema.json
index 6d40f23..6d40f23 100644
--- a/json/tests/draft2019-09/boolean_schema.json
+++ b/tests/draft2019-09/boolean_schema.json
diff --git a/json/tests/draft2019-09/const.json b/tests/draft2019-09/const.json
index 1c2cafc..1c2cafc 100644
--- a/json/tests/draft2019-09/const.json
+++ b/tests/draft2019-09/const.json
diff --git a/json/tests/draft2019-09/contains.json b/tests/draft2019-09/contains.json
index a6add6b..a6add6b 100644
--- a/json/tests/draft2019-09/contains.json
+++ b/tests/draft2019-09/contains.json
diff --git a/json/tests/draft2019-09/content.json b/tests/draft2019-09/content.json
index 44688e8..44688e8 100644
--- a/json/tests/draft2019-09/content.json
+++ b/tests/draft2019-09/content.json
diff --git a/json/tests/draft2019-09/default.json b/tests/draft2019-09/default.json
index 289a9b6..289a9b6 100644
--- a/json/tests/draft2019-09/default.json
+++ b/tests/draft2019-09/default.json
diff --git a/json/tests/draft2019-09/defs.json b/tests/draft2019-09/defs.json
index 70e9dc0..70e9dc0 100644
--- a/json/tests/draft2019-09/defs.json
+++ b/tests/draft2019-09/defs.json
diff --git a/json/tests/draft2019-09/dependentRequired.json b/tests/draft2019-09/dependentRequired.json
index c817120..c817120 100644
--- a/json/tests/draft2019-09/dependentRequired.json
+++ b/tests/draft2019-09/dependentRequired.json
diff --git a/json/tests/draft2019-09/dependentSchemas.json b/tests/draft2019-09/dependentSchemas.json
index 2ba1a75..2ba1a75 100644
--- a/json/tests/draft2019-09/dependentSchemas.json
+++ b/tests/draft2019-09/dependentSchemas.json
diff --git a/json/tests/draft2019-09/enum.json b/tests/draft2019-09/enum.json
index f085097..f085097 100644
--- a/json/tests/draft2019-09/enum.json
+++ b/tests/draft2019-09/enum.json
diff --git a/json/tests/draft2019-09/exclusiveMaximum.json b/tests/draft2019-09/exclusiveMaximum.json
index dc3cd70..dc3cd70 100644
--- a/json/tests/draft2019-09/exclusiveMaximum.json
+++ b/tests/draft2019-09/exclusiveMaximum.json
diff --git a/json/tests/draft2019-09/exclusiveMinimum.json b/tests/draft2019-09/exclusiveMinimum.json
index b38d7ec..b38d7ec 100644
--- a/json/tests/draft2019-09/exclusiveMinimum.json
+++ b/tests/draft2019-09/exclusiveMinimum.json
diff --git a/json/tests/draft2019-09/format.json b/tests/draft2019-09/format.json
index a4b51d2..a4b51d2 100644
--- a/json/tests/draft2019-09/format.json
+++ b/tests/draft2019-09/format.json
diff --git a/json/tests/draft2019-09/id.json b/tests/draft2019-09/id.json
index 0d825ea..0d825ea 100644
--- a/json/tests/draft2019-09/id.json
+++ b/tests/draft2019-09/id.json
diff --git a/json/tests/draft2019-09/if-then-else.json b/tests/draft2019-09/if-then-else.json
index 284e919..284e919 100644
--- a/json/tests/draft2019-09/if-then-else.json
+++ b/tests/draft2019-09/if-then-else.json
diff --git a/json/tests/draft2019-09/infinite-loop-detection.json b/tests/draft2019-09/infinite-loop-detection.json
index 9c3c362..9c3c362 100644
--- a/json/tests/draft2019-09/infinite-loop-detection.json
+++ b/tests/draft2019-09/infinite-loop-detection.json
diff --git a/json/tests/draft2019-09/items.json b/tests/draft2019-09/items.json
index 58992fc..c77ba0b 100644
--- a/json/tests/draft2019-09/items.json
+++ b/tests/draft2019-09/items.json
@@ -263,7 +263,7 @@
]
},
{
- "description": "array-form items should properly handle null data",
+ "description": "array-form items with null instance elements",
"schema": {
"items": [
{
@@ -273,7 +273,7 @@
},
"tests": [
{
- "description": "null items allowed",
+ "description": "allows null elements",
"data": [ null ],
"valid": true
}
diff --git a/json/tests/draft2019-09/maxContains.json b/tests/draft2019-09/maxContains.json
index 61c967d..61c967d 100644
--- a/json/tests/draft2019-09/maxContains.json
+++ b/tests/draft2019-09/maxContains.json
diff --git a/json/tests/draft2019-09/maxItems.json b/tests/draft2019-09/maxItems.json
index f0c36ab..f0c36ab 100644
--- a/json/tests/draft2019-09/maxItems.json
+++ b/tests/draft2019-09/maxItems.json
diff --git a/json/tests/draft2019-09/maxLength.json b/tests/draft2019-09/maxLength.json
index 748b4da..748b4da 100644
--- a/json/tests/draft2019-09/maxLength.json
+++ b/tests/draft2019-09/maxLength.json
diff --git a/json/tests/draft2019-09/maxProperties.json b/tests/draft2019-09/maxProperties.json
index acec142..acec142 100644
--- a/json/tests/draft2019-09/maxProperties.json
+++ b/tests/draft2019-09/maxProperties.json
diff --git a/json/tests/draft2019-09/maximum.json b/tests/draft2019-09/maximum.json
index 6844a39..6844a39 100644
--- a/json/tests/draft2019-09/maximum.json
+++ b/tests/draft2019-09/maximum.json
diff --git a/json/tests/draft2019-09/minContains.json b/tests/draft2019-09/minContains.json
index 1d3b5a5..1d3b5a5 100644
--- a/json/tests/draft2019-09/minContains.json
+++ b/tests/draft2019-09/minContains.json
diff --git a/json/tests/draft2019-09/minItems.json b/tests/draft2019-09/minItems.json
index d3b1872..d3b1872 100644
--- a/json/tests/draft2019-09/minItems.json
+++ b/tests/draft2019-09/minItems.json
diff --git a/json/tests/draft2019-09/minLength.json b/tests/draft2019-09/minLength.json
index 64db948..64db948 100644
--- a/json/tests/draft2019-09/minLength.json
+++ b/tests/draft2019-09/minLength.json
diff --git a/json/tests/draft2019-09/minProperties.json b/tests/draft2019-09/minProperties.json
index 9f74f78..9f74f78 100644
--- a/json/tests/draft2019-09/minProperties.json
+++ b/tests/draft2019-09/minProperties.json
diff --git a/json/tests/draft2019-09/minimum.json b/tests/draft2019-09/minimum.json
index 21ae50e..21ae50e 100644
--- a/json/tests/draft2019-09/minimum.json
+++ b/tests/draft2019-09/minimum.json
diff --git a/json/tests/draft2019-09/multipleOf.json b/tests/draft2019-09/multipleOf.json
index faa87cf..faa87cf 100644
--- a/json/tests/draft2019-09/multipleOf.json
+++ b/tests/draft2019-09/multipleOf.json
diff --git a/json/tests/draft2019-09/not.json b/tests/draft2019-09/not.json
index 98de0ed..98de0ed 100644
--- a/json/tests/draft2019-09/not.json
+++ b/tests/draft2019-09/not.json
diff --git a/json/tests/draft2019-09/oneOf.json b/tests/draft2019-09/oneOf.json
index eeb7ae8..eeb7ae8 100644
--- a/json/tests/draft2019-09/oneOf.json
+++ b/tests/draft2019-09/oneOf.json
diff --git a/json/tests/draft2019-09/optional/bignum.json b/tests/draft2019-09/optional/bignum.json
index 3f49226..94b4a4e 100644
--- a/json/tests/draft2019-09/optional/bignum.json
+++ b/tests/draft2019-09/optional/bignum.json
@@ -43,7 +43,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "maximum integer comparison",
"schema": { "maximum": 18446744073709551615 },
"tests": [
{
@@ -67,7 +67,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "minimum integer comparison",
"schema": { "minimum": -18446744073709551615 },
"tests": [
{
diff --git a/json/tests/draft2019-09/optional/dependencies-compatibility.json b/tests/draft2019-09/optional/dependencies-compatibility.json
index 6eafaf0..6eafaf0 100644
--- a/json/tests/draft2019-09/optional/dependencies-compatibility.json
+++ b/tests/draft2019-09/optional/dependencies-compatibility.json
diff --git a/json/tests/draft2019-09/optional/ecmascript-regex.json b/tests/draft2019-09/optional/ecmascript-regex.json
index 1beb0b3..764248f 100644
--- a/json/tests/draft2019-09/optional/ecmascript-regex.json
+++ b/tests/draft2019-09/optional/ecmascript-regex.json
@@ -7,12 +7,12 @@
},
"tests": [
{
- "description": "matches in Python, but should not in jsonschema",
+ "description": "matches in Python, but not in ECMA 262",
"data": "abc\\n",
"valid": false
},
{
- "description": "should match",
+ "description": "matches",
"data": "abc",
"valid": true
}
@@ -342,7 +342,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "pattern with ASCII ranges",
"schema": { "pattern": "[a-z]cole" },
"tests": [
{
@@ -384,7 +384,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "pattern with non-ASCII digits",
"schema": { "pattern": "^\\p{digit}+$" },
"tests": [
{
@@ -469,7 +469,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "patternProperties with ASCII ranges",
"schema": {
"type": "object",
"patternProperties": {
@@ -523,7 +523,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "patternProperties with non-ASCII digits",
"schema": {
"type": "object",
"patternProperties": {
diff --git a/json/tests/draft2019-09/optional/float-overflow.json b/tests/draft2019-09/optional/float-overflow.json
index 52ff982..52ff982 100644
--- a/json/tests/draft2019-09/optional/float-overflow.json
+++ b/tests/draft2019-09/optional/float-overflow.json
diff --git a/json/tests/draft2019-09/optional/format/date-time.json b/tests/draft2019-09/optional/format/date-time.json
index f4f9933..0911273 100644
--- a/json/tests/draft2019-09/optional/format/date-time.json
+++ b/tests/draft2019-09/optional/format/date-time.json
@@ -119,12 +119,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the date portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion",
"data": "1963-06-1৪T00:00:00Z",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the time portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion",
"data": "1963-06-11T0৪:00:00Z",
"valid": false
}
diff --git a/json/tests/draft2020-12/optional/format/date.json b/tests/draft2019-09/optional/format/date.json
index b4f61ee..06c9ea0 100644
--- a/json/tests/draft2020-12/optional/format/date.json
+++ b/tests/draft2019-09/optional/format/date.json
@@ -214,7 +214,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1963-06-1৪",
"valid": false
}
diff --git a/json/tests/draft2020-12/optional/format/duration.json b/tests/draft2019-09/optional/format/duration.json
index 741348a..a6acdc1 100644
--- a/json/tests/draft2020-12/optional/format/duration.json
+++ b/tests/draft2019-09/optional/format/duration.json
@@ -119,7 +119,7 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "P২Y",
"valid": false
}
diff --git a/json/tests/draft2019-09/optional/format/email.json b/tests/draft2019-09/optional/format/email.json
index d6761a4..d6761a4 100644
--- a/json/tests/draft2019-09/optional/format/email.json
+++ b/tests/draft2019-09/optional/format/email.json
diff --git a/json/tests/draft2019-09/optional/format/hostname.json b/tests/draft2019-09/optional/format/hostname.json
index 8a67fda..8a67fda 100644
--- a/json/tests/draft2019-09/optional/format/hostname.json
+++ b/tests/draft2019-09/optional/format/hostname.json
diff --git a/json/tests/draft2019-09/optional/format/idn-email.json b/tests/draft2019-09/optional/format/idn-email.json
index 6e21374..6e21374 100644
--- a/json/tests/draft2019-09/optional/format/idn-email.json
+++ b/tests/draft2019-09/optional/format/idn-email.json
diff --git a/json/tests/draft2019-09/optional/format/idn-hostname.json b/tests/draft2019-09/optional/format/idn-hostname.json
index 6c8f86a..6c8f86a 100644
--- a/json/tests/draft2019-09/optional/format/idn-hostname.json
+++ b/tests/draft2019-09/optional/format/idn-hostname.json
diff --git a/json/tests/draft2020-12/optional/format/ipv4.json b/tests/draft2019-09/optional/format/ipv4.json
index 6b166c7..4706581 100644
--- a/json/tests/draft2020-12/optional/format/ipv4.json
+++ b/tests/draft2019-09/optional/format/ipv4.json
@@ -64,7 +64,7 @@
"valid": false
},
{
- "description": "leading zeroes should be rejected, as they are treated as octals",
+ "description": "invalid leading zeroes, as they are treated as octals",
"comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
"data": "087.10.0.1",
"valid": false
@@ -75,7 +75,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২7.0.0.1",
"valid": false
}
diff --git a/json/tests/draft2020-12/optional/format/ipv6.json b/tests/draft2019-09/optional/format/ipv6.json
index 6379927..94368f2 100644
--- a/json/tests/draft2020-12/optional/format/ipv6.json
+++ b/tests/draft2019-09/optional/format/ipv6.json
@@ -194,12 +194,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1:2:3:4:5:6:7:৪",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the ipv4 portion also",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion",
"data": "1:2::192.16৪.0.1",
"valid": false
}
diff --git a/json/tests/draft2019-09/optional/format/iri-reference.json b/tests/draft2019-09/optional/format/iri-reference.json
index c6b4c22..c6b4c22 100644
--- a/json/tests/draft2019-09/optional/format/iri-reference.json
+++ b/tests/draft2019-09/optional/format/iri-reference.json
diff --git a/json/tests/draft2019-09/optional/format/iri.json b/tests/draft2019-09/optional/format/iri.json
index a0d12ae..a0d12ae 100644
--- a/json/tests/draft2019-09/optional/format/iri.json
+++ b/tests/draft2019-09/optional/format/iri.json
diff --git a/json/tests/draft2019-09/optional/format/json-pointer.json b/tests/draft2019-09/optional/format/json-pointer.json
index a0346b5..a0346b5 100644
--- a/json/tests/draft2019-09/optional/format/json-pointer.json
+++ b/tests/draft2019-09/optional/format/json-pointer.json
diff --git a/json/tests/draft2019-09/optional/format/regex.json b/tests/draft2019-09/optional/format/regex.json
index 3449177..3449177 100644
--- a/json/tests/draft2019-09/optional/format/regex.json
+++ b/tests/draft2019-09/optional/format/regex.json
diff --git a/json/tests/draft2019-09/optional/format/relative-json-pointer.json b/tests/draft2019-09/optional/format/relative-json-pointer.json
index 9309986..9309986 100644
--- a/json/tests/draft2019-09/optional/format/relative-json-pointer.json
+++ b/tests/draft2019-09/optional/format/relative-json-pointer.json
diff --git a/json/tests/draft7/optional/format/time.json b/tests/draft2019-09/optional/format/time.json
index 5011d78..3142587 100644
--- a/json/tests/draft7/optional/format/time.json
+++ b/tests/draft2019-09/optional/format/time.json
@@ -189,7 +189,7 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২:00:00Z",
"valid": false
}
diff --git a/json/tests/draft2019-09/optional/format/unknown.json b/tests/draft2019-09/optional/format/unknown.json
index 12339ae..12339ae 100644
--- a/json/tests/draft2019-09/optional/format/unknown.json
+++ b/tests/draft2019-09/optional/format/unknown.json
diff --git a/json/tests/draft2019-09/optional/format/uri-reference.json b/tests/draft2019-09/optional/format/uri-reference.json
index 7cdf228..7cdf228 100644
--- a/json/tests/draft2019-09/optional/format/uri-reference.json
+++ b/tests/draft2019-09/optional/format/uri-reference.json
diff --git a/json/tests/draft2019-09/optional/format/uri-template.json b/tests/draft2019-09/optional/format/uri-template.json
index df355c5..df355c5 100644
--- a/json/tests/draft2019-09/optional/format/uri-template.json
+++ b/tests/draft2019-09/optional/format/uri-template.json
diff --git a/json/tests/draft2019-09/optional/format/uri.json b/tests/draft2019-09/optional/format/uri.json
index 792d71a..792d71a 100644
--- a/json/tests/draft2019-09/optional/format/uri.json
+++ b/tests/draft2019-09/optional/format/uri.json
diff --git a/json/tests/draft2019-09/optional/format/uuid.json b/tests/draft2019-09/optional/format/uuid.json
index e54cbc0..e54cbc0 100644
--- a/json/tests/draft2019-09/optional/format/uuid.json
+++ b/tests/draft2019-09/optional/format/uuid.json
diff --git a/json/tests/draft2019-09/optional/non-bmp-regex.json b/tests/draft2019-09/optional/non-bmp-regex.json
index dd67af2..dd67af2 100644
--- a/json/tests/draft2019-09/optional/non-bmp-regex.json
+++ b/tests/draft2019-09/optional/non-bmp-regex.json
diff --git a/json/tests/draft2019-09/optional/refOfUnknownKeyword.json b/tests/draft2019-09/optional/refOfUnknownKeyword.json
index 5b150df..5b150df 100644
--- a/json/tests/draft2019-09/optional/refOfUnknownKeyword.json
+++ b/tests/draft2019-09/optional/refOfUnknownKeyword.json
diff --git a/json/tests/draft2019-09/pattern.json b/tests/draft2019-09/pattern.json
index 92db0f9..92db0f9 100644
--- a/json/tests/draft2019-09/pattern.json
+++ b/tests/draft2019-09/pattern.json
diff --git a/json/tests/draft2019-09/patternProperties.json b/tests/draft2019-09/patternProperties.json
index 34b2e85..34b2e85 100644
--- a/json/tests/draft2019-09/patternProperties.json
+++ b/tests/draft2019-09/patternProperties.json
diff --git a/json/tests/draft2019-09/properties.json b/tests/draft2019-09/properties.json
index 8c3ed35..8c3ed35 100644
--- a/json/tests/draft2019-09/properties.json
+++ b/tests/draft2019-09/properties.json
diff --git a/json/tests/draft2019-09/propertyNames.json b/tests/draft2019-09/propertyNames.json
index f0788e6..f0788e6 100644
--- a/json/tests/draft2019-09/propertyNames.json
+++ b/tests/draft2019-09/propertyNames.json
diff --git a/json/tests/draft2019-09/recursiveRef.json b/tests/draft2019-09/recursiveRef.json
index ebb098c..ebb098c 100644
--- a/json/tests/draft2019-09/recursiveRef.json
+++ b/tests/draft2019-09/recursiveRef.json
diff --git a/json/tests/draft2019-09/ref.json b/tests/draft2019-09/ref.json
index 32e3c66..6d1e90e 100644
--- a/json/tests/draft2019-09/ref.json
+++ b/tests/draft2019-09/ref.json
@@ -567,12 +567,12 @@
},
"tests": [
{
- "description": "number should pass",
+ "description": "number is valid",
"data": 1,
"valid": true
},
{
- "description": "non-number should fail",
+ "description": "non-number is invalid",
"data": "a",
"valid": false
}
diff --git a/json/tests/draft2019-09/refRemote.json b/tests/draft2019-09/refRemote.json
index a844039..a844039 100644
--- a/json/tests/draft2019-09/refRemote.json
+++ b/tests/draft2019-09/refRemote.json
diff --git a/json/tests/draft2019-09/required.json b/tests/draft2019-09/required.json
index abf18f3..abf18f3 100644
--- a/json/tests/draft2019-09/required.json
+++ b/tests/draft2019-09/required.json
diff --git a/json/tests/draft2019-09/type.json b/tests/draft2019-09/type.json
index 8304647..8304647 100644
--- a/json/tests/draft2019-09/type.json
+++ b/tests/draft2019-09/type.json
diff --git a/json/tests/draft2019-09/unevaluatedItems.json b/tests/draft2019-09/unevaluatedItems.json
index 3bf8483..3bf8483 100644
--- a/json/tests/draft2019-09/unevaluatedItems.json
+++ b/tests/draft2019-09/unevaluatedItems.json
diff --git a/json/tests/draft2019-09/unevaluatedProperties.json b/tests/draft2019-09/unevaluatedProperties.json
index 894f683..894f683 100644
--- a/json/tests/draft2019-09/unevaluatedProperties.json
+++ b/tests/draft2019-09/unevaluatedProperties.json
diff --git a/json/tests/draft2019-09/uniqueItems.json b/tests/draft2019-09/uniqueItems.json
index 2ccf666..2ccf666 100644
--- a/json/tests/draft2019-09/uniqueItems.json
+++ b/tests/draft2019-09/uniqueItems.json
diff --git a/json/tests/draft2019-09/unknownKeyword.json b/tests/draft2019-09/unknownKeyword.json
index e46657d..e46657d 100644
--- a/json/tests/draft2019-09/unknownKeyword.json
+++ b/tests/draft2019-09/unknownKeyword.json
diff --git a/json/tests/draft2019-09/vocabulary.json b/tests/draft2019-09/vocabulary.json
index 982e673..982e673 100644
--- a/json/tests/draft2019-09/vocabulary.json
+++ b/tests/draft2019-09/vocabulary.json
diff --git a/json/tests/draft2020-12/additionalProperties.json b/tests/draft2020-12/additionalProperties.json
index 98b8842..98b8842 100644
--- a/json/tests/draft2020-12/additionalProperties.json
+++ b/tests/draft2020-12/additionalProperties.json
diff --git a/json/tests/draft2020-12/allOf.json b/tests/draft2020-12/allOf.json
index ec9319e..ec9319e 100644
--- a/json/tests/draft2020-12/allOf.json
+++ b/tests/draft2020-12/allOf.json
diff --git a/json/tests/draft2020-12/anchor.json b/tests/draft2020-12/anchor.json
index 17e9080..8a6a5ea 100644
--- a/json/tests/draft2020-12/anchor.json
+++ b/tests/draft2020-12/anchor.json
@@ -159,12 +159,12 @@
},
"tests": [
{
- "description": "$ref should resolve to /$defs/A/allOf/1",
+ "description": "$ref resolves to /$defs/A/allOf/1",
"data": "a",
"valid": true
},
{
- "description": "$ref should not resolve to /$defs/A/allOf/0",
+ "description": "$ref does not resolve to /$defs/A/allOf/0",
"data": 1,
"valid": false
}
diff --git a/json/tests/draft2020-12/anyOf.json b/tests/draft2020-12/anyOf.json
index ab5eb38..ab5eb38 100644
--- a/json/tests/draft2020-12/anyOf.json
+++ b/tests/draft2020-12/anyOf.json
diff --git a/json/tests/draft2020-12/boolean_schema.json b/tests/draft2020-12/boolean_schema.json
index 6d40f23..6d40f23 100644
--- a/json/tests/draft2020-12/boolean_schema.json
+++ b/tests/draft2020-12/boolean_schema.json
diff --git a/json/tests/draft2020-12/const.json b/tests/draft2020-12/const.json
index 1c2cafc..1c2cafc 100644
--- a/json/tests/draft2020-12/const.json
+++ b/tests/draft2020-12/const.json
diff --git a/json/tests/draft2020-12/contains.json b/tests/draft2020-12/contains.json
index a6add6b..a6add6b 100644
--- a/json/tests/draft2020-12/contains.json
+++ b/tests/draft2020-12/contains.json
diff --git a/json/tests/draft2020-12/content.json b/tests/draft2020-12/content.json
index 44688e8..44688e8 100644
--- a/json/tests/draft2020-12/content.json
+++ b/tests/draft2020-12/content.json
diff --git a/json/tests/draft2020-12/default.json b/tests/draft2020-12/default.json
index 289a9b6..289a9b6 100644
--- a/json/tests/draft2020-12/default.json
+++ b/tests/draft2020-12/default.json
diff --git a/json/tests/draft2020-12/defs.json b/tests/draft2020-12/defs.json
index c738be2..c738be2 100644
--- a/json/tests/draft2020-12/defs.json
+++ b/tests/draft2020-12/defs.json
diff --git a/json/tests/draft2020-12/dependentRequired.json b/tests/draft2020-12/dependentRequired.json
index c817120..c817120 100644
--- a/json/tests/draft2020-12/dependentRequired.json
+++ b/tests/draft2020-12/dependentRequired.json
diff --git a/json/tests/draft2020-12/dependentSchemas.json b/tests/draft2020-12/dependentSchemas.json
index 2ba1a75..2ba1a75 100644
--- a/json/tests/draft2020-12/dependentSchemas.json
+++ b/tests/draft2020-12/dependentSchemas.json
diff --git a/json/tests/draft2020-12/dynamicRef.json b/tests/draft2020-12/dynamicRef.json
index 618d836..3a51356 100644
--- a/json/tests/draft2020-12/dynamicRef.json
+++ b/tests/draft2020-12/dynamicRef.json
@@ -517,7 +517,7 @@
]
},
{
- "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.",
+ "description": "$ref and $dynamicAnchor are independent of order - $defs first",
"schema": {
"$id": "http://localhost:1234/strict-extendible-allof-defs-first.json",
"allOf": [
@@ -567,7 +567,7 @@
]
},
{
- "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.",
+ "description": "$ref and $dynamicAnchor are independent of order - $ref first",
"schema": {
"$id": "http://localhost:1234/strict-extendible-allof-ref-first.json",
"allOf": [
diff --git a/json/tests/draft2020-12/enum.json b/tests/draft2020-12/enum.json
index f085097..f085097 100644
--- a/json/tests/draft2020-12/enum.json
+++ b/tests/draft2020-12/enum.json
diff --git a/json/tests/draft2020-12/exclusiveMaximum.json b/tests/draft2020-12/exclusiveMaximum.json
index dc3cd70..dc3cd70 100644
--- a/json/tests/draft2020-12/exclusiveMaximum.json
+++ b/tests/draft2020-12/exclusiveMaximum.json
diff --git a/json/tests/draft2020-12/exclusiveMinimum.json b/tests/draft2020-12/exclusiveMinimum.json
index b38d7ec..b38d7ec 100644
--- a/json/tests/draft2020-12/exclusiveMinimum.json
+++ b/tests/draft2020-12/exclusiveMinimum.json
diff --git a/json/tests/draft2020-12/format.json b/tests/draft2020-12/format.json
index a4b51d2..a4b51d2 100644
--- a/json/tests/draft2020-12/format.json
+++ b/tests/draft2020-12/format.json
diff --git a/json/tests/draft2020-12/id.json b/tests/draft2020-12/id.json
index 37fb429..37fb429 100644
--- a/json/tests/draft2020-12/id.json
+++ b/tests/draft2020-12/id.json
diff --git a/json/tests/draft2020-12/if-then-else.json b/tests/draft2020-12/if-then-else.json
index 284e919..284e919 100644
--- a/json/tests/draft2020-12/if-then-else.json
+++ b/tests/draft2020-12/if-then-else.json
diff --git a/json/tests/draft2020-12/infinite-loop-detection.json b/tests/draft2020-12/infinite-loop-detection.json
index 9c3c362..9c3c362 100644
--- a/json/tests/draft2020-12/infinite-loop-detection.json
+++ b/tests/draft2020-12/infinite-loop-detection.json
diff --git a/json/tests/draft2020-12/items.json b/tests/draft2020-12/items.json
index 1f0bdcf..38ab0e0 100644
--- a/json/tests/draft2020-12/items.json
+++ b/tests/draft2020-12/items.json
@@ -214,7 +214,7 @@
]
},
{
- "description": "items should not look in applicators, valid case",
+ "description": "items does not look in applicators, valid case",
"schema": {
"allOf": [
{ "prefixItems": [ { "minimum": 3 } ] }
@@ -223,12 +223,12 @@
},
"tests": [
{
- "description": "prefixItems in allOf should not constrain items, invalid case",
+ "description": "prefixItems in allOf does not constrain items, invalid case",
"data": [ 3, 5 ],
"valid": false
},
{
- "description": "prefixItems in allOf should not constrain items, valid case",
+ "description": "prefixItems in allOf does not constrain items, valid case",
"data": [ 5, 5 ],
"valid": true
}
@@ -254,7 +254,7 @@
]
},
{
- "description": "items should properly handle null data",
+ "description": "items with null instance elements",
"schema": {
"items": {
"type": "null"
@@ -262,7 +262,7 @@
},
"tests": [
{
- "description": "null items allowed",
+ "description": "allows null elements",
"data": [ null ],
"valid": true
}
diff --git a/json/tests/draft2020-12/maxContains.json b/tests/draft2020-12/maxContains.json
index 61c967d..61c967d 100644
--- a/json/tests/draft2020-12/maxContains.json
+++ b/tests/draft2020-12/maxContains.json
diff --git a/json/tests/draft2020-12/maxItems.json b/tests/draft2020-12/maxItems.json
index f0c36ab..f0c36ab 100644
--- a/json/tests/draft2020-12/maxItems.json
+++ b/tests/draft2020-12/maxItems.json
diff --git a/json/tests/draft2020-12/maxLength.json b/tests/draft2020-12/maxLength.json
index 748b4da..748b4da 100644
--- a/json/tests/draft2020-12/maxLength.json
+++ b/tests/draft2020-12/maxLength.json
diff --git a/json/tests/draft2020-12/maxProperties.json b/tests/draft2020-12/maxProperties.json
index acec142..acec142 100644
--- a/json/tests/draft2020-12/maxProperties.json
+++ b/tests/draft2020-12/maxProperties.json
diff --git a/json/tests/draft2020-12/maximum.json b/tests/draft2020-12/maximum.json
index 6844a39..6844a39 100644
--- a/json/tests/draft2020-12/maximum.json
+++ b/tests/draft2020-12/maximum.json
diff --git a/json/tests/draft2020-12/minContains.json b/tests/draft2020-12/minContains.json
index 851e262..851e262 100644
--- a/json/tests/draft2020-12/minContains.json
+++ b/tests/draft2020-12/minContains.json
diff --git a/json/tests/draft2020-12/minItems.json b/tests/draft2020-12/minItems.json
index d3b1872..d3b1872 100644
--- a/json/tests/draft2020-12/minItems.json
+++ b/tests/draft2020-12/minItems.json
diff --git a/json/tests/draft2020-12/minLength.json b/tests/draft2020-12/minLength.json
index 64db948..64db948 100644
--- a/json/tests/draft2020-12/minLength.json
+++ b/tests/draft2020-12/minLength.json
diff --git a/json/tests/draft2020-12/minProperties.json b/tests/draft2020-12/minProperties.json
index 9f74f78..9f74f78 100644
--- a/json/tests/draft2020-12/minProperties.json
+++ b/tests/draft2020-12/minProperties.json
diff --git a/json/tests/draft2020-12/minimum.json b/tests/draft2020-12/minimum.json
index 21ae50e..21ae50e 100644
--- a/json/tests/draft2020-12/minimum.json
+++ b/tests/draft2020-12/minimum.json
diff --git a/json/tests/draft2020-12/multipleOf.json b/tests/draft2020-12/multipleOf.json
index faa87cf..faa87cf 100644
--- a/json/tests/draft2020-12/multipleOf.json
+++ b/tests/draft2020-12/multipleOf.json
diff --git a/json/tests/draft2020-12/not.json b/tests/draft2020-12/not.json
index 98de0ed..98de0ed 100644
--- a/json/tests/draft2020-12/not.json
+++ b/tests/draft2020-12/not.json
diff --git a/json/tests/draft2020-12/oneOf.json b/tests/draft2020-12/oneOf.json
index eeb7ae8..eeb7ae8 100644
--- a/json/tests/draft2020-12/oneOf.json
+++ b/tests/draft2020-12/oneOf.json
diff --git a/json/tests/draft6/optional/bignum.json b/tests/draft2020-12/optional/bignum.json
index 3f49226..94b4a4e 100644
--- a/json/tests/draft6/optional/bignum.json
+++ b/tests/draft2020-12/optional/bignum.json
@@ -43,7 +43,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "maximum integer comparison",
"schema": { "maximum": 18446744073709551615 },
"tests": [
{
@@ -67,7 +67,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "minimum integer comparison",
"schema": { "minimum": -18446744073709551615 },
"tests": [
{
diff --git a/json/tests/draft2020-12/optional/dependencies-compatibility.json b/tests/draft2020-12/optional/dependencies-compatibility.json
index 6eafaf0..6eafaf0 100644
--- a/json/tests/draft2020-12/optional/dependencies-compatibility.json
+++ b/tests/draft2020-12/optional/dependencies-compatibility.json
diff --git a/json/tests/draft2020-12/optional/ecmascript-regex.json b/tests/draft2020-12/optional/ecmascript-regex.json
index bb92acd..4d57efa 100644
--- a/json/tests/draft2020-12/optional/ecmascript-regex.json
+++ b/tests/draft2020-12/optional/ecmascript-regex.json
@@ -7,12 +7,12 @@
},
"tests": [
{
- "description": "matches in Python, but should not in jsonschema",
+ "description": "matches in Python, but not in ECMA 262",
"data": "abc\\n",
"valid": false
},
{
- "description": "should match",
+ "description": "matches",
"data": "abc",
"valid": true
}
@@ -342,7 +342,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "pattern with ASCII ranges",
"schema": { "pattern": "[a-z]cole" },
"tests": [
{
@@ -395,7 +395,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "pattern with non-ASCII digits",
"schema": { "pattern": "^\\p{digit}+$" },
"tests": [
{
@@ -480,7 +480,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "patternProperties with ASCII ranges",
"schema": {
"type": "object",
"patternProperties": {
@@ -534,7 +534,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "patternProperties with non-ASCII digits",
"schema": {
"type": "object",
"patternProperties": {
diff --git a/json/tests/draft2020-12/optional/float-overflow.json b/tests/draft2020-12/optional/float-overflow.json
index 52ff982..52ff982 100644
--- a/json/tests/draft2020-12/optional/float-overflow.json
+++ b/tests/draft2020-12/optional/float-overflow.json
diff --git a/json/tests/draft2020-12/optional/format-assertion.json b/tests/draft2020-12/optional/format-assertion.json
index 0340037..0340037 100644
--- a/json/tests/draft2020-12/optional/format-assertion.json
+++ b/tests/draft2020-12/optional/format-assertion.json
diff --git a/json/tests/draft-next/optional/format/date-time.json b/tests/draft2020-12/optional/format/date-time.json
index f4f9933..0911273 100644
--- a/json/tests/draft-next/optional/format/date-time.json
+++ b/tests/draft2020-12/optional/format/date-time.json
@@ -119,12 +119,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the date portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion",
"data": "1963-06-1৪T00:00:00Z",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the time portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion",
"data": "1963-06-11T0৪:00:00Z",
"valid": false
}
diff --git a/json/tests/draft7/optional/format/date.json b/tests/draft2020-12/optional/format/date.json
index b4f61ee..06c9ea0 100644
--- a/json/tests/draft7/optional/format/date.json
+++ b/tests/draft2020-12/optional/format/date.json
@@ -214,7 +214,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1963-06-1৪",
"valid": false
}
diff --git a/json/tests/draft-next/optional/format/duration.json b/tests/draft2020-12/optional/format/duration.json
index 741348a..a6acdc1 100644
--- a/json/tests/draft-next/optional/format/duration.json
+++ b/tests/draft2020-12/optional/format/duration.json
@@ -119,7 +119,7 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "P২Y",
"valid": false
}
diff --git a/json/tests/draft2020-12/optional/format/email.json b/tests/draft2020-12/optional/format/email.json
index 5ce1c70..5ce1c70 100644
--- a/json/tests/draft2020-12/optional/format/email.json
+++ b/tests/draft2020-12/optional/format/email.json
diff --git a/json/tests/draft2020-12/optional/format/hostname.json b/tests/draft2020-12/optional/format/hostname.json
index 8a67fda..8a67fda 100644
--- a/json/tests/draft2020-12/optional/format/hostname.json
+++ b/tests/draft2020-12/optional/format/hostname.json
diff --git a/json/tests/draft2020-12/optional/format/idn-email.json b/tests/draft2020-12/optional/format/idn-email.json
index 6e21374..6e21374 100644
--- a/json/tests/draft2020-12/optional/format/idn-email.json
+++ b/tests/draft2020-12/optional/format/idn-email.json
diff --git a/json/tests/draft2020-12/optional/format/idn-hostname.json b/tests/draft2020-12/optional/format/idn-hostname.json
index 6c8f86a..6c8f86a 100644
--- a/json/tests/draft2020-12/optional/format/idn-hostname.json
+++ b/tests/draft2020-12/optional/format/idn-hostname.json
diff --git a/json/tests/draft4/optional/format/ipv4.json b/tests/draft2020-12/optional/format/ipv4.json
index 6b166c7..4706581 100644
--- a/json/tests/draft4/optional/format/ipv4.json
+++ b/tests/draft2020-12/optional/format/ipv4.json
@@ -64,7 +64,7 @@
"valid": false
},
{
- "description": "leading zeroes should be rejected, as they are treated as octals",
+ "description": "invalid leading zeroes, as they are treated as octals",
"comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
"data": "087.10.0.1",
"valid": false
@@ -75,7 +75,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২7.0.0.1",
"valid": false
}
diff --git a/json/tests/draft2019-09/optional/format/ipv6.json b/tests/draft2020-12/optional/format/ipv6.json
index 6379927..94368f2 100644
--- a/json/tests/draft2019-09/optional/format/ipv6.json
+++ b/tests/draft2020-12/optional/format/ipv6.json
@@ -194,12 +194,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1:2:3:4:5:6:7:৪",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the ipv4 portion also",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion",
"data": "1:2::192.16৪.0.1",
"valid": false
}
diff --git a/json/tests/draft2020-12/optional/format/iri-reference.json b/tests/draft2020-12/optional/format/iri-reference.json
index c6b4c22..c6b4c22 100644
--- a/json/tests/draft2020-12/optional/format/iri-reference.json
+++ b/tests/draft2020-12/optional/format/iri-reference.json
diff --git a/json/tests/draft2020-12/optional/format/iri.json b/tests/draft2020-12/optional/format/iri.json
index a0d12ae..a0d12ae 100644
--- a/json/tests/draft2020-12/optional/format/iri.json
+++ b/tests/draft2020-12/optional/format/iri.json
diff --git a/json/tests/draft2020-12/optional/format/json-pointer.json b/tests/draft2020-12/optional/format/json-pointer.json
index a0346b5..a0346b5 100644
--- a/json/tests/draft2020-12/optional/format/json-pointer.json
+++ b/tests/draft2020-12/optional/format/json-pointer.json
diff --git a/json/tests/draft2020-12/optional/format/regex.json b/tests/draft2020-12/optional/format/regex.json
index 3449177..3449177 100644
--- a/json/tests/draft2020-12/optional/format/regex.json
+++ b/tests/draft2020-12/optional/format/regex.json
diff --git a/json/tests/draft2020-12/optional/format/relative-json-pointer.json b/tests/draft2020-12/optional/format/relative-json-pointer.json
index 9309986..9309986 100644
--- a/json/tests/draft2020-12/optional/format/relative-json-pointer.json
+++ b/tests/draft2020-12/optional/format/relative-json-pointer.json
diff --git a/json/tests/draft2019-09/optional/format/time.json b/tests/draft2020-12/optional/format/time.json
index 5011d78..3142587 100644
--- a/json/tests/draft2019-09/optional/format/time.json
+++ b/tests/draft2020-12/optional/format/time.json
@@ -189,7 +189,7 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২:00:00Z",
"valid": false
}
diff --git a/json/tests/draft2020-12/optional/format/unknown.json b/tests/draft2020-12/optional/format/unknown.json
index 12339ae..12339ae 100644
--- a/json/tests/draft2020-12/optional/format/unknown.json
+++ b/tests/draft2020-12/optional/format/unknown.json
diff --git a/json/tests/draft2020-12/optional/format/uri-reference.json b/tests/draft2020-12/optional/format/uri-reference.json
index 7cdf228..7cdf228 100644
--- a/json/tests/draft2020-12/optional/format/uri-reference.json
+++ b/tests/draft2020-12/optional/format/uri-reference.json
diff --git a/json/tests/draft2020-12/optional/format/uri-template.json b/tests/draft2020-12/optional/format/uri-template.json
index df355c5..df355c5 100644
--- a/json/tests/draft2020-12/optional/format/uri-template.json
+++ b/tests/draft2020-12/optional/format/uri-template.json
diff --git a/json/tests/draft2020-12/optional/format/uri.json b/tests/draft2020-12/optional/format/uri.json
index 792d71a..792d71a 100644
--- a/json/tests/draft2020-12/optional/format/uri.json
+++ b/tests/draft2020-12/optional/format/uri.json
diff --git a/json/tests/draft2020-12/optional/format/uuid.json b/tests/draft2020-12/optional/format/uuid.json
index e54cbc0..e54cbc0 100644
--- a/json/tests/draft2020-12/optional/format/uuid.json
+++ b/tests/draft2020-12/optional/format/uuid.json
diff --git a/json/tests/draft2020-12/optional/non-bmp-regex.json b/tests/draft2020-12/optional/non-bmp-regex.json
index dd67af2..dd67af2 100644
--- a/json/tests/draft2020-12/optional/non-bmp-regex.json
+++ b/tests/draft2020-12/optional/non-bmp-regex.json
diff --git a/json/tests/draft2020-12/optional/refOfUnknownKeyword.json b/tests/draft2020-12/optional/refOfUnknownKeyword.json
index 5b150df..5b150df 100644
--- a/json/tests/draft2020-12/optional/refOfUnknownKeyword.json
+++ b/tests/draft2020-12/optional/refOfUnknownKeyword.json
diff --git a/json/tests/draft2020-12/pattern.json b/tests/draft2020-12/pattern.json
index 92db0f9..92db0f9 100644
--- a/json/tests/draft2020-12/pattern.json
+++ b/tests/draft2020-12/pattern.json
diff --git a/json/tests/draft2020-12/patternProperties.json b/tests/draft2020-12/patternProperties.json
index 34b2e85..34b2e85 100644
--- a/json/tests/draft2020-12/patternProperties.json
+++ b/tests/draft2020-12/patternProperties.json
diff --git a/json/tests/draft-next/prefixItems.json b/tests/draft2020-12/prefixItems.json
index f72da11..f72da11 100644
--- a/json/tests/draft-next/prefixItems.json
+++ b/tests/draft2020-12/prefixItems.json
diff --git a/json/tests/draft2020-12/properties.json b/tests/draft2020-12/properties.json
index 8c3ed35..8c3ed35 100644
--- a/json/tests/draft2020-12/properties.json
+++ b/tests/draft2020-12/properties.json
diff --git a/json/tests/draft2020-12/propertyNames.json b/tests/draft2020-12/propertyNames.json
index 8423690..8423690 100644
--- a/json/tests/draft2020-12/propertyNames.json
+++ b/tests/draft2020-12/propertyNames.json
diff --git a/json/tests/draft2020-12/ref.json b/tests/draft2020-12/ref.json
index bc8ac44..d630047 100644
--- a/json/tests/draft2020-12/ref.json
+++ b/tests/draft2020-12/ref.json
@@ -567,12 +567,12 @@
},
"tests": [
{
- "description": "number should pass",
+ "description": "number is valid",
"data": 1,
"valid": true
},
{
- "description": "non-number should fail",
+ "description": "non-number is invalid",
"data": "a",
"valid": false
}
diff --git a/json/tests/draft2020-12/refRemote.json b/tests/draft2020-12/refRemote.json
index a844039..a844039 100644
--- a/json/tests/draft2020-12/refRemote.json
+++ b/tests/draft2020-12/refRemote.json
diff --git a/json/tests/draft2020-12/required.json b/tests/draft2020-12/required.json
index abf18f3..abf18f3 100644
--- a/json/tests/draft2020-12/required.json
+++ b/tests/draft2020-12/required.json
diff --git a/json/tests/draft2020-12/type.json b/tests/draft2020-12/type.json
index 8304647..8304647 100644
--- a/json/tests/draft2020-12/type.json
+++ b/tests/draft2020-12/type.json
diff --git a/json/tests/draft2020-12/unevaluatedItems.json b/tests/draft2020-12/unevaluatedItems.json
index eedb19f..eedb19f 100644
--- a/json/tests/draft2020-12/unevaluatedItems.json
+++ b/tests/draft2020-12/unevaluatedItems.json
diff --git a/json/tests/draft2020-12/unevaluatedProperties.json b/tests/draft2020-12/unevaluatedProperties.json
index 894f683..894f683 100644
--- a/json/tests/draft2020-12/unevaluatedProperties.json
+++ b/tests/draft2020-12/unevaluatedProperties.json
diff --git a/json/tests/draft2020-12/uniqueItems.json b/tests/draft2020-12/uniqueItems.json
index 85c619d..85c619d 100644
--- a/json/tests/draft2020-12/uniqueItems.json
+++ b/tests/draft2020-12/uniqueItems.json
diff --git a/json/tests/draft2020-12/unknownKeyword.json b/tests/draft2020-12/unknownKeyword.json
index e46657d..e46657d 100644
--- a/json/tests/draft2020-12/unknownKeyword.json
+++ b/tests/draft2020-12/unknownKeyword.json
diff --git a/json/tests/draft2020-12/vocabulary.json b/tests/draft2020-12/vocabulary.json
index d84f8f1..d84f8f1 100644
--- a/json/tests/draft2020-12/vocabulary.json
+++ b/tests/draft2020-12/vocabulary.json
diff --git a/json/tests/draft3/additionalItems.json b/tests/draft3/additionalItems.json
index 24b1d86..24b1d86 100644
--- a/json/tests/draft3/additionalItems.json
+++ b/tests/draft3/additionalItems.json
diff --git a/json/tests/draft3/additionalProperties.json b/tests/draft3/additionalProperties.json
index 0a33b3b..0a33b3b 100644
--- a/json/tests/draft3/additionalProperties.json
+++ b/tests/draft3/additionalProperties.json
diff --git a/json/tests/draft3/default.json b/tests/draft3/default.json
index 289a9b6..289a9b6 100644
--- a/json/tests/draft3/default.json
+++ b/tests/draft3/default.json
diff --git a/json/tests/draft3/dependencies.json b/tests/draft3/dependencies.json
index 0ffa6bf..0ffa6bf 100644
--- a/json/tests/draft3/dependencies.json
+++ b/tests/draft3/dependencies.json
diff --git a/json/tests/draft3/disallow.json b/tests/draft3/disallow.json
index a5c9d90..a5c9d90 100644
--- a/json/tests/draft3/disallow.json
+++ b/tests/draft3/disallow.json
diff --git a/json/tests/draft3/divisibleBy.json b/tests/draft3/divisibleBy.json
index ef7cc14..ef7cc14 100644
--- a/json/tests/draft3/divisibleBy.json
+++ b/tests/draft3/divisibleBy.json
diff --git a/json/tests/draft3/enum.json b/tests/draft3/enum.json
index 5a1ab3b..5a1ab3b 100644
--- a/json/tests/draft3/enum.json
+++ b/tests/draft3/enum.json
diff --git a/json/tests/draft3/extends.json b/tests/draft3/extends.json
index 909bce5..909bce5 100644
--- a/json/tests/draft3/extends.json
+++ b/tests/draft3/extends.json
diff --git a/json/tests/draft3/format.json b/tests/draft3/format.json
index a5447c9..a5447c9 100644
--- a/json/tests/draft3/format.json
+++ b/tests/draft3/format.json
diff --git a/json/tests/draft3/infinite-loop-detection.json b/tests/draft3/infinite-loop-detection.json
index 090f49a..090f49a 100644
--- a/json/tests/draft3/infinite-loop-detection.json
+++ b/tests/draft3/infinite-loop-detection.json
diff --git a/json/tests/draft3/items.json b/tests/draft3/items.json
index 586a559..586a559 100644
--- a/json/tests/draft3/items.json
+++ b/tests/draft3/items.json
diff --git a/json/tests/draft3/maxItems.json b/tests/draft3/maxItems.json
index 3b53a6b..3b53a6b 100644
--- a/json/tests/draft3/maxItems.json
+++ b/tests/draft3/maxItems.json
diff --git a/json/tests/draft3/maxLength.json b/tests/draft3/maxLength.json
index 4de42bc..4de42bc 100644
--- a/json/tests/draft3/maxLength.json
+++ b/tests/draft3/maxLength.json
diff --git a/json/tests/draft3/maximum.json b/tests/draft3/maximum.json
index ccb79c6..ccb79c6 100644
--- a/json/tests/draft3/maximum.json
+++ b/tests/draft3/maximum.json
diff --git a/json/tests/draft3/minItems.json b/tests/draft3/minItems.json
index ed51188..ed51188 100644
--- a/json/tests/draft3/minItems.json
+++ b/tests/draft3/minItems.json
diff --git a/json/tests/draft3/minLength.json b/tests/draft3/minLength.json
index 3f09158..3f09158 100644
--- a/json/tests/draft3/minLength.json
+++ b/tests/draft3/minLength.json
diff --git a/json/tests/draft3/minimum.json b/tests/draft3/minimum.json
index d579536..d579536 100644
--- a/json/tests/draft3/minimum.json
+++ b/tests/draft3/minimum.json
diff --git a/json/tests/draft4/optional/bignum.json b/tests/draft3/optional/bignum.json
index 7a622de..1bc8eb2 100644
--- a/json/tests/draft4/optional/bignum.json
+++ b/tests/draft3/optional/bignum.json
@@ -43,7 +43,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "maximum integer comparison",
"schema": { "maximum": 18446744073709551615 },
"tests": [
{
@@ -68,7 +68,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "minimum integer comparison",
"schema": { "minimum": -18446744073709551615 },
"tests": [
{
diff --git a/json/tests/draft3/optional/ecmascript-regex.json b/tests/draft3/optional/ecmascript-regex.json
index 03fe977..03fe977 100644
--- a/json/tests/draft3/optional/ecmascript-regex.json
+++ b/tests/draft3/optional/ecmascript-regex.json
diff --git a/json/tests/draft3/optional/format/color.json b/tests/draft3/optional/format/color.json
index 0c0b534..0c0b534 100644
--- a/json/tests/draft3/optional/format/color.json
+++ b/tests/draft3/optional/format/color.json
diff --git a/json/tests/draft3/optional/format/date-time.json b/tests/draft3/optional/format/date-time.json
index 1f1e6fb..1f1e6fb 100644
--- a/json/tests/draft3/optional/format/date-time.json
+++ b/tests/draft3/optional/format/date-time.json
diff --git a/json/tests/draft3/optional/format/date.json b/tests/draft3/optional/format/date.json
index 796bc46..796bc46 100644
--- a/json/tests/draft3/optional/format/date.json
+++ b/tests/draft3/optional/format/date.json
diff --git a/json/tests/draft3/optional/format/email.json b/tests/draft3/optional/format/email.json
index 059615a..059615a 100644
--- a/json/tests/draft3/optional/format/email.json
+++ b/tests/draft3/optional/format/email.json
diff --git a/json/tests/draft3/optional/format/host-name.json b/tests/draft3/optional/format/host-name.json
index d418f37..d418f37 100644
--- a/json/tests/draft3/optional/format/host-name.json
+++ b/tests/draft3/optional/format/host-name.json
diff --git a/json/tests/draft3/optional/format/ip-address.json b/tests/draft3/optional/format/ip-address.json
index 91cac9f..91cac9f 100644
--- a/json/tests/draft3/optional/format/ip-address.json
+++ b/tests/draft3/optional/format/ip-address.json
diff --git a/json/tests/draft3/optional/format/ipv6.json b/tests/draft3/optional/format/ipv6.json
index c3ef379..c3ef379 100644
--- a/json/tests/draft3/optional/format/ipv6.json
+++ b/tests/draft3/optional/format/ipv6.json
diff --git a/json/tests/draft3/optional/format/regex.json b/tests/draft3/optional/format/regex.json
index 8a37763..8a37763 100644
--- a/json/tests/draft3/optional/format/regex.json
+++ b/tests/draft3/optional/format/regex.json
diff --git a/json/tests/draft3/optional/format/time.json b/tests/draft3/optional/format/time.json
index 36c823e..36c823e 100644
--- a/json/tests/draft3/optional/format/time.json
+++ b/tests/draft3/optional/format/time.json
diff --git a/json/tests/draft3/optional/format/uri.json b/tests/draft3/optional/format/uri.json
index f024b62..f024b62 100644
--- a/json/tests/draft3/optional/format/uri.json
+++ b/tests/draft3/optional/format/uri.json
diff --git a/json/tests/draft3/optional/non-bmp-regex.json b/tests/draft3/optional/non-bmp-regex.json
index dd67af2..dd67af2 100644
--- a/json/tests/draft3/optional/non-bmp-regex.json
+++ b/tests/draft3/optional/non-bmp-regex.json
diff --git a/json/tests/draft3/optional/zeroTerminatedFloats.json b/tests/draft3/optional/zeroTerminatedFloats.json
index 9b50ea2..9b50ea2 100644
--- a/json/tests/draft3/optional/zeroTerminatedFloats.json
+++ b/tests/draft3/optional/zeroTerminatedFloats.json
diff --git a/json/tests/draft3/pattern.json b/tests/draft3/pattern.json
index 92db0f9..92db0f9 100644
--- a/json/tests/draft3/pattern.json
+++ b/tests/draft3/pattern.json
diff --git a/json/tests/draft3/patternProperties.json b/tests/draft3/patternProperties.json
index 71954fd..71954fd 100644
--- a/json/tests/draft3/patternProperties.json
+++ b/tests/draft3/patternProperties.json
diff --git a/json/tests/draft3/properties.json b/tests/draft3/properties.json
index 5b6a833..5b6a833 100644
--- a/json/tests/draft3/properties.json
+++ b/tests/draft3/properties.json
diff --git a/json/tests/draft3/ref.json b/tests/draft3/ref.json
index 924db76..924db76 100644
--- a/json/tests/draft3/ref.json
+++ b/tests/draft3/ref.json
diff --git a/json/tests/draft3/refRemote.json b/tests/draft3/refRemote.json
index de0cb43..de0cb43 100644
--- a/json/tests/draft3/refRemote.json
+++ b/tests/draft3/refRemote.json
diff --git a/json/tests/draft3/required.json b/tests/draft3/required.json
index aaaf024..aaaf024 100644
--- a/json/tests/draft3/required.json
+++ b/tests/draft3/required.json
diff --git a/json/tests/draft3/type.json b/tests/draft3/type.json
index f962cc3..f962cc3 100644
--- a/json/tests/draft3/type.json
+++ b/tests/draft3/type.json
diff --git a/json/tests/draft3/uniqueItems.json b/tests/draft3/uniqueItems.json
index c48c6a0..c48c6a0 100644
--- a/json/tests/draft3/uniqueItems.json
+++ b/tests/draft3/uniqueItems.json
diff --git a/json/tests/draft4/additionalItems.json b/tests/draft4/additionalItems.json
index 454142b..454142b 100644
--- a/json/tests/draft4/additionalItems.json
+++ b/tests/draft4/additionalItems.json
diff --git a/json/tests/draft4/additionalProperties.json b/tests/draft4/additionalProperties.json
index 98b8842..98b8842 100644
--- a/json/tests/draft4/additionalProperties.json
+++ b/tests/draft4/additionalProperties.json
diff --git a/json/tests/draft4/allOf.json b/tests/draft4/allOf.json
index fc7dec5..fc7dec5 100644
--- a/json/tests/draft4/allOf.json
+++ b/tests/draft4/allOf.json
diff --git a/json/tests/draft4/anyOf.json b/tests/draft4/anyOf.json
index f8d82e8..09cc3c2 100644
--- a/json/tests/draft4/anyOf.json
+++ b/tests/draft4/anyOf.json
@@ -152,31 +152,5 @@
"valid": false
}
]
- },
- {
- "description": "nested anyOf, to check validation semantics",
- "schema": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- }
- ]
- }
- ]
- },
- "tests": [
- {
- "description": "null is valid",
- "data": null,
- "valid": true
- },
- {
- "description": "anything non-null is invalid",
- "data": 123,
- "valid": false
- }
- ]
}
]
diff --git a/json/tests/draft4/default.json b/tests/draft4/default.json
index 289a9b6..289a9b6 100644
--- a/json/tests/draft4/default.json
+++ b/tests/draft4/default.json
diff --git a/json/tests/draft4/definitions.json b/tests/draft4/definitions.json
index 482823b..482823b 100644
--- a/json/tests/draft4/definitions.json
+++ b/tests/draft4/definitions.json
diff --git a/json/tests/draft4/dependencies.json b/tests/draft4/dependencies.json
index 51eeddf..51eeddf 100644
--- a/json/tests/draft4/dependencies.json
+++ b/tests/draft4/dependencies.json
diff --git a/json/tests/draft4/enum.json b/tests/draft4/enum.json
index f085097..f085097 100644
--- a/json/tests/draft4/enum.json
+++ b/tests/draft4/enum.json
diff --git a/json/tests/draft4/format.json b/tests/draft4/format.json
index 5bd83cc..5bd83cc 100644
--- a/json/tests/draft4/format.json
+++ b/tests/draft4/format.json
diff --git a/json/tests/draft4/id.json b/tests/draft4/id.json
index 1c91d33..1c91d33 100644
--- a/json/tests/draft4/id.json
+++ b/tests/draft4/id.json
diff --git a/json/tests/draft4/infinite-loop-detection.json b/tests/draft4/infinite-loop-detection.json
index f98c74f..f98c74f 100644
--- a/json/tests/draft4/infinite-loop-detection.json
+++ b/tests/draft4/infinite-loop-detection.json
diff --git a/json/tests/draft4/items.json b/tests/draft4/items.json
index 89801db..89801db 100644
--- a/json/tests/draft4/items.json
+++ b/tests/draft4/items.json
diff --git a/json/tests/draft4/maxItems.json b/tests/draft4/maxItems.json
index 3b53a6b..3b53a6b 100644
--- a/json/tests/draft4/maxItems.json
+++ b/tests/draft4/maxItems.json
diff --git a/json/tests/draft4/maxLength.json b/tests/draft4/maxLength.json
index 811d35b..811d35b 100644
--- a/json/tests/draft4/maxLength.json
+++ b/tests/draft4/maxLength.json
diff --git a/json/tests/draft4/maxProperties.json b/tests/draft4/maxProperties.json
index aa7209f..aa7209f 100644
--- a/json/tests/draft4/maxProperties.json
+++ b/tests/draft4/maxProperties.json
diff --git a/json/tests/draft4/maximum.json b/tests/draft4/maximum.json
index ccb79c6..ccb79c6 100644
--- a/json/tests/draft4/maximum.json
+++ b/tests/draft4/maximum.json
diff --git a/json/tests/draft4/minItems.json b/tests/draft4/minItems.json
index ed51188..ed51188 100644
--- a/json/tests/draft4/minItems.json
+++ b/tests/draft4/minItems.json
diff --git a/json/tests/draft4/minLength.json b/tests/draft4/minLength.json
index 3f09158..3f09158 100644
--- a/json/tests/draft4/minLength.json
+++ b/tests/draft4/minLength.json
diff --git a/json/tests/draft4/minProperties.json b/tests/draft4/minProperties.json
index 49a0726..49a0726 100644
--- a/json/tests/draft4/minProperties.json
+++ b/tests/draft4/minProperties.json
diff --git a/json/tests/draft4/minimum.json b/tests/draft4/minimum.json
index 22d310e..22d310e 100644
--- a/json/tests/draft4/minimum.json
+++ b/tests/draft4/minimum.json
diff --git a/json/tests/draft4/multipleOf.json b/tests/draft4/multipleOf.json
index faa87cf..faa87cf 100644
--- a/json/tests/draft4/multipleOf.json
+++ b/tests/draft4/multipleOf.json
diff --git a/json/tests/draft4/not.json b/tests/draft4/not.json
index cbb7f46..cbb7f46 100644
--- a/json/tests/draft4/not.json
+++ b/tests/draft4/not.json
diff --git a/json/tests/draft4/oneOf.json b/tests/draft4/oneOf.json
index fb63b08..fb63b08 100644
--- a/json/tests/draft4/oneOf.json
+++ b/tests/draft4/oneOf.json
diff --git a/tests/draft4/optional/bignum.json b/tests/draft4/optional/bignum.json
new file mode 100644
index 0000000..1bc8eb2
--- /dev/null
+++ b/tests/draft4/optional/bignum.json
@@ -0,0 +1,95 @@
+[
+ {
+ "description": "integer",
+ "schema": { "type": "integer" },
+ "tests": [
+ {
+ "description": "a bignum is an integer",
+ "data": 12345678910111213141516171819202122232425262728293031,
+ "valid": true
+ },
+ {
+ "description": "a negative bignum is an integer",
+ "data": -12345678910111213141516171819202122232425262728293031,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "number",
+ "schema": { "type": "number" },
+ "tests": [
+ {
+ "description": "a bignum is a number",
+ "data": 98249283749234923498293171823948729348710298301928331,
+ "valid": true
+ },
+ {
+ "description": "a negative bignum is a number",
+ "data": -98249283749234923498293171823948729348710298301928331,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "string",
+ "schema": { "type": "string" },
+ "tests": [
+ {
+ "description": "a bignum is not a string",
+ "data": 98249283749234923498293171823948729348710298301928331,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "maximum integer comparison",
+ "schema": { "maximum": 18446744073709551615 },
+ "tests": [
+ {
+ "description": "comparison works for high numbers",
+ "data": 18446744073709551600,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "float comparison with high precision",
+ "schema": {
+ "maximum": 972783798187987123879878123.18878137,
+ "exclusiveMaximum": true
+ },
+ "tests": [
+ {
+ "description": "comparison works for high numbers",
+ "data": 972783798187987123879878123.188781371,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "minimum integer comparison",
+ "schema": { "minimum": -18446744073709551615 },
+ "tests": [
+ {
+ "description": "comparison works for very negative numbers",
+ "data": -18446744073709551600,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "float comparison with high precision on negative numbers",
+ "schema": {
+ "minimum": -972783798187987123879878123.18878137,
+ "exclusiveMinimum": true
+ },
+ "tests": [
+ {
+ "description": "comparison works for very negative numbers",
+ "data": -972783798187987123879878123.188781371,
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/json/tests/draft4/optional/ecmascript-regex.json b/tests/draft4/optional/ecmascript-regex.json
index 77624cf..9266c04 100644
--- a/json/tests/draft4/optional/ecmascript-regex.json
+++ b/tests/draft4/optional/ecmascript-regex.json
@@ -7,12 +7,12 @@
},
"tests": [
{
- "description": "matches in Python, but should not in jsonschema",
+ "description": "matches in Python, but not in ECMA 262",
"data": "abc\\n",
"valid": false
},
{
- "description": "should match",
+ "description": "matches",
"data": "abc",
"valid": true
}
@@ -342,7 +342,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "pattern with ASCII ranges",
"schema": { "pattern": "[a-z]cole" },
"tests": [
{
@@ -384,7 +384,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "pattern with non-ASCII digits",
"schema": { "pattern": "^\\p{digit}+$" },
"tests": [
{
@@ -469,7 +469,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "patternProperties with ASCII ranges",
"schema": {
"type": "object",
"patternProperties": {
@@ -523,7 +523,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "patternProperties with non-ASCII digits",
"schema": {
"type": "object",
"patternProperties": {
diff --git a/json/tests/draft4/optional/float-overflow.json b/tests/draft4/optional/float-overflow.json
index 47fd5ba..47fd5ba 100644
--- a/json/tests/draft4/optional/float-overflow.json
+++ b/tests/draft4/optional/float-overflow.json
diff --git a/json/tests/draft4/optional/format/date-time.json b/tests/draft4/optional/format/date-time.json
index f4f9933..0911273 100644
--- a/json/tests/draft4/optional/format/date-time.json
+++ b/tests/draft4/optional/format/date-time.json
@@ -119,12 +119,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the date portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion",
"data": "1963-06-1৪T00:00:00Z",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the time portion",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion",
"data": "1963-06-11T0৪:00:00Z",
"valid": false
}
diff --git a/json/tests/draft4/optional/format/email.json b/tests/draft4/optional/format/email.json
index d6761a4..d6761a4 100644
--- a/json/tests/draft4/optional/format/email.json
+++ b/tests/draft4/optional/format/email.json
diff --git a/json/tests/draft4/optional/format/hostname.json b/tests/draft4/optional/format/hostname.json
index 8a67fda..8a67fda 100644
--- a/json/tests/draft4/optional/format/hostname.json
+++ b/tests/draft4/optional/format/hostname.json
diff --git a/json/tests/draft-next/optional/format/ipv4.json b/tests/draft4/optional/format/ipv4.json
index 6b166c7..4706581 100644
--- a/json/tests/draft-next/optional/format/ipv4.json
+++ b/tests/draft4/optional/format/ipv4.json
@@ -64,7 +64,7 @@
"valid": false
},
{
- "description": "leading zeroes should be rejected, as they are treated as octals",
+ "description": "invalid leading zeroes, as they are treated as octals",
"comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
"data": "087.10.0.1",
"valid": false
@@ -75,7 +75,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২7.0.0.1",
"valid": false
}
diff --git a/json/tests/draft4/optional/format/ipv6.json b/tests/draft4/optional/format/ipv6.json
index 6379927..94368f2 100644
--- a/json/tests/draft4/optional/format/ipv6.json
+++ b/tests/draft4/optional/format/ipv6.json
@@ -194,12 +194,12 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1:2:3:4:5:6:7:৪",
"valid": false
},
{
- "description": "non-ascii digits should be rejected in the ipv4 portion also",
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion",
"data": "1:2::192.16৪.0.1",
"valid": false
}
diff --git a/json/tests/draft4/optional/format/unknown.json b/tests/draft4/optional/format/unknown.json
index 12339ae..12339ae 100644
--- a/json/tests/draft4/optional/format/unknown.json
+++ b/tests/draft4/optional/format/unknown.json
diff --git a/json/tests/draft4/optional/format/uri.json b/tests/draft4/optional/format/uri.json
index 792d71a..792d71a 100644
--- a/json/tests/draft4/optional/format/uri.json
+++ b/tests/draft4/optional/format/uri.json
diff --git a/json/tests/draft4/optional/non-bmp-regex.json b/tests/draft4/optional/non-bmp-regex.json
index dd67af2..dd67af2 100644
--- a/json/tests/draft4/optional/non-bmp-regex.json
+++ b/tests/draft4/optional/non-bmp-regex.json
diff --git a/json/tests/draft4/optional/zeroTerminatedFloats.json b/tests/draft4/optional/zeroTerminatedFloats.json
index 9b50ea2..9b50ea2 100644
--- a/json/tests/draft4/optional/zeroTerminatedFloats.json
+++ b/tests/draft4/optional/zeroTerminatedFloats.json
diff --git a/json/tests/draft4/pattern.json b/tests/draft4/pattern.json
index 92db0f9..92db0f9 100644
--- a/json/tests/draft4/pattern.json
+++ b/tests/draft4/pattern.json
diff --git a/json/tests/draft4/patternProperties.json b/tests/draft4/patternProperties.json
index 0511763..0511763 100644
--- a/json/tests/draft4/patternProperties.json
+++ b/tests/draft4/patternProperties.json
diff --git a/json/tests/draft4/properties.json b/tests/draft4/properties.json
index 9fcb601..9fcb601 100644
--- a/json/tests/draft4/properties.json
+++ b/tests/draft4/properties.json
diff --git a/json/tests/draft4/ref.json b/tests/draft4/ref.json
index d9978e9..b714fb0 100644
--- a/json/tests/draft4/ref.json
+++ b/tests/draft4/ref.json
@@ -493,12 +493,12 @@
},
"tests": [
{
- "description": "number should pass",
+ "description": "number is valid",
"data": 1,
"valid": true
},
{
- "description": "non-number should fail",
+ "description": "non-number is invalid",
"data": "a",
"valid": false
}
diff --git a/json/tests/draft4/refRemote.json b/tests/draft4/refRemote.json
index 412c9ff..412c9ff 100644
--- a/json/tests/draft4/refRemote.json
+++ b/tests/draft4/refRemote.json
diff --git a/json/tests/draft4/required.json b/tests/draft4/required.json
index 9b05318..9b05318 100644
--- a/json/tests/draft4/required.json
+++ b/tests/draft4/required.json
diff --git a/json/tests/draft4/type.json b/tests/draft4/type.json
index df46677..df46677 100644
--- a/json/tests/draft4/type.json
+++ b/tests/draft4/type.json
diff --git a/json/tests/draft4/uniqueItems.json b/tests/draft4/uniqueItems.json
index 2ccf666..2ccf666 100644
--- a/json/tests/draft4/uniqueItems.json
+++ b/tests/draft4/uniqueItems.json
diff --git a/json/tests/draft6/additionalItems.json b/tests/draft6/additionalItems.json
index 454142b..454142b 100644
--- a/json/tests/draft6/additionalItems.json
+++ b/tests/draft6/additionalItems.json
diff --git a/json/tests/draft6/additionalProperties.json b/tests/draft6/additionalProperties.json
index 98b8842..98b8842 100644
--- a/json/tests/draft6/additionalProperties.json
+++ b/tests/draft6/additionalProperties.json
diff --git a/json/tests/draft6/allOf.json b/tests/draft6/allOf.json
index ec9319e..ec9319e 100644
--- a/json/tests/draft6/allOf.json
+++ b/tests/draft6/allOf.json
diff --git a/json/tests/draft6/anyOf.json b/tests/draft6/anyOf.json
index b720afa..ab5eb38 100644
--- a/json/tests/draft6/anyOf.json
+++ b/tests/draft6/anyOf.json
@@ -185,31 +185,5 @@
"valid": false
}
]
- },
- {
- "description": "nested anyOf, to check validation semantics",
- "schema": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- }
- ]
- }
- ]
- },
- "tests": [
- {
- "description": "null is valid",
- "data": null,
- "valid": true
- },
- {
- "description": "anything non-null is invalid",
- "data": 123,
- "valid": false
- }
- ]
}
]
diff --git a/json/tests/draft6/boolean_schema.json b/tests/draft6/boolean_schema.json
index 6d40f23..6d40f23 100644
--- a/json/tests/draft6/boolean_schema.json
+++ b/tests/draft6/boolean_schema.json
diff --git a/json/tests/draft6/const.json b/tests/draft6/const.json
index 1c2cafc..1c2cafc 100644
--- a/json/tests/draft6/const.json
+++ b/tests/draft6/const.json
diff --git a/json/tests/draft6/contains.json b/tests/draft6/contains.json
index be87c97..be87c97 100644
--- a/json/tests/draft6/contains.json
+++ b/tests/draft6/contains.json
diff --git a/json/tests/draft6/default.json b/tests/draft6/default.json
index 289a9b6..289a9b6 100644
--- a/json/tests/draft6/default.json
+++ b/tests/draft6/default.json
diff --git a/json/tests/draft6/definitions.json b/tests/draft6/definitions.json
index d772fde..d772fde 100644
--- a/json/tests/draft6/definitions.json
+++ b/tests/draft6/definitions.json
diff --git a/json/tests/draft6/dependencies.json b/tests/draft6/dependencies.json
index a5e5428..a5e5428 100644
--- a/json/tests/draft6/dependencies.json
+++ b/tests/draft6/dependencies.json
diff --git a/json/tests/draft6/enum.json b/tests/draft6/enum.json
index f085097..f085097 100644
--- a/json/tests/draft6/enum.json
+++ b/tests/draft6/enum.json
diff --git a/json/tests/draft6/exclusiveMaximum.json b/tests/draft6/exclusiveMaximum.json
index dc3cd70..dc3cd70 100644
--- a/json/tests/draft6/exclusiveMaximum.json
+++ b/tests/draft6/exclusiveMaximum.json
diff --git a/json/tests/draft6/exclusiveMinimum.json b/tests/draft6/exclusiveMinimum.json
index b38d7ec..b38d7ec 100644
--- a/json/tests/draft6/exclusiveMinimum.json
+++ b/tests/draft6/exclusiveMinimum.json
diff --git a/json/tests/draft6/format.json b/tests/draft6/format.json
index 2df2a9f..2df2a9f 100644
--- a/json/tests/draft6/format.json
+++ b/tests/draft6/format.json
diff --git a/json/tests/draft6/id.json b/tests/draft6/id.json
index 0cbff5a..0cbff5a 100644
--- a/json/tests/draft6/id.json
+++ b/tests/draft6/id.json
diff --git a/json/tests/draft6/infinite-loop-detection.json b/tests/draft6/infinite-loop-detection.json
index f98c74f..f98c74f 100644
--- a/json/tests/draft6/infinite-loop-detection.json
+++ b/tests/draft6/infinite-loop-detection.json
diff --git a/json/tests/draft6/items.json b/tests/draft6/items.json
index dc56e7c..dc56e7c 100644
--- a/json/tests/draft6/items.json
+++ b/tests/draft6/items.json
diff --git a/json/tests/draft6/maxItems.json b/tests/draft6/maxItems.json
index f0c36ab..f0c36ab 100644
--- a/json/tests/draft6/maxItems.json
+++ b/tests/draft6/maxItems.json
diff --git a/json/tests/draft6/maxLength.json b/tests/draft6/maxLength.json
index 748b4da..748b4da 100644
--- a/json/tests/draft6/maxLength.json
+++ b/tests/draft6/maxLength.json
diff --git a/json/tests/draft6/maxProperties.json b/tests/draft6/maxProperties.json
index acec142..acec142 100644
--- a/json/tests/draft6/maxProperties.json
+++ b/tests/draft6/maxProperties.json
diff --git a/json/tests/draft6/maximum.json b/tests/draft6/maximum.json
index 6844a39..6844a39 100644
--- a/json/tests/draft6/maximum.json
+++ b/tests/draft6/maximum.json
diff --git a/json/tests/draft6/minItems.json b/tests/draft6/minItems.json
index d3b1872..d3b1872 100644
--- a/json/tests/draft6/minItems.json
+++ b/tests/draft6/minItems.json
diff --git a/json/tests/draft6/minLength.json b/tests/draft6/minLength.json
index 64db948..64db948 100644
--- a/json/tests/draft6/minLength.json
+++ b/tests/draft6/minLength.json
diff --git a/json/tests/draft6/minProperties.json b/tests/draft6/minProperties.json
index 9f74f78..9f74f78 100644
--- a/json/tests/draft6/minProperties.json
+++ b/tests/draft6/minProperties.json
diff --git a/json/tests/draft6/minimum.json b/tests/draft6/minimum.json
index 21ae50e..21ae50e 100644
--- a/json/tests/draft6/minimum.json
+++ b/tests/draft6/minimum.json
diff --git a/json/tests/draft6/multipleOf.json b/tests/draft6/multipleOf.json
index faa87cf..faa87cf 100644
--- a/json/tests/draft6/multipleOf.json
+++ b/tests/draft6/multipleOf.json
diff --git a/json/tests/draft6/not.json b/tests/draft6/not.json
index 98de0ed..98de0ed 100644
--- a/json/tests/draft6/not.json
+++ b/tests/draft6/not.json
diff --git a/json/tests/draft6/oneOf.json b/tests/draft6/oneOf.json
index eeb7ae8..eeb7ae8 100644
--- a/json/tests/draft6/oneOf.json
+++ b/tests/draft6/oneOf.json
diff --git a/json/tests/draft-next/optional/bignum.json b/tests/draft6/optional/bignum.json
index 3f49226..94b4a4e 100644
--- a/json/tests/draft-next/optional/bignum.json
+++ b/tests/draft6/optional/bignum.json
@@ -43,7 +43,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "maximum integer comparison",
"schema": { "maximum": 18446744073709551615 },
"tests": [
{
@@ -67,7 +67,7 @@
]
},
{
- "description": "integer comparison",
+ "description": "minimum integer comparison",
"schema": { "minimum": -18446744073709551615 },
"tests": [
{
diff --git a/json/tests/draft7/optional/ecmascript-regex.json b/tests/draft6/optional/ecmascript-regex.json
index 1beb0b3..764248f 100644
--- a/json/tests/draft7/optional/ecmascript-regex.json
+++ b/tests/draft6/optional/ecmascript-regex.json
@@ -7,12 +7,12 @@
},
"tests": [
{
- "description": "matches in Python, but should not in jsonschema",
+ "description": "matches in Python, but not in ECMA 262",
"data": "abc\\n",
"valid": false
},
{
- "description": "should match",
+ "description": "matches",
"data": "abc",
"valid": true
}
@@ -342,7 +342,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "pattern with ASCII ranges",
"schema": { "pattern": "[a-z]cole" },
"tests": [
{
@@ -384,7 +384,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "pattern with non-ASCII digits",
"schema": { "pattern": "^\\p{digit}+$" },
"tests": [
{
@@ -469,7 +469,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "patternProperties with ASCII ranges",
"schema": {
"type": "object",
"patternProperties": {
@@ -523,7 +523,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "patternProperties with non-ASCII digits",
"schema": {
"type": "object",
"patternProperties": {
diff --git a/json/tests/draft6/optional/float-overflow.json b/tests/draft6/optional/float-overflow.json
index 52ff982..52ff982 100644
--- a/json/tests/draft6/optional/float-overflow.json
+++ b/tests/draft6/optional/float-overflow.json
diff --git a/tests/draft6/optional/format/date-time.json b/tests/draft6/optional/format/date-time.json
new file mode 100644
index 0000000..0911273
--- /dev/null
+++ b/tests/draft6/optional/format/date-time.json
@@ -0,0 +1,133 @@
+[
+ {
+ "description": "validation of date-time strings",
+ "schema": { "format": "date-time" },
+ "tests": [
+ {
+ "description": "all string formats ignore integers",
+ "data": 12,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore floats",
+ "data": 13.7,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore objects",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore arrays",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore booleans",
+ "data": false,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore nulls",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string",
+ "data": "1963-06-19T08:30:06.283185Z",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string without second fraction",
+ "data": "1963-06-19T08:30:06Z",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string with plus offset",
+ "data": "1937-01-01T12:00:27.87+00:20",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string with minus offset",
+ "data": "1990-12-31T15:59:50.123-08:00",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time with a leap second, UTC",
+ "data": "1998-12-31T23:59:60Z",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time with a leap second, with minus offset",
+ "data": "1998-12-31T15:59:60.123-08:00",
+ "valid": true
+ },
+ {
+ "description": "an invalid date-time past leap second, UTC",
+ "data": "1998-12-31T23:59:61Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid date-time with leap second on a wrong minute, UTC",
+ "data": "1998-12-31T23:58:60Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid date-time with leap second on a wrong hour, UTC",
+ "data": "1998-12-31T22:59:60Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid day in date-time string",
+ "data": "1990-02-31T15:59:59.123-08:00",
+ "valid": false
+ },
+ {
+ "description": "an invalid offset in date-time string",
+ "data": "1990-12-31T15:59:59-24:00",
+ "valid": false
+ },
+ {
+ "description": "an invalid closing Z after time-zone offset",
+ "data": "1963-06-19T08:30:06.28123+01:00Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid date-time string",
+ "data": "06/19/1963 08:30:06 PST",
+ "valid": false
+ },
+ {
+ "description": "case-insensitive T and Z",
+ "data": "1963-06-19t08:30:06.283185z",
+ "valid": true
+ },
+ {
+ "description": "only RFC3339 not all of ISO 8601 are valid",
+ "data": "2013-350T01:01:01",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded month dates",
+ "data": "1963-6-19T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded day dates",
+ "data": "1963-06-1T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion",
+ "data": "1963-06-1৪T00:00:00Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion",
+ "data": "1963-06-11T0৪:00:00Z",
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/json/tests/draft6/optional/format/email.json b/tests/draft6/optional/format/email.json
index d6761a4..d6761a4 100644
--- a/json/tests/draft6/optional/format/email.json
+++ b/tests/draft6/optional/format/email.json
diff --git a/json/tests/draft6/optional/format/hostname.json b/tests/draft6/optional/format/hostname.json
index 8a67fda..8a67fda 100644
--- a/json/tests/draft6/optional/format/hostname.json
+++ b/tests/draft6/optional/format/hostname.json
diff --git a/tests/draft6/optional/format/ipv4.json b/tests/draft6/optional/format/ipv4.json
new file mode 100644
index 0000000..4706581
--- /dev/null
+++ b/tests/draft6/optional/format/ipv4.json
@@ -0,0 +1,84 @@
+[
+ {
+ "description": "validation of IP addresses",
+ "schema": { "format": "ipv4" },
+ "tests": [
+ {
+ "description": "all string formats ignore integers",
+ "data": 12,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore floats",
+ "data": 13.7,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore objects",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore arrays",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore booleans",
+ "data": false,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore nulls",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "a valid IP address",
+ "data": "192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "an IP address with too many components",
+ "data": "127.0.0.0.1",
+ "valid": false
+ },
+ {
+ "description": "an IP address with out-of-range values",
+ "data": "256.256.256.256",
+ "valid": false
+ },
+ {
+ "description": "an IP address without 4 components",
+ "data": "127.0",
+ "valid": false
+ },
+ {
+ "description": "an IP address as an integer",
+ "data": "0x7f000001",
+ "valid": false
+ },
+ {
+ "description": "an IP address as an integer (decimal)",
+ "data": "2130706433",
+ "valid": false
+ },
+ {
+ "description": "invalid leading zeroes, as they are treated as octals",
+ "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
+ "data": "087.10.0.1",
+ "valid": false
+ },
+ {
+ "description": "value without leading zero is valid",
+ "data": "87.10.0.1",
+ "valid": true
+ },
+ {
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
+ "data": "1২7.0.0.1",
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/tests/draft6/optional/format/ipv6.json b/tests/draft6/optional/format/ipv6.json
new file mode 100644
index 0000000..94368f2
--- /dev/null
+++ b/tests/draft6/optional/format/ipv6.json
@@ -0,0 +1,208 @@
+[
+ {
+ "description": "validation of IPv6 addresses",
+ "schema": { "format": "ipv6" },
+ "tests": [
+ {
+ "description": "all string formats ignore integers",
+ "data": 12,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore floats",
+ "data": 13.7,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore objects",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore arrays",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore booleans",
+ "data": false,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore nulls",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "a valid IPv6 address",
+ "data": "::1",
+ "valid": true
+ },
+ {
+ "description": "an IPv6 address with out-of-range values",
+ "data": "12345::",
+ "valid": false
+ },
+ {
+ "description": "trailing 4 hex symbols is valid",
+ "data": "::abef",
+ "valid": true
+ },
+ {
+ "description": "trailing 5 hex symbols is invalid",
+ "data": "::abcef",
+ "valid": false
+ },
+ {
+ "description": "an IPv6 address with too many components",
+ "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1",
+ "valid": false
+ },
+ {
+ "description": "an IPv6 address containing illegal characters",
+ "data": "::laptop",
+ "valid": false
+ },
+ {
+ "description": "no digits is valid",
+ "data": "::",
+ "valid": true
+ },
+ {
+ "description": "leading colons is valid",
+ "data": "::42:ff:1",
+ "valid": true
+ },
+ {
+ "description": "trailing colons is valid",
+ "data": "d6::",
+ "valid": true
+ },
+ {
+ "description": "missing leading octet is invalid",
+ "data": ":2:3:4:5:6:7:8",
+ "valid": false
+ },
+ {
+ "description": "missing trailing octet is invalid",
+ "data": "1:2:3:4:5:6:7:",
+ "valid": false
+ },
+ {
+ "description": "missing leading octet with omitted octets later",
+ "data": ":2:3:4::8",
+ "valid": false
+ },
+ {
+ "description": "single set of double colons in the middle is valid",
+ "data": "1:d6::42",
+ "valid": true
+ },
+ {
+ "description": "two sets of double colons is invalid",
+ "data": "1::d6::42",
+ "valid": false
+ },
+ {
+ "description": "mixed format with the ipv4 section as decimal octets",
+ "data": "1::d6:192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "mixed format with double colons between the sections",
+ "data": "1:2::192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "mixed format with ipv4 section with octet out of range",
+ "data": "1::2:192.168.256.1",
+ "valid": false
+ },
+ {
+ "description": "mixed format with ipv4 section with a hex octet",
+ "data": "1::2:192.168.ff.1",
+ "valid": false
+ },
+ {
+ "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)",
+ "data": "::ffff:192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "triple colons is invalid",
+ "data": "1:2:3:4:5:::8",
+ "valid": false
+ },
+ {
+ "description": "8 octets",
+ "data": "1:2:3:4:5:6:7:8",
+ "valid": true
+ },
+ {
+ "description": "insufficient octets without double colons",
+ "data": "1:2:3:4:5:6:7",
+ "valid": false
+ },
+ {
+ "description": "no colons is invalid",
+ "data": "1",
+ "valid": false
+ },
+ {
+ "description": "ipv4 is not ipv6",
+ "data": "127.0.0.1",
+ "valid": false
+ },
+ {
+ "description": "ipv4 segment must have 4 octets",
+ "data": "1:2:3:4:1.2.3",
+ "valid": false
+ },
+ {
+ "description": "leading whitespace is invalid",
+ "data": " ::1",
+ "valid": false
+ },
+ {
+ "description": "trailing whitespace is invalid",
+ "data": "::1 ",
+ "valid": false
+ },
+ {
+ "description": "netmask is not a part of ipv6 address",
+ "data": "fe80::/64",
+ "valid": false
+ },
+ {
+ "description": "zone id is not a part of ipv6 address",
+ "data": "fe80::a%eth1",
+ "valid": false
+ },
+ {
+ "description": "a long valid ipv6",
+ "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
+ "valid": true
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, first",
+ "data": "100:100:100:100:100:100:255.255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, second",
+ "data": "100:100:100:100:100:100:100:255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
+ "data": "1:2:3:4:5:6:7:৪",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion",
+ "data": "1:2::192.16৪.0.1",
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/json/tests/draft6/optional/format/json-pointer.json b/tests/draft6/optional/format/json-pointer.json
index a0346b5..a0346b5 100644
--- a/json/tests/draft6/optional/format/json-pointer.json
+++ b/tests/draft6/optional/format/json-pointer.json
diff --git a/json/tests/draft6/optional/format/unknown.json b/tests/draft6/optional/format/unknown.json
index 12339ae..12339ae 100644
--- a/json/tests/draft6/optional/format/unknown.json
+++ b/tests/draft6/optional/format/unknown.json
diff --git a/json/tests/draft6/optional/format/uri-reference.json b/tests/draft6/optional/format/uri-reference.json
index 7cdf228..7cdf228 100644
--- a/json/tests/draft6/optional/format/uri-reference.json
+++ b/tests/draft6/optional/format/uri-reference.json
diff --git a/json/tests/draft6/optional/format/uri-template.json b/tests/draft6/optional/format/uri-template.json
index df355c5..df355c5 100644
--- a/json/tests/draft6/optional/format/uri-template.json
+++ b/tests/draft6/optional/format/uri-template.json
diff --git a/json/tests/draft6/optional/format/uri.json b/tests/draft6/optional/format/uri.json
index 792d71a..792d71a 100644
--- a/json/tests/draft6/optional/format/uri.json
+++ b/tests/draft6/optional/format/uri.json
diff --git a/json/tests/draft6/optional/non-bmp-regex.json b/tests/draft6/optional/non-bmp-regex.json
index dd67af2..dd67af2 100644
--- a/json/tests/draft6/optional/non-bmp-regex.json
+++ b/tests/draft6/optional/non-bmp-regex.json
diff --git a/json/tests/draft6/pattern.json b/tests/draft6/pattern.json
index 92db0f9..92db0f9 100644
--- a/json/tests/draft6/pattern.json
+++ b/tests/draft6/pattern.json
diff --git a/json/tests/draft6/patternProperties.json b/tests/draft6/patternProperties.json
index 34b2e85..34b2e85 100644
--- a/json/tests/draft6/patternProperties.json
+++ b/tests/draft6/patternProperties.json
diff --git a/json/tests/draft6/properties.json b/tests/draft6/properties.json
index 8c3ed35..8c3ed35 100644
--- a/json/tests/draft6/properties.json
+++ b/tests/draft6/properties.json
diff --git a/json/tests/draft6/propertyNames.json b/tests/draft6/propertyNames.json
index f0788e6..f0788e6 100644
--- a/json/tests/draft6/propertyNames.json
+++ b/tests/draft6/propertyNames.json
diff --git a/json/tests/draft6/ref.json b/tests/draft6/ref.json
index 3e72a59..3e72a59 100644
--- a/json/tests/draft6/ref.json
+++ b/tests/draft6/ref.json
diff --git a/json/tests/draft6/refRemote.json b/tests/draft6/refRemote.json
index c2b2002..c2b2002 100644
--- a/json/tests/draft6/refRemote.json
+++ b/tests/draft6/refRemote.json
diff --git a/json/tests/draft6/required.json b/tests/draft6/required.json
index abf18f3..abf18f3 100644
--- a/json/tests/draft6/required.json
+++ b/tests/draft6/required.json
diff --git a/json/tests/draft6/type.json b/tests/draft6/type.json
index 8304647..8304647 100644
--- a/json/tests/draft6/type.json
+++ b/tests/draft6/type.json
diff --git a/json/tests/draft6/uniqueItems.json b/tests/draft6/uniqueItems.json
index 2ccf666..2ccf666 100644
--- a/json/tests/draft6/uniqueItems.json
+++ b/tests/draft6/uniqueItems.json
diff --git a/json/tests/draft6/unknownKeyword.json b/tests/draft6/unknownKeyword.json
index 1f58d97..1f58d97 100644
--- a/json/tests/draft6/unknownKeyword.json
+++ b/tests/draft6/unknownKeyword.json
diff --git a/json/tests/draft7/additionalItems.json b/tests/draft7/additionalItems.json
index 454142b..454142b 100644
--- a/json/tests/draft7/additionalItems.json
+++ b/tests/draft7/additionalItems.json
diff --git a/json/tests/draft7/additionalProperties.json b/tests/draft7/additionalProperties.json
index 98b8842..98b8842 100644
--- a/json/tests/draft7/additionalProperties.json
+++ b/tests/draft7/additionalProperties.json
diff --git a/json/tests/draft7/allOf.json b/tests/draft7/allOf.json
index ec9319e..ec9319e 100644
--- a/json/tests/draft7/allOf.json
+++ b/tests/draft7/allOf.json
diff --git a/tests/draft7/anyOf.json b/tests/draft7/anyOf.json
new file mode 100644
index 0000000..ab5eb38
--- /dev/null
+++ b/tests/draft7/anyOf.json
@@ -0,0 +1,189 @@
+[
+ {
+ "description": "anyOf",
+ "schema": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "minimum": 2
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "first anyOf valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "second anyOf valid",
+ "data": 2.5,
+ "valid": true
+ },
+ {
+ "description": "both anyOf valid",
+ "data": 3,
+ "valid": true
+ },
+ {
+ "description": "neither anyOf valid",
+ "data": 1.5,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "anyOf with base schema",
+ "schema": {
+ "type": "string",
+ "anyOf" : [
+ {
+ "maxLength": 2
+ },
+ {
+ "minLength": 4
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "mismatch base schema",
+ "data": 3,
+ "valid": false
+ },
+ {
+ "description": "one anyOf valid",
+ "data": "foobar",
+ "valid": true
+ },
+ {
+ "description": "both anyOf invalid",
+ "data": "foo",
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "anyOf with boolean schemas, all true",
+ "schema": {"anyOf": [true, true]},
+ "tests": [
+ {
+ "description": "any value is valid",
+ "data": "foo",
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "anyOf with boolean schemas, some true",
+ "schema": {"anyOf": [true, false]},
+ "tests": [
+ {
+ "description": "any value is valid",
+ "data": "foo",
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "anyOf with boolean schemas, all false",
+ "schema": {"anyOf": [false, false]},
+ "tests": [
+ {
+ "description": "any value is invalid",
+ "data": "foo",
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "anyOf complex types",
+ "schema": {
+ "anyOf": [
+ {
+ "properties": {
+ "bar": {"type": "integer"}
+ },
+ "required": ["bar"]
+ },
+ {
+ "properties": {
+ "foo": {"type": "string"}
+ },
+ "required": ["foo"]
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "first anyOf valid (complex)",
+ "data": {"bar": 2},
+ "valid": true
+ },
+ {
+ "description": "second anyOf valid (complex)",
+ "data": {"foo": "baz"},
+ "valid": true
+ },
+ {
+ "description": "both anyOf valid (complex)",
+ "data": {"foo": "baz", "bar": 2},
+ "valid": true
+ },
+ {
+ "description": "neither anyOf valid (complex)",
+ "data": {"foo": 2, "bar": "quux"},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "anyOf with one empty schema",
+ "schema": {
+ "anyOf": [
+ { "type": "number" },
+ {}
+ ]
+ },
+ "tests": [
+ {
+ "description": "string is valid",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "number is valid",
+ "data": 123,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "nested anyOf, to check validation semantics",
+ "schema": {
+ "anyOf": [
+ {
+ "anyOf": [
+ {
+ "type": "null"
+ }
+ ]
+ }
+ ]
+ },
+ "tests": [
+ {
+ "description": "null is valid",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "anything non-null is invalid",
+ "data": 123,
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/json/tests/draft7/boolean_schema.json b/tests/draft7/boolean_schema.json
index 6d40f23..6d40f23 100644
--- a/json/tests/draft7/boolean_schema.json
+++ b/tests/draft7/boolean_schema.json
diff --git a/json/tests/draft7/const.json b/tests/draft7/const.json
index 1c2cafc..1c2cafc 100644
--- a/json/tests/draft7/const.json
+++ b/tests/draft7/const.json
diff --git a/json/tests/draft7/contains.json b/tests/draft7/contains.json
index b1c36a4..b1c36a4 100644
--- a/json/tests/draft7/contains.json
+++ b/tests/draft7/contains.json
diff --git a/json/tests/draft7/default.json b/tests/draft7/default.json
index 289a9b6..289a9b6 100644
--- a/json/tests/draft7/default.json
+++ b/tests/draft7/default.json
diff --git a/json/tests/draft7/definitions.json b/tests/draft7/definitions.json
index afe396e..afe396e 100644
--- a/json/tests/draft7/definitions.json
+++ b/tests/draft7/definitions.json
diff --git a/json/tests/draft7/dependencies.json b/tests/draft7/dependencies.json
index a5e5428..a5e5428 100644
--- a/json/tests/draft7/dependencies.json
+++ b/tests/draft7/dependencies.json
diff --git a/json/tests/draft7/enum.json b/tests/draft7/enum.json
index f085097..f085097 100644
--- a/json/tests/draft7/enum.json
+++ b/tests/draft7/enum.json
diff --git a/json/tests/draft7/exclusiveMaximum.json b/tests/draft7/exclusiveMaximum.json
index dc3cd70..dc3cd70 100644
--- a/json/tests/draft7/exclusiveMaximum.json
+++ b/tests/draft7/exclusiveMaximum.json
diff --git a/json/tests/draft7/exclusiveMinimum.json b/tests/draft7/exclusiveMinimum.json
index b38d7ec..b38d7ec 100644
--- a/json/tests/draft7/exclusiveMinimum.json
+++ b/tests/draft7/exclusiveMinimum.json
diff --git a/json/tests/draft7/format.json b/tests/draft7/format.json
index e2447d6..e2447d6 100644
--- a/json/tests/draft7/format.json
+++ b/tests/draft7/format.json
diff --git a/json/tests/draft7/id.json b/tests/draft7/id.json
index b03248b..b03248b 100644
--- a/json/tests/draft7/id.json
+++ b/tests/draft7/id.json
diff --git a/json/tests/draft7/if-then-else.json b/tests/draft7/if-then-else.json
index 284e919..284e919 100644
--- a/json/tests/draft7/if-then-else.json
+++ b/tests/draft7/if-then-else.json
diff --git a/json/tests/draft7/infinite-loop-detection.json b/tests/draft7/infinite-loop-detection.json
index f98c74f..f98c74f 100644
--- a/json/tests/draft7/infinite-loop-detection.json
+++ b/tests/draft7/infinite-loop-detection.json
diff --git a/json/tests/draft7/items.json b/tests/draft7/items.json
index dc56e7c..dc56e7c 100644
--- a/json/tests/draft7/items.json
+++ b/tests/draft7/items.json
diff --git a/json/tests/draft7/maxItems.json b/tests/draft7/maxItems.json
index f0c36ab..f0c36ab 100644
--- a/json/tests/draft7/maxItems.json
+++ b/tests/draft7/maxItems.json
diff --git a/json/tests/draft7/maxLength.json b/tests/draft7/maxLength.json
index 748b4da..748b4da 100644
--- a/json/tests/draft7/maxLength.json
+++ b/tests/draft7/maxLength.json
diff --git a/json/tests/draft7/maxProperties.json b/tests/draft7/maxProperties.json
index acec142..acec142 100644
--- a/json/tests/draft7/maxProperties.json
+++ b/tests/draft7/maxProperties.json
diff --git a/json/tests/draft7/maximum.json b/tests/draft7/maximum.json
index 6844a39..6844a39 100644
--- a/json/tests/draft7/maximum.json
+++ b/tests/draft7/maximum.json
diff --git a/json/tests/draft7/minItems.json b/tests/draft7/minItems.json
index d3b1872..d3b1872 100644
--- a/json/tests/draft7/minItems.json
+++ b/tests/draft7/minItems.json
diff --git a/json/tests/draft7/minLength.json b/tests/draft7/minLength.json
index 64db948..64db948 100644
--- a/json/tests/draft7/minLength.json
+++ b/tests/draft7/minLength.json
diff --git a/json/tests/draft7/minProperties.json b/tests/draft7/minProperties.json
index 9f74f78..9f74f78 100644
--- a/json/tests/draft7/minProperties.json
+++ b/tests/draft7/minProperties.json
diff --git a/json/tests/draft7/minimum.json b/tests/draft7/minimum.json
index 21ae50e..21ae50e 100644
--- a/json/tests/draft7/minimum.json
+++ b/tests/draft7/minimum.json
diff --git a/json/tests/draft7/multipleOf.json b/tests/draft7/multipleOf.json
index faa87cf..faa87cf 100644
--- a/json/tests/draft7/multipleOf.json
+++ b/tests/draft7/multipleOf.json
diff --git a/json/tests/draft7/not.json b/tests/draft7/not.json
index 98de0ed..98de0ed 100644
--- a/json/tests/draft7/not.json
+++ b/tests/draft7/not.json
diff --git a/json/tests/draft7/oneOf.json b/tests/draft7/oneOf.json
index eeb7ae8..eeb7ae8 100644
--- a/json/tests/draft7/oneOf.json
+++ b/tests/draft7/oneOf.json
diff --git a/tests/draft7/optional/bignum.json b/tests/draft7/optional/bignum.json
new file mode 100644
index 0000000..94b4a4e
--- /dev/null
+++ b/tests/draft7/optional/bignum.json
@@ -0,0 +1,93 @@
+[
+ {
+ "description": "integer",
+ "schema": { "type": "integer" },
+ "tests": [
+ {
+ "description": "a bignum is an integer",
+ "data": 12345678910111213141516171819202122232425262728293031,
+ "valid": true
+ },
+ {
+ "description": "a negative bignum is an integer",
+ "data": -12345678910111213141516171819202122232425262728293031,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "number",
+ "schema": { "type": "number" },
+ "tests": [
+ {
+ "description": "a bignum is a number",
+ "data": 98249283749234923498293171823948729348710298301928331,
+ "valid": true
+ },
+ {
+ "description": "a negative bignum is a number",
+ "data": -98249283749234923498293171823948729348710298301928331,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "string",
+ "schema": { "type": "string" },
+ "tests": [
+ {
+ "description": "a bignum is not a string",
+ "data": 98249283749234923498293171823948729348710298301928331,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "maximum integer comparison",
+ "schema": { "maximum": 18446744073709551615 },
+ "tests": [
+ {
+ "description": "comparison works for high numbers",
+ "data": 18446744073709551600,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "float comparison with high precision",
+ "schema": {
+ "exclusiveMaximum": 972783798187987123879878123.18878137
+ },
+ "tests": [
+ {
+ "description": "comparison works for high numbers",
+ "data": 972783798187987123879878123.188781371,
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "minimum integer comparison",
+ "schema": { "minimum": -18446744073709551615 },
+ "tests": [
+ {
+ "description": "comparison works for very negative numbers",
+ "data": -18446744073709551600,
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "float comparison with high precision on negative numbers",
+ "schema": {
+ "exclusiveMinimum": -972783798187987123879878123.18878137
+ },
+ "tests": [
+ {
+ "description": "comparison works for very negative numbers",
+ "data": -972783798187987123879878123.188781371,
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/json/tests/draft7/optional/content.json b/tests/draft7/optional/content.json
index 3f5a743..3f5a743 100644
--- a/json/tests/draft7/optional/content.json
+++ b/tests/draft7/optional/content.json
diff --git a/json/tests/draft6/optional/ecmascript-regex.json b/tests/draft7/optional/ecmascript-regex.json
index 1beb0b3..764248f 100644
--- a/json/tests/draft6/optional/ecmascript-regex.json
+++ b/tests/draft7/optional/ecmascript-regex.json
@@ -7,12 +7,12 @@
},
"tests": [
{
- "description": "matches in Python, but should not in jsonschema",
+ "description": "matches in Python, but not in ECMA 262",
"data": "abc\\n",
"valid": false
},
{
- "description": "should match",
+ "description": "matches",
"data": "abc",
"valid": true
}
@@ -342,7 +342,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "pattern with ASCII ranges",
"schema": { "pattern": "[a-z]cole" },
"tests": [
{
@@ -384,7 +384,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "pattern with non-ASCII digits",
"schema": { "pattern": "^\\p{digit}+$" },
"tests": [
{
@@ -469,7 +469,7 @@
]
},
{
- "description": "unicode characters do not match ascii ranges",
+ "description": "patternProperties with ASCII ranges",
"schema": {
"type": "object",
"patternProperties": {
@@ -523,7 +523,7 @@
]
},
{
- "description": "unicode digits are more than 0 through 9",
+ "description": "patternProperties with non-ASCII digits",
"schema": {
"type": "object",
"patternProperties": {
diff --git a/json/tests/draft7/optional/float-overflow.json b/tests/draft7/optional/float-overflow.json
index 52ff982..52ff982 100644
--- a/json/tests/draft7/optional/float-overflow.json
+++ b/tests/draft7/optional/float-overflow.json
diff --git a/tests/draft7/optional/format/date-time.json b/tests/draft7/optional/format/date-time.json
new file mode 100644
index 0000000..0911273
--- /dev/null
+++ b/tests/draft7/optional/format/date-time.json
@@ -0,0 +1,133 @@
+[
+ {
+ "description": "validation of date-time strings",
+ "schema": { "format": "date-time" },
+ "tests": [
+ {
+ "description": "all string formats ignore integers",
+ "data": 12,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore floats",
+ "data": 13.7,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore objects",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore arrays",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore booleans",
+ "data": false,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore nulls",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string",
+ "data": "1963-06-19T08:30:06.283185Z",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string without second fraction",
+ "data": "1963-06-19T08:30:06Z",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string with plus offset",
+ "data": "1937-01-01T12:00:27.87+00:20",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time string with minus offset",
+ "data": "1990-12-31T15:59:50.123-08:00",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time with a leap second, UTC",
+ "data": "1998-12-31T23:59:60Z",
+ "valid": true
+ },
+ {
+ "description": "a valid date-time with a leap second, with minus offset",
+ "data": "1998-12-31T15:59:60.123-08:00",
+ "valid": true
+ },
+ {
+ "description": "an invalid date-time past leap second, UTC",
+ "data": "1998-12-31T23:59:61Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid date-time with leap second on a wrong minute, UTC",
+ "data": "1998-12-31T23:58:60Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid date-time with leap second on a wrong hour, UTC",
+ "data": "1998-12-31T22:59:60Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid day in date-time string",
+ "data": "1990-02-31T15:59:59.123-08:00",
+ "valid": false
+ },
+ {
+ "description": "an invalid offset in date-time string",
+ "data": "1990-12-31T15:59:59-24:00",
+ "valid": false
+ },
+ {
+ "description": "an invalid closing Z after time-zone offset",
+ "data": "1963-06-19T08:30:06.28123+01:00Z",
+ "valid": false
+ },
+ {
+ "description": "an invalid date-time string",
+ "data": "06/19/1963 08:30:06 PST",
+ "valid": false
+ },
+ {
+ "description": "case-insensitive T and Z",
+ "data": "1963-06-19t08:30:06.283185z",
+ "valid": true
+ },
+ {
+ "description": "only RFC3339 not all of ISO 8601 are valid",
+ "data": "2013-350T01:01:01",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded month dates",
+ "data": "1963-6-19T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded day dates",
+ "data": "1963-06-1T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion",
+ "data": "1963-06-1৪T00:00:00Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion",
+ "data": "1963-06-11T0৪:00:00Z",
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/json/tests/draft-next/optional/format/date.json b/tests/draft7/optional/format/date.json
index b4f61ee..06c9ea0 100644
--- a/json/tests/draft-next/optional/format/date.json
+++ b/tests/draft7/optional/format/date.json
@@ -214,7 +214,7 @@
"valid": true
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
"data": "1963-06-1৪",
"valid": false
}
diff --git a/json/tests/draft7/optional/format/email.json b/tests/draft7/optional/format/email.json
index d6761a4..d6761a4 100644
--- a/json/tests/draft7/optional/format/email.json
+++ b/tests/draft7/optional/format/email.json
diff --git a/json/tests/draft7/optional/format/hostname.json b/tests/draft7/optional/format/hostname.json
index 8a67fda..8a67fda 100644
--- a/json/tests/draft7/optional/format/hostname.json
+++ b/tests/draft7/optional/format/hostname.json
diff --git a/json/tests/draft7/optional/format/idn-email.json b/tests/draft7/optional/format/idn-email.json
index 6e21374..6e21374 100644
--- a/json/tests/draft7/optional/format/idn-email.json
+++ b/tests/draft7/optional/format/idn-email.json
diff --git a/json/tests/draft7/optional/format/idn-hostname.json b/tests/draft7/optional/format/idn-hostname.json
index 6c8f86a..6c8f86a 100644
--- a/json/tests/draft7/optional/format/idn-hostname.json
+++ b/tests/draft7/optional/format/idn-hostname.json
diff --git a/tests/draft7/optional/format/ipv4.json b/tests/draft7/optional/format/ipv4.json
new file mode 100644
index 0000000..4706581
--- /dev/null
+++ b/tests/draft7/optional/format/ipv4.json
@@ -0,0 +1,84 @@
+[
+ {
+ "description": "validation of IP addresses",
+ "schema": { "format": "ipv4" },
+ "tests": [
+ {
+ "description": "all string formats ignore integers",
+ "data": 12,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore floats",
+ "data": 13.7,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore objects",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore arrays",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore booleans",
+ "data": false,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore nulls",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "a valid IP address",
+ "data": "192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "an IP address with too many components",
+ "data": "127.0.0.0.1",
+ "valid": false
+ },
+ {
+ "description": "an IP address with out-of-range values",
+ "data": "256.256.256.256",
+ "valid": false
+ },
+ {
+ "description": "an IP address without 4 components",
+ "data": "127.0",
+ "valid": false
+ },
+ {
+ "description": "an IP address as an integer",
+ "data": "0x7f000001",
+ "valid": false
+ },
+ {
+ "description": "an IP address as an integer (decimal)",
+ "data": "2130706433",
+ "valid": false
+ },
+ {
+ "description": "invalid leading zeroes, as they are treated as octals",
+ "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
+ "data": "087.10.0.1",
+ "valid": false
+ },
+ {
+ "description": "value without leading zero is valid",
+ "data": "87.10.0.1",
+ "valid": true
+ },
+ {
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
+ "data": "1২7.0.0.1",
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/tests/draft7/optional/format/ipv6.json b/tests/draft7/optional/format/ipv6.json
new file mode 100644
index 0000000..94368f2
--- /dev/null
+++ b/tests/draft7/optional/format/ipv6.json
@@ -0,0 +1,208 @@
+[
+ {
+ "description": "validation of IPv6 addresses",
+ "schema": { "format": "ipv6" },
+ "tests": [
+ {
+ "description": "all string formats ignore integers",
+ "data": 12,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore floats",
+ "data": 13.7,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore objects",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore arrays",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore booleans",
+ "data": false,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore nulls",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "a valid IPv6 address",
+ "data": "::1",
+ "valid": true
+ },
+ {
+ "description": "an IPv6 address with out-of-range values",
+ "data": "12345::",
+ "valid": false
+ },
+ {
+ "description": "trailing 4 hex symbols is valid",
+ "data": "::abef",
+ "valid": true
+ },
+ {
+ "description": "trailing 5 hex symbols is invalid",
+ "data": "::abcef",
+ "valid": false
+ },
+ {
+ "description": "an IPv6 address with too many components",
+ "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1",
+ "valid": false
+ },
+ {
+ "description": "an IPv6 address containing illegal characters",
+ "data": "::laptop",
+ "valid": false
+ },
+ {
+ "description": "no digits is valid",
+ "data": "::",
+ "valid": true
+ },
+ {
+ "description": "leading colons is valid",
+ "data": "::42:ff:1",
+ "valid": true
+ },
+ {
+ "description": "trailing colons is valid",
+ "data": "d6::",
+ "valid": true
+ },
+ {
+ "description": "missing leading octet is invalid",
+ "data": ":2:3:4:5:6:7:8",
+ "valid": false
+ },
+ {
+ "description": "missing trailing octet is invalid",
+ "data": "1:2:3:4:5:6:7:",
+ "valid": false
+ },
+ {
+ "description": "missing leading octet with omitted octets later",
+ "data": ":2:3:4::8",
+ "valid": false
+ },
+ {
+ "description": "single set of double colons in the middle is valid",
+ "data": "1:d6::42",
+ "valid": true
+ },
+ {
+ "description": "two sets of double colons is invalid",
+ "data": "1::d6::42",
+ "valid": false
+ },
+ {
+ "description": "mixed format with the ipv4 section as decimal octets",
+ "data": "1::d6:192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "mixed format with double colons between the sections",
+ "data": "1:2::192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "mixed format with ipv4 section with octet out of range",
+ "data": "1::2:192.168.256.1",
+ "valid": false
+ },
+ {
+ "description": "mixed format with ipv4 section with a hex octet",
+ "data": "1::2:192.168.ff.1",
+ "valid": false
+ },
+ {
+ "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)",
+ "data": "::ffff:192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "triple colons is invalid",
+ "data": "1:2:3:4:5:::8",
+ "valid": false
+ },
+ {
+ "description": "8 octets",
+ "data": "1:2:3:4:5:6:7:8",
+ "valid": true
+ },
+ {
+ "description": "insufficient octets without double colons",
+ "data": "1:2:3:4:5:6:7",
+ "valid": false
+ },
+ {
+ "description": "no colons is invalid",
+ "data": "1",
+ "valid": false
+ },
+ {
+ "description": "ipv4 is not ipv6",
+ "data": "127.0.0.1",
+ "valid": false
+ },
+ {
+ "description": "ipv4 segment must have 4 octets",
+ "data": "1:2:3:4:1.2.3",
+ "valid": false
+ },
+ {
+ "description": "leading whitespace is invalid",
+ "data": " ::1",
+ "valid": false
+ },
+ {
+ "description": "trailing whitespace is invalid",
+ "data": "::1 ",
+ "valid": false
+ },
+ {
+ "description": "netmask is not a part of ipv6 address",
+ "data": "fe80::/64",
+ "valid": false
+ },
+ {
+ "description": "zone id is not a part of ipv6 address",
+ "data": "fe80::a%eth1",
+ "valid": false
+ },
+ {
+ "description": "a long valid ipv6",
+ "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
+ "valid": true
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, first",
+ "data": "100:100:100:100:100:100:255.255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, second",
+ "data": "100:100:100:100:100:100:100:255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4)",
+ "data": "1:2:3:4:5:6:7:৪",
+ "valid": false
+ },
+ {
+ "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion",
+ "data": "1:2::192.16৪.0.1",
+ "valid": false
+ }
+ ]
+ }
+]
diff --git a/json/tests/draft7/optional/format/iri-reference.json b/tests/draft7/optional/format/iri-reference.json
index c6b4c22..c6b4c22 100644
--- a/json/tests/draft7/optional/format/iri-reference.json
+++ b/tests/draft7/optional/format/iri-reference.json
diff --git a/json/tests/draft7/optional/format/iri.json b/tests/draft7/optional/format/iri.json
index a0d12ae..a0d12ae 100644
--- a/json/tests/draft7/optional/format/iri.json
+++ b/tests/draft7/optional/format/iri.json
diff --git a/json/tests/draft7/optional/format/json-pointer.json b/tests/draft7/optional/format/json-pointer.json
index a0346b5..a0346b5 100644
--- a/json/tests/draft7/optional/format/json-pointer.json
+++ b/tests/draft7/optional/format/json-pointer.json
diff --git a/json/tests/draft7/optional/format/regex.json b/tests/draft7/optional/format/regex.json
index 3449177..3449177 100644
--- a/json/tests/draft7/optional/format/regex.json
+++ b/tests/draft7/optional/format/regex.json
diff --git a/json/tests/draft7/optional/format/relative-json-pointer.json b/tests/draft7/optional/format/relative-json-pointer.json
index 9309986..9309986 100644
--- a/json/tests/draft7/optional/format/relative-json-pointer.json
+++ b/tests/draft7/optional/format/relative-json-pointer.json
diff --git a/json/tests/draft-next/optional/format/time.json b/tests/draft7/optional/format/time.json
index 5011d78..3142587 100644
--- a/json/tests/draft-next/optional/format/time.json
+++ b/tests/draft7/optional/format/time.json
@@ -189,7 +189,7 @@
"valid": false
},
{
- "description": "non-ascii digits should be rejected",
+ "description": "invalid non-ASCII '২' (a Bengali 2)",
"data": "1২:00:00Z",
"valid": false
}
diff --git a/json/tests/draft7/optional/format/unknown.json b/tests/draft7/optional/format/unknown.json
index 12339ae..12339ae 100644
--- a/json/tests/draft7/optional/format/unknown.json
+++ b/tests/draft7/optional/format/unknown.json
diff --git a/json/tests/draft7/optional/format/uri-reference.json b/tests/draft7/optional/format/uri-reference.json
index 7cdf228..7cdf228 100644
--- a/json/tests/draft7/optional/format/uri-reference.json
+++ b/tests/draft7/optional/format/uri-reference.json
diff --git a/json/tests/draft7/optional/format/uri-template.json b/tests/draft7/optional/format/uri-template.json
index df355c5..df355c5 100644
--- a/json/tests/draft7/optional/format/uri-template.json
+++ b/tests/draft7/optional/format/uri-template.json
diff --git a/json/tests/draft7/optional/format/uri.json b/tests/draft7/optional/format/uri.json
index 792d71a..792d71a 100644
--- a/json/tests/draft7/optional/format/uri.json
+++ b/tests/draft7/optional/format/uri.json
diff --git a/json/tests/draft7/optional/non-bmp-regex.json b/tests/draft7/optional/non-bmp-regex.json
index dd67af2..dd67af2 100644
--- a/json/tests/draft7/optional/non-bmp-regex.json
+++ b/tests/draft7/optional/non-bmp-regex.json
diff --git a/json/tests/draft7/pattern.json b/tests/draft7/pattern.json
index 92db0f9..92db0f9 100644
--- a/json/tests/draft7/pattern.json
+++ b/tests/draft7/pattern.json
diff --git a/json/tests/draft7/patternProperties.json b/tests/draft7/patternProperties.json
index 34b2e85..34b2e85 100644
--- a/json/tests/draft7/patternProperties.json
+++ b/tests/draft7/patternProperties.json
diff --git a/json/tests/draft7/properties.json b/tests/draft7/properties.json
index 8c3ed35..8c3ed35 100644
--- a/json/tests/draft7/properties.json
+++ b/tests/draft7/properties.json
diff --git a/json/tests/draft7/propertyNames.json b/tests/draft7/propertyNames.json
index f0788e6..f0788e6 100644
--- a/json/tests/draft7/propertyNames.json
+++ b/tests/draft7/propertyNames.json
diff --git a/json/tests/draft7/ref.json b/tests/draft7/ref.json
index 52e5168..dbf0595 100644
--- a/json/tests/draft7/ref.json
+++ b/tests/draft7/ref.json
@@ -634,12 +634,12 @@
},
"tests": [
{
- "description": "number should pass",
+ "description": "number is valid",
"data": 1,
"valid": true
},
{
- "description": "non-number should fail",
+ "description": "non-number is invalid",
"data": "a",
"valid": false
}
diff --git a/json/tests/draft7/refRemote.json b/tests/draft7/refRemote.json
index c2b2002..c2b2002 100644
--- a/json/tests/draft7/refRemote.json
+++ b/tests/draft7/refRemote.json
diff --git a/json/tests/draft7/required.json b/tests/draft7/required.json
index abf18f3..abf18f3 100644
--- a/json/tests/draft7/required.json
+++ b/tests/draft7/required.json
diff --git a/json/tests/draft7/type.json b/tests/draft7/type.json
index 8304647..8304647 100644
--- a/json/tests/draft7/type.json
+++ b/tests/draft7/type.json
diff --git a/json/tests/draft7/uniqueItems.json b/tests/draft7/uniqueItems.json
index 2ccf666..2ccf666 100644
--- a/json/tests/draft7/uniqueItems.json
+++ b/tests/draft7/uniqueItems.json
diff --git a/json/tests/draft7/unknownKeyword.json b/tests/draft7/unknownKeyword.json
index 1f58d97..1f58d97 100644
--- a/json/tests/draft7/unknownKeyword.json
+++ b/tests/draft7/unknownKeyword.json
diff --git a/json/tests/latest b/tests/latest
index 9a4784d..9a4784d 120000
--- a/json/tests/latest
+++ b/tests/latest
diff --git a/tox.ini b/tox.ini
index fcb60d8..ec180a9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,118 +1,9 @@
[tox]
-envlist =
- py{37,38,39,310,311,py3}-{noextra,format,formatnongpl}-{build,tests},
- readme
- safety
- secrets
- style
- typing
- docs-{dirhtml,doctest,linkcheck,spelling,style}
+minversion = 1.6
+envlist = sanity
skipsdist = True
-[testenv]
-changedir = {envtmpdir}
-passenv = CODECOV* CI
-setenv =
- JSON_SCHEMA_TEST_SUITE = {toxinidir}/json
-
- coverage,codecov: MAYBE_COVERAGE = coverage run -m
- coverage,codecov: COVERAGE_RCFILE={toxinidir}/.coveragerc
- coverage,codecov: COVERAGE_DEBUG_FILE={envtmpdir}/coverage-debug
- coverage,codecov: COVERAGE_FILE={envtmpdir}/coverage-data
-whitelist_externals =
- mkdir
-commands =
- noextra: {envpython} -m pip install --disable-pip-version-check {toxinidir}
- format,perf: {envpython} -m pip install --disable-pip-version-check '{toxinidir}[format]'
- formatnongpl: {envpython} -m pip install --disable-pip-version-check '{toxinidir}[format-nongpl]'
-
- # Ignore the deprecation warning until pypa/setuptools#3276 is released
- tests,coverage,codecov: {envpython} -Werror -W"ignore:module 'sre_constants' is deprecated:DeprecationWarning" -m {env:MAYBE_COVERAGE:} twisted.trial {posargs:jsonschema}
- tests: {envpython} -m doctest {toxinidir}/README.rst
-
- coverage: {envpython} -m coverage report --show-missing
- coverage: {envpython} -m coverage html --directory={envtmpdir}/htmlcov
- codecov: {envpython} -m coverage xml -o {envtmpdir}/coverage.xml
- codecov: codecov --required --disable gcov --file {envtmpdir}/coverage.xml
-
- perf: {envpython} {toxinidir}/jsonschema/benchmarks/issue232.py --inherit-environ JSON_SCHEMA_TEST_SUITE {posargs:--output {envtmpdir}/bench-issue232.json}
- perfsuite: {envpython} {toxinidir}/jsonschema/benchmarks/json_schema_test_suite.py --inherit-environ JSON_SCHEMA_TEST_SUITE {posargs:--output {envtmpdir}/bench-json_schema_test_suite.json}
-
- build: {envpython} -m build {toxinidir} --outdir {envtmpdir}/dist
-deps =
- build: build
-
- perf,perfsuite: pyperf
-
- tests,coverage,codecov: twisted
-
- coverage,codecov: coverage
- codecov: codecov
-
-[testenv:bandit]
-deps = bandit
-commands = {envbindir}/bandit --recursive {toxinidir}/jsonschema
-
-[testenv:readme]
-deps =
- build
- docutils
- twine
-commands =
- {envpython} -m build --outdir {envtmpdir}/dist {toxinidir}
- {envpython} -m twine check {envtmpdir}/dist/*
- {envbindir}/rst2html5.py --halt=warning {toxinidir}/CHANGELOG.rst /dev/null
-
-[testenv:safety]
-deps = safety
-commands =
- {envpython} -m pip install --disable-pip-version-check '{toxinidir}[format]'
- {envpython} -m safety check
-
-[testenv:secrets]
-deps = detect-secrets
-commands = {envbindir}/detect-secrets scan {toxinidir}
-
-[testenv:style]
-deps =
- flake8
- flake8-broken-line
- flake8-bugbear
- flake8-commas
- flake8-quotes
- flake8-tidy-imports
-commands =
- {envpython} -m flake8 {posargs} {toxinidir}/jsonschema {toxinidir}/docs
-
-[testenv:typing]
-skip_install = true
-deps =
- mypy
- pyrsistent
- types-attrs
- types-requests
-commands = {envpython} -m mypy --config {toxinidir}/pyproject.toml {posargs} {toxinidir}/jsonschema
-
-[testenv:docs-dirhtml]
-commands = {envpython} -m sphinx -b dirhtml {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W}
-deps =
- -r{toxinidir}/docs/requirements.txt
-
-[testenv:docs-doctest]
-commands = {envpython} -m sphinx -b doctest {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W}
-deps = {[testenv:docs-dirhtml]deps}
-
-[testenv:docs-linkcheck]
-commands = {envpython} -m sphinx -b linkcheck {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W}
-deps = {[testenv:docs-dirhtml]deps}
-
-[testenv:docs-spelling]
-commands = {envpython} -m sphinx -b spelling {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -T -W}
-deps = {[testenv:docs-dirhtml]deps}
-
-[testenv:docs-style]
-commands = doc8 {posargs} {toxinidir}/docs
-deps =
- doc8
- pygments
- pygments-github-lexers
+[testenv:sanity]
+# used just for validating the structure of the test case files themselves
+deps = jsonschema==4.6.1
+commands = {envpython} bin/jsonschema_suite check