From 8c725a1e4ded065dfd23c0d49d790df8e5396e6c Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 2 Aug 2019 14:24:56 -0400 Subject: [PATCH 01/97] perf is pyperf now. --- README.rst | 11 ++++++----- jsonschema/benchmarks/issue232.py | 2 +- jsonschema/benchmarks/json_schema_test_suite.py | 2 +- tox.ini | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index a3004b43..e87b1bd6 100644 --- a/README.rst +++ b/README.rst @@ -137,19 +137,20 @@ favorite test runner. The tests live in the ``jsonschema.tests`` package. Benchmarks ---------- -``jsonschema``'s benchmarks make use of `perf `_. +``jsonschema``'s benchmarks make use of `pyperf +`_. -Running them can be done via ``tox -e perf``, or by invoking the ``perf`` +Running them can be done via ``tox -e perf``, or by invoking the ``pyperf`` commands externally (after ensuring that both it and ``jsonschema`` itself are installed):: - $ python -m perf jsonschema/benchmarks/test_suite.py --hist --output results.json + $ python -m pyperf jsonschema/benchmarks/test_suite.py --hist --output results.json To compare to a previous run, use:: - $ python -m perf compare_to --table reference.json results.json + $ python -m pyperf compare_to --table reference.json results.json -See the ``perf`` documentation for more details. +See the ``pyperf`` documentation for more details. Community diff --git a/jsonschema/benchmarks/issue232.py b/jsonschema/benchmarks/issue232.py index 460bb06c..5d16ee33 100644 --- a/jsonschema/benchmarks/issue232.py +++ b/jsonschema/benchmarks/issue232.py @@ -6,7 +6,7 @@ https://github.com/Julian/jsonschema/pull/232 """ from twisted.python.filepath import FilePath -from perf import Runner +from pyperf import Runner from pyrsistent import m from jsonschema.tests._suite import Collection diff --git a/jsonschema/benchmarks/json_schema_test_suite.py b/jsonschema/benchmarks/json_schema_test_suite.py index c4d3ccd6..5add5051 100644 --- a/jsonschema/benchmarks/json_schema_test_suite.py +++ b/jsonschema/benchmarks/json_schema_test_suite.py @@ -5,7 +5,7 @@ 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 perf import Runner +from pyperf import Runner from jsonschema.tests._suite import Suite diff --git a/tox.ini b/tox.ini index 3e12e2a9..1b7a77d0 100644 --- a/tox.ini +++ b/tox.ini @@ -45,7 +45,7 @@ deps = coverage,codecov: coverage codecov: codecov - perf: perf + perf: pyperf safety: safety [testenv:readme] -- GitLab From 5d0b751cfc0c292ef29e29d992db705e43d6452d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 3 Aug 2019 10:56:17 -0400 Subject: [PATCH 02/97] Fix a test suite bug where id_of wasn't carried along for ref resolution. So now this test passes on all drafts. --- jsonschema/tests/_suite.py | 6 ++++-- jsonschema/tests/test_jsonschema_test_suite.py | 15 --------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/jsonschema/tests/_suite.py b/jsonschema/tests/_suite.py index 8db05195..06ceee6d 100644 --- a/jsonschema/tests/_suite.py +++ b/jsonschema/tests/_suite.py @@ -202,9 +202,11 @@ class _Test(object): reason = skip(self) return unittest.skipIf(reason is not None, reason)(fn) - def validate(self, Validator=None, **kwargs): + def validate(self, Validator, **kwargs): resolver = jsonschema.RefResolver.from_schema( - schema=self.schema, store=self._remotes, + schema=self.schema, + store=self._remotes, + id_of=Validator.ID_OF, ) jsonschema.validate( instance=self.data, diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 065e319c..d31c6b7a 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -125,11 +125,6 @@ TestDraft4 = DRAFT4.to_unittest_testcase( "Location-independent identifier with base URI change in subschema" ), )(test) - or skip( - message=bug(), - subject="refRemote", - case_description="base URI change - change folder", - )(test) or skip( message=bug(), subject="refRemote", @@ -178,11 +173,6 @@ TestDraft6 = DRAFT6.to_unittest_testcase( "Location-independent identifier with base URI change in subschema" ), )(test) - or skip( - message=bug(), - subject="refRemote", - case_description="base URI change - change folder", - )(test) or skip( message=bug(), subject="refRemote", @@ -231,11 +221,6 @@ TestDraft7 = DRAFT7.to_unittest_testcase( "Location-independent identifier with base URI change in subschema" ), )(test) - or skip( - message=bug(), - subject="refRemote", - case_description="base URI change - change folder", - )(test) or skip( message=bug(), subject="refRemote", -- GitLab From 9b1e8f9e2097fd79c0909ba775001ca2027dc593 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 3 Aug 2019 20:32:20 -0400 Subject: [PATCH 03/97] Fix the benchmarks... --- jsonschema/benchmarks/issue232.py | 10 ++++++---- jsonschema/tests/_suite.py | 12 ++++++------ tox.ini | 6 ++++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/jsonschema/benchmarks/issue232.py b/jsonschema/benchmarks/issue232.py index 5d16ee33..1bbb3558 100644 --- a/jsonschema/benchmarks/issue232.py +++ b/jsonschema/benchmarks/issue232.py @@ -9,17 +9,19 @@ from twisted.python.filepath import FilePath from pyperf import Runner from pyrsistent import m -from jsonschema.tests._suite import Collection +from jsonschema.tests._suite import Version import jsonschema -collection = Collection( +issue232 = Version( path=FilePath(__file__).sibling("issue232"), remotes=m(), name="issue232", - validator=jsonschema.Draft7Validator, ) if __name__ == "__main__": - collection.benchmark(runner=Runner()) + issue232.benchmark( + runner=Runner(), + Validator=jsonschema.Draft4Validator, + ) diff --git a/jsonschema/tests/_suite.py b/jsonschema/tests/_suite.py index 06ceee6d..b68a7b66 100644 --- a/jsonschema/tests/_suite.py +++ b/jsonschema/tests/_suite.py @@ -1,8 +1,8 @@ """ Python representations of the JSON Schema Test Suite tests. - """ +from functools import partial import json import os import re @@ -71,12 +71,12 @@ class Version(object): name = attr.ib() - def benchmark(self, runner): # pragma: no cover + def benchmark(self, runner, **kwargs): # pragma: no cover for suite in self.tests(): for test in suite: runner.bench_func( - name=test.fully_qualified_name, - func=test.validate_ignoring_errors, + test.fully_qualified_name, + partial(test.validate_ignoring_errors, **kwargs), ) def tests(self): @@ -216,9 +216,9 @@ class _Test(object): **kwargs ) - def validate_ignoring_errors(self, **kwargs): # pragma: no cover + def validate_ignoring_errors(self, Validator): # pragma: no cover try: - self.validate(**kwargs) + self.validate(Validator=Validator) except jsonschema.ValidationError: pass diff --git a/tox.ini b/tox.ini index 1b7a77d0..77c78809 100644 --- a/tox.ini +++ b/tox.ini @@ -14,6 +14,7 @@ setenv = JSON_SCHEMA_TEST_SUITE = {toxinidir}/json whitelist_externals = python2.7 + mkdir sh virtualenv commands = @@ -22,8 +23,9 @@ commands = tests: {envbindir}/trial {posargs:jsonschema} py{py,27,37}-tests: {envpython} -m doctest {toxinidir}/README.rst - perf: {envpython} {toxinidir}/jsonschema/benchmarks/json_schema_test_suite.py --inherit-environ JSON_SCHEMA_TEST_SUITE - perf: {envpython} {toxinidir}/jsonschema/benchmarks/issue232.py --inherit-environ JSON_SCHEMA_TEST_SUITE + perf: mkdir {envtmpdir}/benchmarks/ + perf: {envpython} {toxinidir}/jsonschema/benchmarks/issue232.py --inherit-environ JSON_SCHEMA_TEST_SUITE --output {envtmpdir}/benchmarks/issue232.json + perf: {envpython} {toxinidir}/jsonschema/benchmarks/json_schema_test_suite.py --inherit-environ JSON_SCHEMA_TEST_SUITE --output {envtmpdir}/benchmarks/json_schema_test_suite.json # Check to make sure that releases build and install properly build: virtualenv --quiet --python=python2.7 {envtmpdir}/venv -- GitLab From 016f4f451e00101287f345a76184f13b1de45a58 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 10:19:52 -0400 Subject: [PATCH 04/97] Squashed 'json/' changes from c09f995c..94a35867 94a35867 Merge remote-tracking branch 'Zac-HD/typos' 0987b613 Typo fixes git-subtree-dir: json git-subtree-split: 94a358671f13d83afd93dd77ba39c790cb9dc83e --- README.md | 4 ++-- tests/draft2019-06/if-then-else.json | 2 +- tests/draft7/if-then-else.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 635f87c2..186a7674 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ This suite is being used by: ### Dart ### -* [json_schema](https://github.com/patefacio/json_schema) +* [json_schema](https://github.com/patefacio/json_schema) ### Elixir ### @@ -92,7 +92,7 @@ This suite is being used by: ### Go ### -* [gojsonschema](https://github.com/sigu-399/gojsonschema) +* [gojsonschema](https://github.com/sigu-399/gojsonschema) * [validate-json](https://github.com/cesanta/validate-json) ### Haskell ### diff --git a/tests/draft2019-06/if-then-else.json b/tests/draft2019-06/if-then-else.json index 37a229c8..be732816 100644 --- a/tests/draft2019-06/if-then-else.json +++ b/tests/draft2019-06/if-then-else.json @@ -174,7 +174,7 @@ }, "tests": [ { - "description": "valid, but woud have been invalid through then", + "description": "valid, but would have been invalid through then", "data": -100, "valid": true }, diff --git a/tests/draft7/if-then-else.json b/tests/draft7/if-then-else.json index 37a229c8..be732816 100644 --- a/tests/draft7/if-then-else.json +++ b/tests/draft7/if-then-else.json @@ -174,7 +174,7 @@ }, "tests": [ { - "description": "valid, but woud have been invalid through then", + "description": "valid, but would have been invalid through then", "data": -100, "valid": true }, -- GitLab From 7bc5f9a1a71cdb3daae7d2f5ea489378eaab104f Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 11:02:56 -0400 Subject: [PATCH 05/97] Squashed 'json/' changes from 94a35867..e2f566f6 e2f566f6 Update the dates for the upcoming spec. c37f912f Update the link to the npm-specific support. git-subtree-dir: json git-subtree-split: e2f566f6728f344dc5ba5e47ea87b0044ffd8574 --- README.md | 11 ++++++----- .../additionalItems.json | 0 .../additionalProperties.json | 0 tests/{draft2019-06 => draft2019-08}/allOf.json | 0 tests/{draft2019-06 => draft2019-08}/anyOf.json | 0 .../boolean_schema.json | 0 tests/{draft2019-06 => draft2019-08}/const.json | 0 tests/{draft2019-06 => draft2019-08}/contains.json | 0 tests/{draft2019-06 => draft2019-08}/default.json | 0 tests/{draft2019-06 => draft2019-08}/defs.json | 0 .../{draft2019-06 => draft2019-08}/dependencies.json | 0 tests/{draft2019-06 => draft2019-08}/enum.json | 0 .../exclusiveMaximum.json | 0 .../exclusiveMinimum.json | 0 .../{draft2019-06 => draft2019-08}/if-then-else.json | 0 tests/{draft2019-06 => draft2019-08}/items.json | 0 tests/{draft2019-06 => draft2019-08}/maxItems.json | 0 tests/{draft2019-06 => draft2019-08}/maxLength.json | 0 .../{draft2019-06 => draft2019-08}/maxProperties.json | 0 tests/{draft2019-06 => draft2019-08}/maximum.json | 0 tests/{draft2019-06 => draft2019-08}/minItems.json | 0 tests/{draft2019-06 => draft2019-08}/minLength.json | 0 .../{draft2019-06 => draft2019-08}/minProperties.json | 0 tests/{draft2019-06 => draft2019-08}/minimum.json | 0 tests/{draft2019-06 => draft2019-08}/multipleOf.json | 0 tests/{draft2019-06 => draft2019-08}/not.json | 0 tests/{draft2019-06 => draft2019-08}/oneOf.json | 0 .../optional/bignum.json | 0 .../optional/content.json | 0 .../optional/ecmascript-regex.json | 0 .../optional/format/date-time.json | 0 .../optional/format/date.json | 0 .../optional/format/email.json | 0 .../optional/format/hostname.json | 0 .../optional/format/idn-email.json | 0 .../optional/format/idn-hostname.json | 0 .../optional/format/ipv4.json | 0 .../optional/format/ipv6.json | 0 .../optional/format/iri-reference.json | 0 .../optional/format/iri.json | 0 .../optional/format/json-pointer.json | 0 .../optional/format/regex.json | 0 .../optional/format/relative-json-pointer.json | 0 .../optional/format/time.json | 0 .../optional/format/uri-reference.json | 0 .../optional/format/uri-template.json | 0 .../optional/format/uri.json | 0 .../optional/zeroTerminatedFloats.json | 0 tests/{draft2019-06 => draft2019-08}/pattern.json | 0 .../patternProperties.json | 0 tests/{draft2019-06 => draft2019-08}/properties.json | 0 .../{draft2019-06 => draft2019-08}/propertyNames.json | 0 tests/{draft2019-06 => draft2019-08}/ref.json | 0 tests/{draft2019-06 => draft2019-08}/refRemote.json | 0 tests/{draft2019-06 => draft2019-08}/required.json | 0 tests/{draft2019-06 => draft2019-08}/type.json | 0 tests/{draft2019-06 => draft2019-08}/uniqueItems.json | 0 57 files changed, 6 insertions(+), 5 deletions(-) rename tests/{draft2019-06 => draft2019-08}/additionalItems.json (100%) rename tests/{draft2019-06 => draft2019-08}/additionalProperties.json (100%) rename tests/{draft2019-06 => draft2019-08}/allOf.json (100%) rename tests/{draft2019-06 => draft2019-08}/anyOf.json (100%) rename tests/{draft2019-06 => draft2019-08}/boolean_schema.json (100%) rename tests/{draft2019-06 => draft2019-08}/const.json (100%) rename tests/{draft2019-06 => draft2019-08}/contains.json (100%) rename tests/{draft2019-06 => draft2019-08}/default.json (100%) rename tests/{draft2019-06 => draft2019-08}/defs.json (100%) rename tests/{draft2019-06 => draft2019-08}/dependencies.json (100%) rename tests/{draft2019-06 => draft2019-08}/enum.json (100%) rename tests/{draft2019-06 => draft2019-08}/exclusiveMaximum.json (100%) rename tests/{draft2019-06 => draft2019-08}/exclusiveMinimum.json (100%) rename tests/{draft2019-06 => draft2019-08}/if-then-else.json (100%) rename tests/{draft2019-06 => draft2019-08}/items.json (100%) rename tests/{draft2019-06 => draft2019-08}/maxItems.json (100%) rename tests/{draft2019-06 => draft2019-08}/maxLength.json (100%) rename tests/{draft2019-06 => draft2019-08}/maxProperties.json (100%) rename tests/{draft2019-06 => draft2019-08}/maximum.json (100%) rename tests/{draft2019-06 => draft2019-08}/minItems.json (100%) rename tests/{draft2019-06 => draft2019-08}/minLength.json (100%) rename tests/{draft2019-06 => draft2019-08}/minProperties.json (100%) rename tests/{draft2019-06 => draft2019-08}/minimum.json (100%) rename tests/{draft2019-06 => draft2019-08}/multipleOf.json (100%) rename tests/{draft2019-06 => draft2019-08}/not.json (100%) rename tests/{draft2019-06 => draft2019-08}/oneOf.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/bignum.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/content.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/ecmascript-regex.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/date-time.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/date.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/email.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/hostname.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/idn-email.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/idn-hostname.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/ipv4.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/ipv6.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/iri-reference.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/iri.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/json-pointer.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/regex.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/relative-json-pointer.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/time.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/uri-reference.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/uri-template.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/format/uri.json (100%) rename tests/{draft2019-06 => draft2019-08}/optional/zeroTerminatedFloats.json (100%) rename tests/{draft2019-06 => draft2019-08}/pattern.json (100%) rename tests/{draft2019-06 => draft2019-08}/patternProperties.json (100%) rename tests/{draft2019-06 => draft2019-08}/properties.json (100%) rename tests/{draft2019-06 => draft2019-08}/propertyNames.json (100%) rename tests/{draft2019-06 => draft2019-08}/ref.json (100%) rename tests/{draft2019-06 => draft2019-08}/refRemote.json (100%) rename tests/{draft2019-06 => draft2019-08}/required.json (100%) rename tests/{draft2019-06 => draft2019-08}/type.json (100%) rename tests/{draft2019-06 => draft2019-08}/uniqueItems.json (100%) diff --git a/README.md b/README.md index 186a7674..1145f433 100644 --- a/README.md +++ b/README.md @@ -127,11 +127,12 @@ This suite is being used by: ### Node.js ### -The JSON Schema Test Suite is also available as an -[npm](https://www.npmjs.com/package/json-schema-test-suite) package. -Node-specific support is maintained on the [node branch](https://github.com/json-schema-org/JSON-Schema-Test-Suite/tree/node). -See [NODE-README.md](https://github.com/json-schema-org/JSON-Schema-Test-Suite/blob/node/NODE-README.md) -for more information. +For node.js developers, the suite is also available as an +[npm](https://www.npmjs.com/package/@json-schema-org/tests) package. + +Node-specific support is maintained in a [separate +repository](https://github.com/json-schema-org/json-schema-test-suite-npm) +which also welcomes your contributions! ### .NET ### diff --git a/tests/draft2019-06/additionalItems.json b/tests/draft2019-08/additionalItems.json similarity index 100% rename from tests/draft2019-06/additionalItems.json rename to tests/draft2019-08/additionalItems.json diff --git a/tests/draft2019-06/additionalProperties.json b/tests/draft2019-08/additionalProperties.json similarity index 100% rename from tests/draft2019-06/additionalProperties.json rename to tests/draft2019-08/additionalProperties.json diff --git a/tests/draft2019-06/allOf.json b/tests/draft2019-08/allOf.json similarity index 100% rename from tests/draft2019-06/allOf.json rename to tests/draft2019-08/allOf.json diff --git a/tests/draft2019-06/anyOf.json b/tests/draft2019-08/anyOf.json similarity index 100% rename from tests/draft2019-06/anyOf.json rename to tests/draft2019-08/anyOf.json diff --git a/tests/draft2019-06/boolean_schema.json b/tests/draft2019-08/boolean_schema.json similarity index 100% rename from tests/draft2019-06/boolean_schema.json rename to tests/draft2019-08/boolean_schema.json diff --git a/tests/draft2019-06/const.json b/tests/draft2019-08/const.json similarity index 100% rename from tests/draft2019-06/const.json rename to tests/draft2019-08/const.json diff --git a/tests/draft2019-06/contains.json b/tests/draft2019-08/contains.json similarity index 100% rename from tests/draft2019-06/contains.json rename to tests/draft2019-08/contains.json diff --git a/tests/draft2019-06/default.json b/tests/draft2019-08/default.json similarity index 100% rename from tests/draft2019-06/default.json rename to tests/draft2019-08/default.json diff --git a/tests/draft2019-06/defs.json b/tests/draft2019-08/defs.json similarity index 100% rename from tests/draft2019-06/defs.json rename to tests/draft2019-08/defs.json diff --git a/tests/draft2019-06/dependencies.json b/tests/draft2019-08/dependencies.json similarity index 100% rename from tests/draft2019-06/dependencies.json rename to tests/draft2019-08/dependencies.json diff --git a/tests/draft2019-06/enum.json b/tests/draft2019-08/enum.json similarity index 100% rename from tests/draft2019-06/enum.json rename to tests/draft2019-08/enum.json diff --git a/tests/draft2019-06/exclusiveMaximum.json b/tests/draft2019-08/exclusiveMaximum.json similarity index 100% rename from tests/draft2019-06/exclusiveMaximum.json rename to tests/draft2019-08/exclusiveMaximum.json diff --git a/tests/draft2019-06/exclusiveMinimum.json b/tests/draft2019-08/exclusiveMinimum.json similarity index 100% rename from tests/draft2019-06/exclusiveMinimum.json rename to tests/draft2019-08/exclusiveMinimum.json diff --git a/tests/draft2019-06/if-then-else.json b/tests/draft2019-08/if-then-else.json similarity index 100% rename from tests/draft2019-06/if-then-else.json rename to tests/draft2019-08/if-then-else.json diff --git a/tests/draft2019-06/items.json b/tests/draft2019-08/items.json similarity index 100% rename from tests/draft2019-06/items.json rename to tests/draft2019-08/items.json diff --git a/tests/draft2019-06/maxItems.json b/tests/draft2019-08/maxItems.json similarity index 100% rename from tests/draft2019-06/maxItems.json rename to tests/draft2019-08/maxItems.json diff --git a/tests/draft2019-06/maxLength.json b/tests/draft2019-08/maxLength.json similarity index 100% rename from tests/draft2019-06/maxLength.json rename to tests/draft2019-08/maxLength.json diff --git a/tests/draft2019-06/maxProperties.json b/tests/draft2019-08/maxProperties.json similarity index 100% rename from tests/draft2019-06/maxProperties.json rename to tests/draft2019-08/maxProperties.json diff --git a/tests/draft2019-06/maximum.json b/tests/draft2019-08/maximum.json similarity index 100% rename from tests/draft2019-06/maximum.json rename to tests/draft2019-08/maximum.json diff --git a/tests/draft2019-06/minItems.json b/tests/draft2019-08/minItems.json similarity index 100% rename from tests/draft2019-06/minItems.json rename to tests/draft2019-08/minItems.json diff --git a/tests/draft2019-06/minLength.json b/tests/draft2019-08/minLength.json similarity index 100% rename from tests/draft2019-06/minLength.json rename to tests/draft2019-08/minLength.json diff --git a/tests/draft2019-06/minProperties.json b/tests/draft2019-08/minProperties.json similarity index 100% rename from tests/draft2019-06/minProperties.json rename to tests/draft2019-08/minProperties.json diff --git a/tests/draft2019-06/minimum.json b/tests/draft2019-08/minimum.json similarity index 100% rename from tests/draft2019-06/minimum.json rename to tests/draft2019-08/minimum.json diff --git a/tests/draft2019-06/multipleOf.json b/tests/draft2019-08/multipleOf.json similarity index 100% rename from tests/draft2019-06/multipleOf.json rename to tests/draft2019-08/multipleOf.json diff --git a/tests/draft2019-06/not.json b/tests/draft2019-08/not.json similarity index 100% rename from tests/draft2019-06/not.json rename to tests/draft2019-08/not.json diff --git a/tests/draft2019-06/oneOf.json b/tests/draft2019-08/oneOf.json similarity index 100% rename from tests/draft2019-06/oneOf.json rename to tests/draft2019-08/oneOf.json diff --git a/tests/draft2019-06/optional/bignum.json b/tests/draft2019-08/optional/bignum.json similarity index 100% rename from tests/draft2019-06/optional/bignum.json rename to tests/draft2019-08/optional/bignum.json diff --git a/tests/draft2019-06/optional/content.json b/tests/draft2019-08/optional/content.json similarity index 100% rename from tests/draft2019-06/optional/content.json rename to tests/draft2019-08/optional/content.json diff --git a/tests/draft2019-06/optional/ecmascript-regex.json b/tests/draft2019-08/optional/ecmascript-regex.json similarity index 100% rename from tests/draft2019-06/optional/ecmascript-regex.json rename to tests/draft2019-08/optional/ecmascript-regex.json diff --git a/tests/draft2019-06/optional/format/date-time.json b/tests/draft2019-08/optional/format/date-time.json similarity index 100% rename from tests/draft2019-06/optional/format/date-time.json rename to tests/draft2019-08/optional/format/date-time.json diff --git a/tests/draft2019-06/optional/format/date.json b/tests/draft2019-08/optional/format/date.json similarity index 100% rename from tests/draft2019-06/optional/format/date.json rename to tests/draft2019-08/optional/format/date.json diff --git a/tests/draft2019-06/optional/format/email.json b/tests/draft2019-08/optional/format/email.json similarity index 100% rename from tests/draft2019-06/optional/format/email.json rename to tests/draft2019-08/optional/format/email.json diff --git a/tests/draft2019-06/optional/format/hostname.json b/tests/draft2019-08/optional/format/hostname.json similarity index 100% rename from tests/draft2019-06/optional/format/hostname.json rename to tests/draft2019-08/optional/format/hostname.json diff --git a/tests/draft2019-06/optional/format/idn-email.json b/tests/draft2019-08/optional/format/idn-email.json similarity index 100% rename from tests/draft2019-06/optional/format/idn-email.json rename to tests/draft2019-08/optional/format/idn-email.json diff --git a/tests/draft2019-06/optional/format/idn-hostname.json b/tests/draft2019-08/optional/format/idn-hostname.json similarity index 100% rename from tests/draft2019-06/optional/format/idn-hostname.json rename to tests/draft2019-08/optional/format/idn-hostname.json diff --git a/tests/draft2019-06/optional/format/ipv4.json b/tests/draft2019-08/optional/format/ipv4.json similarity index 100% rename from tests/draft2019-06/optional/format/ipv4.json rename to tests/draft2019-08/optional/format/ipv4.json diff --git a/tests/draft2019-06/optional/format/ipv6.json b/tests/draft2019-08/optional/format/ipv6.json similarity index 100% rename from tests/draft2019-06/optional/format/ipv6.json rename to tests/draft2019-08/optional/format/ipv6.json diff --git a/tests/draft2019-06/optional/format/iri-reference.json b/tests/draft2019-08/optional/format/iri-reference.json similarity index 100% rename from tests/draft2019-06/optional/format/iri-reference.json rename to tests/draft2019-08/optional/format/iri-reference.json diff --git a/tests/draft2019-06/optional/format/iri.json b/tests/draft2019-08/optional/format/iri.json similarity index 100% rename from tests/draft2019-06/optional/format/iri.json rename to tests/draft2019-08/optional/format/iri.json diff --git a/tests/draft2019-06/optional/format/json-pointer.json b/tests/draft2019-08/optional/format/json-pointer.json similarity index 100% rename from tests/draft2019-06/optional/format/json-pointer.json rename to tests/draft2019-08/optional/format/json-pointer.json diff --git a/tests/draft2019-06/optional/format/regex.json b/tests/draft2019-08/optional/format/regex.json similarity index 100% rename from tests/draft2019-06/optional/format/regex.json rename to tests/draft2019-08/optional/format/regex.json diff --git a/tests/draft2019-06/optional/format/relative-json-pointer.json b/tests/draft2019-08/optional/format/relative-json-pointer.json similarity index 100% rename from tests/draft2019-06/optional/format/relative-json-pointer.json rename to tests/draft2019-08/optional/format/relative-json-pointer.json diff --git a/tests/draft2019-06/optional/format/time.json b/tests/draft2019-08/optional/format/time.json similarity index 100% rename from tests/draft2019-06/optional/format/time.json rename to tests/draft2019-08/optional/format/time.json diff --git a/tests/draft2019-06/optional/format/uri-reference.json b/tests/draft2019-08/optional/format/uri-reference.json similarity index 100% rename from tests/draft2019-06/optional/format/uri-reference.json rename to tests/draft2019-08/optional/format/uri-reference.json diff --git a/tests/draft2019-06/optional/format/uri-template.json b/tests/draft2019-08/optional/format/uri-template.json similarity index 100% rename from tests/draft2019-06/optional/format/uri-template.json rename to tests/draft2019-08/optional/format/uri-template.json diff --git a/tests/draft2019-06/optional/format/uri.json b/tests/draft2019-08/optional/format/uri.json similarity index 100% rename from tests/draft2019-06/optional/format/uri.json rename to tests/draft2019-08/optional/format/uri.json diff --git a/tests/draft2019-06/optional/zeroTerminatedFloats.json b/tests/draft2019-08/optional/zeroTerminatedFloats.json similarity index 100% rename from tests/draft2019-06/optional/zeroTerminatedFloats.json rename to tests/draft2019-08/optional/zeroTerminatedFloats.json diff --git a/tests/draft2019-06/pattern.json b/tests/draft2019-08/pattern.json similarity index 100% rename from tests/draft2019-06/pattern.json rename to tests/draft2019-08/pattern.json diff --git a/tests/draft2019-06/patternProperties.json b/tests/draft2019-08/patternProperties.json similarity index 100% rename from tests/draft2019-06/patternProperties.json rename to tests/draft2019-08/patternProperties.json diff --git a/tests/draft2019-06/properties.json b/tests/draft2019-08/properties.json similarity index 100% rename from tests/draft2019-06/properties.json rename to tests/draft2019-08/properties.json diff --git a/tests/draft2019-06/propertyNames.json b/tests/draft2019-08/propertyNames.json similarity index 100% rename from tests/draft2019-06/propertyNames.json rename to tests/draft2019-08/propertyNames.json diff --git a/tests/draft2019-06/ref.json b/tests/draft2019-08/ref.json similarity index 100% rename from tests/draft2019-06/ref.json rename to tests/draft2019-08/ref.json diff --git a/tests/draft2019-06/refRemote.json b/tests/draft2019-08/refRemote.json similarity index 100% rename from tests/draft2019-06/refRemote.json rename to tests/draft2019-08/refRemote.json diff --git a/tests/draft2019-06/required.json b/tests/draft2019-08/required.json similarity index 100% rename from tests/draft2019-06/required.json rename to tests/draft2019-08/required.json diff --git a/tests/draft2019-06/type.json b/tests/draft2019-08/type.json similarity index 100% rename from tests/draft2019-06/type.json rename to tests/draft2019-08/type.json diff --git a/tests/draft2019-06/uniqueItems.json b/tests/draft2019-08/uniqueItems.json similarity index 100% rename from tests/draft2019-06/uniqueItems.json rename to tests/draft2019-08/uniqueItems.json -- GitLab From 9e25a56f26989e193d6cb69de8762b10c210bd2d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 11:49:46 -0400 Subject: [PATCH 06/97] Mark the boolean schema bug with the issue number --- jsonschema/tests/__init__.py | 5 +++++ jsonschema/tests/test_jsonschema_test_suite.py | 8 +------- jsonschema/tests/test_validators.py | 5 +++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/jsonschema/tests/__init__.py b/jsonschema/tests/__init__.py index e69de29b..70f291fe 100644 --- a/jsonschema/tests/__init__.py +++ b/jsonschema/tests/__init__.py @@ -0,0 +1,5 @@ +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/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index d31c6b7a..8852856a 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -19,6 +19,7 @@ from jsonschema import ( draft6_format_checker, draft7_format_checker, ) +from jsonschema.tests import bug from jsonschema.tests._suite import Suite from jsonschema.validators import _DEPRECATED_DEFAULT_TYPES, create @@ -65,13 +66,6 @@ else: return -def bug(issue=None): - message = "A known bug." - if issue is not None: - message += " See issue #{issue}.".format(issue=issue) - return message - - TestDraft3 = DRAFT3.to_unittest_testcase( DRAFT3.tests(), DRAFT3.optional_tests_of(name="format"), diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 0adbf306..1e2f20bd 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -14,6 +14,7 @@ import attr from jsonschema import FormatChecker, TypeChecker, exceptions, validators from jsonschema.compat import PY3, pathname2url +from jsonschema.tests import bug import jsonschema @@ -1283,14 +1284,14 @@ class AntiDraft6LeakMixin(object): self.Validator.check_schema(False) self.assertIn("False is not of type", str(e.exception)) - @unittest.skip("This test fails, but it shouldn't.") + @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("This test fails, but it shouldn't.") + @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: -- GitLab From 133ebad2efe901b1a052f99c79d3140f500ab2d8 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 11:58:31 -0400 Subject: [PATCH 07/97] Yeah, fine... --- jsonschema/tests/__init__.py | 5 ----- jsonschema/tests/helpers.py | 5 +++++ jsonschema/tests/test_jsonschema_test_suite.py | 2 +- jsonschema/tests/test_validators.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 jsonschema/tests/helpers.py diff --git a/jsonschema/tests/__init__.py b/jsonschema/tests/__init__.py index 70f291fe..e69de29b 100644 --- a/jsonschema/tests/__init__.py +++ b/jsonschema/tests/__init__.py @@ -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/helpers.py b/jsonschema/tests/helpers.py new file mode 100644 index 00000000..70f291fe --- /dev/null +++ b/jsonschema/tests/helpers.py @@ -0,0 +1,5 @@ +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/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 8852856a..b16d5bcf 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -19,8 +19,8 @@ from jsonschema import ( draft6_format_checker, draft7_format_checker, ) -from jsonschema.tests import bug from jsonschema.tests._suite import Suite +from jsonschema.tests.helpers import bug from jsonschema.validators import _DEPRECATED_DEFAULT_TYPES, create diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 1e2f20bd..e4572c5c 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -14,7 +14,7 @@ import attr from jsonschema import FormatChecker, TypeChecker, exceptions, validators from jsonschema.compat import PY3, pathname2url -from jsonschema.tests import bug +from jsonschema.tests.helpers import bug import jsonschema -- GitLab From 624d848c06b6cd2d293d47aef5f29eb99fd39101 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 11:59:12 -0400 Subject: [PATCH 08/97] Add a detect-secrets tox env. --- tox.ini | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tox.ini b/tox.ini index 77c78809..29dffe9f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,12 @@ [tox] -skipsdist = True envlist = - py{35,36,37,py,py3}-{build,tests}, - docs-{html,doctest,linkcheck,spelling,style}, - readme, - safety, - style, + py{35,36,37,py,py3}-{build,tests} + readme + safety + secrets + style + docs-{html,doctest,linkcheck,spelling,style} +skipsdist = True [testenv] changedir = @@ -62,6 +63,10 @@ commands = {envbindir}/pip install '{toxinidir}[format]' {envbindir}/safety check +[testenv:secrets] +deps = detect-secrets +commands = {envbindir}/detect-secrets scan {toxinidir} + [testenv:style] deps = ebb-lint>=0.19.1.0 @@ -141,4 +146,4 @@ ignore-path = [travis] python = - pypy: pypy, docs, readme, safety, style + pypy: pypy, docs, readme, safety, secrets, style -- GitLab From 02bf1860cfde6f83e4e06dc8f6bac851971ea720 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 13:41:14 -0400 Subject: [PATCH 09/97] Bump to Sphinx2 for docs, fixing random nonsense along the way. --- docs/errors.rst | 2 +- docs/requirements.txt | 33 +++++++++++++++++++++++++++++---- jsonschema/_types.py | 2 +- jsonschema/validators.py | 10 ++++++---- tox.ini | 10 +++++----- 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/docs/errors.rst b/docs/errors.rst index 708425fc..1851ff5d 100644 --- a/docs/errors.rst +++ b/docs/errors.rst @@ -375,7 +375,7 @@ to guess the most relevant error in a given bunch. provide a mixture of errors from different validation attempts (i.e. from different instances or schemas), since it won't produce sensical output. - :argument callable key: the key to use when sorting errors. See + :argument collections.Callable key: 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 diff --git a/docs/requirements.txt b/docs/requirements.txt index eb3007ae..357bdc93 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,29 @@ -certifi -lxml -sphinx==1.6.7 -sphinxcontrib-spelling +alabaster==0.7.12 +attrs==19.1.0 +Babel==2.7.0 +certifi==2019.6.16 +chardet==3.0.4 +docutils==0.15.2 +greenlet==0.4.13 +idna==2.8 +imagesize==1.1.0 +Jinja2==2.10.1 +lxml==4.4.0 +MarkupSafe==1.1.1 +packaging==19.1 +pyenchant==2.0.0 +Pygments==2.4.2 +pyparsing==2.4.2 +pytz==2019.2 +requests==2.22.0 +six==1.12.0 +snowballstemmer==1.9.0 +Sphinx==2.1.2 +sphinxcontrib-applehelp==1.0.1 +sphinxcontrib-devhelp==1.0.1 +sphinxcontrib-htmlhelp==1.0.2 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.2 +sphinxcontrib-serializinghtml==1.1.3 +sphinxcontrib-spelling==4.3.0 +urllib3==1.25.3 diff --git a/jsonschema/_types.py b/jsonschema/_types.py index f556dedb..a71a4e34 100644 --- a/jsonschema/_types.py +++ b/jsonschema/_types.py @@ -104,7 +104,7 @@ class TypeChecker(object): The name of the type to check. - fn (callable): + fn (collections.Callable): A function taking exactly two parameters - the type checker calling the function and the instance to check. diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 7b7d76df..e1ea871e 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -114,7 +114,9 @@ def validates(version): Returns: - callable: a class decorator to decorate the validator with the version + collections.Callable: + + a class decorator to decorate the validator with the version """ def _validates(cls): @@ -206,7 +208,7 @@ def create( will be converted to functions and redefined in this object's `jsonschema.TypeChecker`. - id_of (callable): + id_of (collections.Callable): A function that given a schema, returns its ID. @@ -611,12 +613,12 @@ class RefResolver(object): A mapping from URI schemes to functions that should be used to retrieve them - urljoin_cache (functools.lru_cache): + 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 (functools.lru_cache): + remote_cache (:func:`functools.lru_cache`): A cache that will be used for caching the results of resolved remote URLs. diff --git a/tox.ini b/tox.ini index 29dffe9f..93ea5ae7 100644 --- a/tox.ini +++ b/tox.ini @@ -94,7 +94,7 @@ commands = codecov --required --disable gcov --file {envtmpdir}/coverage.xml [testenv:docs-html] -basepython = pypy +basepython = pypy3 changedir = docs whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' html @@ -103,7 +103,7 @@ deps = -e{toxinidir} [testenv:docs-doctest] -basepython = pypy +basepython = pypy3 changedir = docs whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' doctest @@ -112,7 +112,7 @@ deps = -e{toxinidir} [testenv:docs-linkcheck] -basepython = pypy +basepython = pypy3 changedir = docs whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' linkcheck @@ -121,7 +121,7 @@ deps = -e{toxinidir} [testenv:docs-spelling] -basepython = pypy +basepython = pypy3 changedir = docs whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' spelling @@ -130,7 +130,7 @@ deps = -e{toxinidir} [testenv:docs-style] -basepython = pypy +basepython = pypy3 changedir = docs commands = doc8 {posargs} {toxinidir}/docs deps = -- GitLab From 245c6e2d6c1892f4fb2344e14a22a272e2e02067 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 13:48:32 -0400 Subject: [PATCH 10/97] Sigh, fix CI dumpster fire again. --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 93ea5ae7..c3f629cb 100644 --- a/tox.ini +++ b/tox.ini @@ -146,4 +146,5 @@ ignore-path = [travis] python = - pypy: pypy, docs, readme, safety, secrets, style + pypy: pypy, readme, safety, secrets, style + pypy3: pypy3, docs -- GitLab From 687efff07669e6e6bc30e15b4dfc605ab5b09d96 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 13:55:51 -0400 Subject: [PATCH 11/97] Someone save me. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index c3f629cb..359bca1b 100644 --- a/tox.ini +++ b/tox.ini @@ -146,5 +146,5 @@ ignore-path = [travis] python = - pypy: pypy, readme, safety, secrets, style + pypy: pypy, readme, safety, secrets, style, !docs-style pypy3: pypy3, docs -- GitLab From 35d5cb5dbb8ad12c4a0cf9cab8b2ddd8dd470222 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 14:03:13 -0400 Subject: [PATCH 12/97] Like, I have no words. --- tox.ini | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tox.ini b/tox.ini index 359bca1b..53522465 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ envlist = safety secrets style - docs-{html,doctest,linkcheck,spelling,style} + docs-{html,doc8,doctest,linkcheck,spelling} skipsdist = True [testenv] @@ -102,6 +102,15 @@ deps = -r{toxinidir}/docs/requirements.txt -e{toxinidir} +[testenv:docs-doc8] +basepython = pypy3 +changedir = docs +commands = doc8 {posargs} {toxinidir}/docs +deps = + doc8 + pygments + pygments-github-lexers + [testenv:docs-doctest] basepython = pypy3 changedir = docs @@ -129,15 +138,6 @@ deps = -r{toxinidir}/docs/requirements.txt -e{toxinidir} -[testenv:docs-style] -basepython = pypy3 -changedir = docs -commands = doc8 {posargs} {toxinidir}/docs -deps = - doc8 - pygments - pygments-github-lexers - [doc8] ignore-path = version.txt, @@ -146,5 +146,5 @@ ignore-path = [travis] python = - pypy: pypy, readme, safety, secrets, style, !docs-style + pypy: pypy, readme, safety, secrets, style pypy3: pypy3, docs -- GitLab From 918dad5989736e2d40cffe85556bc87935dbfb35 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 15:53:02 -0400 Subject: [PATCH 13/97] Minor style. --- tox.ini | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tox.ini b/tox.ini index 53522465..65a8226f 100644 --- a/tox.ini +++ b/tox.ini @@ -49,17 +49,16 @@ deps = codecov: codecov perf: pyperf - safety: safety [testenv:readme] changedir = {toxinidir} deps = readme_renderer -commands = +commands = {envbindir}/python setup.py check --restructuredtext --strict [testenv:safety] deps = safety -commands = +commands = {envbindir}/pip install '{toxinidir}[format]' {envbindir}/safety check @@ -71,7 +70,8 @@ commands = {envbindir}/detect-secrets scan {toxinidir} deps = ebb-lint>=0.19.1.0 git+https://github.com/pyga/awpa@py37 -commands = {envbindir}/flake8 {posargs} {toxinidir}/jsonschema {toxinidir}/docs {toxinidir}/setup.py +commands = + {envbindir}/flake8 {posargs} {toxinidir}/jsonschema {toxinidir}/docs {toxinidir}/setup.py [testenv:coverage] setenv = @@ -84,15 +84,6 @@ commands = {envbindir}/coverage report --rcfile={toxinidir}/.coveragerc --show-missing {envbindir}/coverage html --directory={envtmpdir}/htmlcov --rcfile={toxinidir}/.coveragerc {posargs} -[testenv:codecov] -passenv = CODECOV* CI TRAVIS TRAVIS_* -setenv = {[testenv:coverage]setenv} -commands = - {envbindir}/python -m pip install '{toxinidir}[format]' - {envbindir}/coverage run --rcfile={toxinidir}/.coveragerc {envbindir}/trial jsonschema - {envbindir}/coverage xml -o {envtmpdir}/coverage.xml - codecov --required --disable gcov --file {envtmpdir}/coverage.xml - [testenv:docs-html] basepython = pypy3 changedir = docs @@ -144,6 +135,15 @@ ignore-path = .*/, _*/ +[testenv:codecov] +passenv = CODECOV* CI TRAVIS TRAVIS_* +setenv = {[testenv:coverage]setenv} +commands = + {envbindir}/python -m pip install '{toxinidir}[format]' + {envbindir}/coverage run --rcfile={toxinidir}/.coveragerc {envbindir}/trial jsonschema + {envbindir}/coverage xml -o {envtmpdir}/coverage.xml + codecov --required --disable gcov --file {envtmpdir}/coverage.xml + [travis] python = pypy: pypy, readme, safety, secrets, style -- GitLab From 10bf4435c901842e116db5dd12d78e71459a1dcb Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 19:16:24 -0400 Subject: [PATCH 14/97] Enable then skip the tests from #593. --- .../tests/test_jsonschema_test_suite.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index b16d5bcf..11290a31 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -186,6 +186,7 @@ TestDraft7 = DRAFT7.to_unittest_testcase( DRAFT7.format_tests(), DRAFT7.optional_tests_of(name="bignum"), DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), + DRAFT7.optional_tests_of(name="content"), Validator=Draft7Validator, format_checker=draft7_format_checker, skip=lambda test: ( @@ -225,6 +226,25 @@ TestDraft7 = DRAFT7.to_unittest_testcase( subject="date-time", description="case-insensitive T and Z", )(test) + or skip( + message=bug(593), + subject="content", + case_description=( + "validation of string-encoded content based on media type" + ), + )(test) + or skip( + message=bug(593), + subject="content", + case_description="validation of binary string-encoding", + )(test) + or skip( + message=bug(593), + subject="content", + case_description=( + "validation of binary-encoded media type documents" + ), + )(test) ), ) -- GitLab From 055c7f6e70d2a463a8fc9a9bc50e4cb98900a5de Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 4 Aug 2019 19:22:29 -0400 Subject: [PATCH 15/97] wheel -> bdist_wheel, since the former is apparently deprecated. --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 7d56e5fe..1a448466 100644 --- a/setup.cfg +++ b/setup.cfg @@ -52,5 +52,5 @@ exclude = jsonschema/__init__.py jsonschema/_reflect.py -[wheel] +[bdist_wheel] universal = 1 -- GitLab From 3a0ee68ba7bf6a71e1f00f17ed9ca39e147d3100 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 16 Aug 2019 12:25:23 +0200 Subject: [PATCH 16/97] Add the output. --- DEMO.ipynb | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/DEMO.ipynb b/DEMO.ipynb index cb66de12..f008b793 100644 --- a/DEMO.ipynb +++ b/DEMO.ipynb @@ -54,17 +54,31 @@ "outputs": [], "source": [ "# If no exception is raised by validate(), the instance is valid.\n", - "validate({\"name\" : \"Eggs\", \"price\" : 34.99}, schema)" + "validate(instance={\"name\" : \"Eggs\", \"price\" : 34.99}, schema=schema)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ValidationError", + "evalue": "'Invalid' is not of type 'number'\n\nFailed validating 'type' in schema['properties']['price']:\n {'type': 'number'}\n\nOn instance['price']:\n 'Invalid'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m validate(\n\u001b[1;32m 2\u001b[0m \u001b[0minstance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"name\"\u001b[0m \u001b[0;34m:\u001b[0m \u001b[0;34m\"Eggs\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"price\"\u001b[0m \u001b[0;34m:\u001b[0m \u001b[0;34m\"Invalid\"\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mschema\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mschema\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m )\n", + "\u001b[0;32m~/Development/jsonschema/jsonschema/validators.py\u001b[0m in \u001b[0;36mvalidate\u001b[0;34m(instance, schema, cls, *args, **kwargs)\u001b[0m\n\u001b[1;32m 899\u001b[0m \u001b[0merror\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_match\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalidator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miter_errors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minstance\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0merror\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 901\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merror\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 902\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValidationError\u001b[0m: 'Invalid' is not of type 'number'\n\nFailed validating 'type' in schema['properties']['price']:\n {'type': 'number'}\n\nOn instance['price']:\n 'Invalid'" + ] + } + ], "source": [ "validate(\n", - " {\"name\" : \"Eggs\", \"price\" : \"Invalid\"}, schema\n", + " instance={\"name\" : \"Eggs\", \"price\" : \"Invalid\"},\n", + " schema=schema,\n", ")" ] }, @@ -145,9 +159,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.7.4" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } -- GitLab From 3d5fada3f5e53d7170ead9b085a73d31738c4f9c Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 16 Aug 2019 13:00:18 +0200 Subject: [PATCH 17/97] Maybe this constitutes a test for the demo notebook. --- tox.ini | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 65a8226f..8300a67f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,7 @@ [tox] envlist = py{35,36,37,py,py3}-{build,tests} + demo readme safety secrets @@ -50,6 +51,11 @@ deps = perf: pyperf +[testenv:demo] +deps = jupyter +commands = + {envbindir}/jupyter nbconvert --output-dir {envtmpdir} {toxinidir}/DEMO.ipynb + [testenv:readme] changedir = {toxinidir} deps = readme_renderer @@ -147,4 +153,4 @@ commands = [travis] python = pypy: pypy, readme, safety, secrets, style - pypy3: pypy3, docs + pypy3: pypy3, demo, docs -- GitLab From 21f608813567e7cd7d59330e8caf2278f36e40ba Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 16 Aug 2019 17:26:13 +0200 Subject: [PATCH 18/97] Hopefully unnecessarily remind that tests are not public API. --- docs/faq.rst | 74 +++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index 889b3065..768bd15b 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -9,19 +9,21 @@ 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 `, so you can -easily create an `jsonschema.IValidator` 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.) +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 +`, so you can easily create an `jsonschema.IValidator` 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.) .. code-block:: python @@ -59,8 +61,8 @@ themselves will need to be valid under the schema.) See the above-linked document for more info on how this works, but -basically, it just extends the :validator:`properties` validator on a -`jsonschema.Draft7Validator` to then go ahead and update all the +basically, it just extends the :validator:`properties` validator on +a `jsonschema.Draft7Validator` to then go ahead and update all the defaults. .. note:: @@ -100,8 +102,9 @@ defaults. DefaultValidatingDraft7Validator(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. + ...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. .. code-block:: python @@ -114,37 +117,42 @@ defaults. How do jsonschema version numbers work? --------------------------------------- -``jsonschema`` tries to follow the `Semantic Versioning `_ -specification. +``jsonschema`` tries to follow the `Semantic Versioning +`_ specification. -This means broadly that no backwards-incompatible changes should be made in -minor releases (and certainly not in dot releases). +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 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: +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) + * 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 following are *not* considered public API and may change without +notice: * the exact wording and contents of error messages; typical reasons to do this seem to involve unit tests. API users are encouraged to use the extensive introspection provided in - `jsonschema.exceptions.ValidationError`\s instead to make - meaningful assertions about what failed. + `jsonschema.exceptions.ValidationError`\s instead to make meaningful + assertions about what failed. * the order in which validation errors are returned or raised + * the contents of the ``jsonschema.tests`` package + * the ``compat.py`` module, which is for internal compatibility use * 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. +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. -- GitLab From 2f7c59392ed41f857f3a1c4583dce9a0ca455952 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 16 Aug 2019 17:26:55 +0200 Subject: [PATCH 19/97] But rename helpers anyways for anyone who doesn't check the docs. --- jsonschema/tests/{helpers.py => _helpers.py} | 0 jsonschema/tests/test_jsonschema_test_suite.py | 2 +- jsonschema/tests/test_validators.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename jsonschema/tests/{helpers.py => _helpers.py} (100%) diff --git a/jsonschema/tests/helpers.py b/jsonschema/tests/_helpers.py similarity index 100% rename from jsonschema/tests/helpers.py rename to jsonschema/tests/_helpers.py diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 11290a31..45d7c96e 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -19,8 +19,8 @@ from jsonschema import ( draft6_format_checker, draft7_format_checker, ) +from jsonschema.tests._helpers import bug from jsonschema.tests._suite import Suite -from jsonschema.tests.helpers import bug from jsonschema.validators import _DEPRECATED_DEFAULT_TYPES, create diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index e4572c5c..5a6fac34 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -14,7 +14,7 @@ import attr from jsonschema import FormatChecker, TypeChecker, exceptions, validators from jsonschema.compat import PY3, pathname2url -from jsonschema.tests.helpers import bug +from jsonschema.tests._helpers import bug import jsonschema -- GitLab From 47a2ac312c8da76b2ef51ad9aa0ff3d92e217c59 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 16 Aug 2019 18:48:28 +0200 Subject: [PATCH 20/97] Minor style. --- jsonschema/validators.py | 72 ++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/jsonschema/validators.py b/jsonschema/validators.py index e1ea871e..089dbbbd 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -38,9 +38,9 @@ class _DontDoThat(Exception): """ Raised when a Validators with non-default type checker is misused. - Asking one for DEFAULT_TYPES doesn't make sense, since type checkers exist - for the unrepresentable cases where DEFAULT_TYPES can't represent the type - relationship. + Asking one for DEFAULT_TYPES doesn't make sense, since type checkers + exist for the unrepresentable cases where DEFAULT_TYPES can't + represent the type relationship. """ def __str__(self): @@ -186,17 +186,17 @@ def create( 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. + 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. + If unprovided, a `jsonschema.TypeChecker` will be created + with a set of default types typical of JSON Schema drafts. default_types (collections.Mapping): @@ -204,9 +204,9 @@ def create( Please use the type_checker argument instead. - If set, it provides mappings of JSON types to Python types that - will be converted to functions and redefined in this object's - `jsonschema.TypeChecker`. + If set, it provides mappings of JSON types to Python types + that will be converted to functions and redefined in this + object's `jsonschema.TypeChecker`. id_of (collections.Callable): @@ -383,14 +383,14 @@ def extend(validator, validators=(), version=None, type_checker=None): .. 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. + 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 + validator callable, delegate and call it directly in + the new validator function by retrieving it using ``OldValidator.VALIDATORS["validator_name"]``. version (str): @@ -844,9 +844,9 @@ def validate(instance, schema, cls=None, *args, **kwargs): ... 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. + :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 @@ -868,16 +868,16 @@ def validate(instance, schema, cls=None, *args, **kwargs): 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. + 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``. + Any other provided positional and keyword arguments will be passed + on when instantiating the ``cls``. Raises: @@ -905,8 +905,8 @@ 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. + Uses the :validator:`$schema` property that should be present in the + given schema to look up the appropriate validator class. Arguments: @@ -916,11 +916,11 @@ def validator_for(schema, default=_LATEST_VERSION): default: - the default to return if the appropriate validator class cannot be - determined. + the default to return if the appropriate validator class + cannot be determined. - If unprovided, the default is to return - the latest supported draft. + If unprovided, the default is to return the latest supported + draft. """ if schema is True or schema is False or u"$schema" not in schema: return default -- GitLab From 190c3f73b57439a55eae9d762ed27ab7f42c798f Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 23 Aug 2019 11:05:24 +0200 Subject: [PATCH 21/97] Make it so we don't need to install editable for any toxenvs. Now we're close to sane again, just have to fix changing directory also for build, but I've already cursed enough at setuptools for one morning. Sigh. And yeah probably at some point this will switch to using pep517.build, or maybe poetry, that's what the kids all use these days eh. --- tox.ini | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tox.ini b/tox.ini index 8300a67f..b2f235d4 100644 --- a/tox.ini +++ b/tox.ini @@ -17,6 +17,7 @@ setenv = whitelist_externals = python2.7 mkdir + rm sh virtualenv commands = @@ -39,6 +40,12 @@ commands = build: python2.7 {toxinidir}/setup.py --quiet sdist --dist-dir={envtmpdir}/sdist --format=gztar,zip build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.tar.gz' build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.zip' + + # FIXME: This has side effects! But it's not my fault... I can't + # figure out yet how to get setuptools to not create this directory + # here yet. But whatever, probably this will change to pep517.build + # soon anways. + build: rm -rf {toxinidir}/jsonschema.egg-info deps = -r{toxinidir}/test-requirements.txt @@ -97,7 +104,7 @@ whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' html deps = -r{toxinidir}/docs/requirements.txt - -e{toxinidir} + {toxinidir} [testenv:docs-doc8] basepython = pypy3 @@ -115,7 +122,7 @@ whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' doctest deps = -r{toxinidir}/docs/requirements.txt - -e{toxinidir} + {toxinidir} [testenv:docs-linkcheck] basepython = pypy3 @@ -124,7 +131,7 @@ whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' linkcheck deps = -r{toxinidir}/docs/requirements.txt - -e{toxinidir} + {toxinidir} [testenv:docs-spelling] basepython = pypy3 @@ -133,7 +140,7 @@ whitelist_externals = make commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' spelling deps = -r{toxinidir}/docs/requirements.txt - -e{toxinidir} + {toxinidir} [doc8] ignore-path = -- GitLab From a14b6a22f43cc3a28df1be7895de62deeb141c72 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 23 Aug 2019 13:34:39 +0200 Subject: [PATCH 22/97] Don't run the build envs on a dying 2.7. --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index b2f235d4..7d996a8c 100644 --- a/tox.ini +++ b/tox.ini @@ -15,8 +15,8 @@ changedir = setenv = JSON_SCHEMA_TEST_SUITE = {toxinidir}/json whitelist_externals = - python2.7 mkdir + pypy rm sh virtualenv @@ -31,13 +31,13 @@ commands = perf: {envpython} {toxinidir}/jsonschema/benchmarks/json_schema_test_suite.py --inherit-environ JSON_SCHEMA_TEST_SUITE --output {envtmpdir}/benchmarks/json_schema_test_suite.json # Check to make sure that releases build and install properly - build: virtualenv --quiet --python=python2.7 {envtmpdir}/venv + build: virtualenv --quiet --python=pypy {envtmpdir}/venv build: {envtmpdir}/venv/bin/pip install --quiet wheel build: {envtmpdir}/venv/bin/python {toxinidir}/setup.py --quiet bdist_wheel --dist-dir={envtmpdir}/wheel build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/wheel/jsonschema*.whl' - build: python2.7 {toxinidir}/setup.py --quiet sdist --dist-dir={envtmpdir}/sdist --format=gztar,zip + build: pypy {toxinidir}/setup.py --quiet sdist --dist-dir={envtmpdir}/sdist --format=gztar,zip build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.tar.gz' build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.zip' -- GitLab From 36eee3cf5c3000b201e610a8b49fa2de561eb758 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 23 Aug 2019 13:37:07 +0200 Subject: [PATCH 23/97] Ugh right but Travis doesn't install PyPy everywhere. And I'm too lazy to figure out how to do that. Revert "Don't run the build envs on a dying 2.7." This reverts commit a14b6a22f43cc3a28df1be7895de62deeb141c72. --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 7d996a8c..b2f235d4 100644 --- a/tox.ini +++ b/tox.ini @@ -15,8 +15,8 @@ changedir = setenv = JSON_SCHEMA_TEST_SUITE = {toxinidir}/json whitelist_externals = + python2.7 mkdir - pypy rm sh virtualenv @@ -31,13 +31,13 @@ commands = perf: {envpython} {toxinidir}/jsonschema/benchmarks/json_schema_test_suite.py --inherit-environ JSON_SCHEMA_TEST_SUITE --output {envtmpdir}/benchmarks/json_schema_test_suite.json # Check to make sure that releases build and install properly - build: virtualenv --quiet --python=pypy {envtmpdir}/venv + build: virtualenv --quiet --python=python2.7 {envtmpdir}/venv build: {envtmpdir}/venv/bin/pip install --quiet wheel build: {envtmpdir}/venv/bin/python {toxinidir}/setup.py --quiet bdist_wheel --dist-dir={envtmpdir}/wheel build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/wheel/jsonschema*.whl' - build: pypy {toxinidir}/setup.py --quiet sdist --dist-dir={envtmpdir}/sdist --format=gztar,zip + build: python2.7 {toxinidir}/setup.py --quiet sdist --dist-dir={envtmpdir}/sdist --format=gztar,zip build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.tar.gz' build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.zip' -- GitLab From a5d26a53b230f61ede8f1b0ab04d306a8c828fe0 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 25 Aug 2019 21:47:58 +0200 Subject: [PATCH 24/97] Run pep517.check in CI. Probably eventually I'll drop the setup.py check. --- tox.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tox.ini b/tox.ini index b2f235d4..ab385dc1 100644 --- a/tox.ini +++ b/tox.ini @@ -41,6 +41,8 @@ commands = build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.tar.gz' build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.zip' + build: {envbindir}/python -m pep517.check {toxinidir} + # FIXME: This has side effects! But it's not my fault... I can't # figure out yet how to get setuptools to not create this directory # here yet. But whatever, probably this will change to pep517.build @@ -49,6 +51,8 @@ commands = deps = -r{toxinidir}/test-requirements.txt + build: pep517 + tests,coverage,codecov: twisted tests: lxml tests: sphinx -- GitLab From 3aa8ec9eae4419c895d4c0bda185b234241cc505 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 28 Aug 2019 21:48:22 +0200 Subject: [PATCH 25/97] New awpa is released. --- tox.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/tox.ini b/tox.ini index ab385dc1..486dc257 100644 --- a/tox.ini +++ b/tox.ini @@ -86,7 +86,6 @@ commands = {envbindir}/detect-secrets scan {toxinidir} [testenv:style] deps = ebb-lint>=0.19.1.0 - git+https://github.com/pyga/awpa@py37 commands = {envbindir}/flake8 {posargs} {toxinidir}/jsonschema {toxinidir}/docs {toxinidir}/setup.py -- GitLab From dd5b8d5c874d819832e5852d7fc1b5942a894408 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 29 Aug 2019 09:30:03 +0200 Subject: [PATCH 26/97] Doc stylin. --- docs/errors.rst | 46 ---------------- jsonschema/benchmarks/issue232.py | 5 +- jsonschema/cli.py | 3 ++ jsonschema/exceptions.py | 90 ++++++++++++++++++++++++++++--- jsonschema/validators.py | 33 ++++++++++++ setup.cfg | 15 +++++- 6 files changed, 135 insertions(+), 57 deletions(-) diff --git a/docs/errors.rst b/docs/errors.rst index 1851ff5d..d3827026 100644 --- a/docs/errors.rst +++ b/docs/errors.rst @@ -9,8 +9,6 @@ raised or returned, depending on which method or function is used. .. autoexception:: ValidationError - The instance didn't properly validate under the provided schema. - The information carried by an error roughly breaks down into: =============== ================= ======================== @@ -119,8 +117,6 @@ raised. .. autoexception:: SchemaError - The provided schema is malformed. - The same attributes are present as for `ValidationError`\s. @@ -360,37 +356,6 @@ to guess the most relevant error in a given bunch. .. autofunction:: best_match - 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. - - :argument collections.Iterable errors: 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. - :argument collections.Callable key: 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. - .. function:: relevance(validation_error) @@ -432,14 +397,3 @@ to guess the most relevant error in a given bunch. .. autofunction:: by_relevance - - Create a key function that can be used to sort errors by relevance. - - :argument set weak: 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. - :argument set strong: a collection of validator names to consider to - be "strong" diff --git a/jsonschema/benchmarks/issue232.py b/jsonschema/benchmarks/issue232.py index 1bbb3558..65e3aedf 100644 --- a/jsonschema/benchmarks/issue232.py +++ b/jsonschema/benchmarks/issue232.py @@ -1,9 +1,8 @@ #!/usr/bin/env python """ -A performance benchmark using the example from issue #232: - -https://github.com/Julian/jsonschema/pull/232 +A performance benchmark using the example from issue #232. +See https://github.com/Julian/jsonschema/pull/232. """ from twisted.python.filepath import FilePath from pyperf import Runner diff --git a/jsonschema/cli.py b/jsonschema/cli.py index 6a503ecd..45acb741 100644 --- a/jsonschema/cli.py +++ b/jsonschema/cli.py @@ -1,3 +1,6 @@ +""" +The ``jsonschema`` command line. +""" from __future__ import absolute_import import argparse import json diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 90081821..9d6949da 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -1,3 +1,6 @@ +""" +Validation errors, and some surrounding helpers. +""" from collections import defaultdict, deque import itertools import pprint @@ -129,17 +132,28 @@ class _Error(Exception): 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() @@ -148,6 +162,10 @@ class RefResolutionError(Exception): class UndefinedTypeCheck(Exception): + """ + A type checker was asked to check a type it did not have registered. + """ + def __init__(self, type): self.type = type @@ -162,6 +180,10 @@ class UndefinedTypeCheck(Exception): 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 @@ -187,6 +209,10 @@ class UnknownType(Exception): class FormatError(Exception): + """ + Validating a format failed. + """ + def __init__(self, message, cause=None): super(FormatError, self).__init__(message, cause) self.message = message @@ -205,7 +231,6 @@ class FormatError(Exception): class ErrorTree(object): """ ErrorTrees make it easier to check which validations failed. - """ _instance = _unset @@ -246,22 +271,22 @@ class ErrorTree(object): 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): """ - Same as `total_errors`. - + Return the `total_errors`. """ - return self.total_errors def __repr__(self): @@ -271,7 +296,6 @@ class ErrorTree(object): def total_errors(self): """ The total number of errors in the entire tree, including children. - """ child_errors = sum(len(tree) for _, tree in iteritems(self._contents)) @@ -279,6 +303,22 @@ class ErrorTree(object): 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 @@ -289,6 +329,44 @@ 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.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.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: diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 089dbbbd..1dc420c7 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -1,3 +1,6 @@ +""" +Creation and extension of validators, with implementations for existing drafts. +""" from __future__ import division from warnings import warn @@ -679,11 +682,26 @@ class RefResolver(object): 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: @@ -695,15 +713,24 @@ class RefResolver(object): @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. + """ self.push_scope(scope) try: yield @@ -732,10 +759,16 @@ class RefResolver(object): self.pop_scope() def resolve(self, ref): + """ + Resolve the given reference. + """ url = self._urljoin_cache(self.resolution_scope, ref) return url, self._remote_cache(url) def resolve_from_url(self, url): + """ + Resolve the given remote URL. + """ url, fragment = urldefrag(url) try: document = self.store[url] diff --git a/setup.cfg b/setup.cfg index 1a448466..3c86176f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,10 +47,21 @@ console_scripts = [options.package_data] jsonschema = schemas/*.json +[bdist_wheel] +universal = 1 + [flake8] exclude = jsonschema/__init__.py jsonschema/_reflect.py -[bdist_wheel] -universal = 1 +[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 -- GitLab From 80e96a3d02c930a0d74fa4eb65e2276c37f170e4 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Tue, 3 Sep 2019 08:08:52 +0200 Subject: [PATCH 27/97] Lunix spelling. --- docs/spelling-wordlist.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt index e43b09ce..d745513a 100644 --- a/docs/spelling-wordlist.txt +++ b/docs/spelling-wordlist.txt @@ -8,6 +8,7 @@ ValidationError th callables deque +dereferences hostname implementers indices @@ -15,6 +16,7 @@ indices ipv iterable jsonschema +metaschema pre programmatically recurses -- GitLab From f082f83c395a657b58c542c60cadc9ba394e2b8a Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Tue, 3 Sep 2019 08:39:12 +0200 Subject: [PATCH 28/97] Don't let flake8 complain about unicode on Py3. This isn't really the right way to do this, but the code it complains about won't run on Py3, and some random future code that uses unicode should get unit tested, so we don't rely on flake8 for actually testing stuff runs correctly... --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index 3c86176f..70e1712e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,6 +51,7 @@ jsonschema = schemas/*.json universal = 1 [flake8] +builtins = unicode exclude = jsonschema/__init__.py jsonschema/_reflect.py -- GitLab From b958b383d45ca6d8c1ba783c0f10b80e08be5ece Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Tue, 3 Sep 2019 10:12:34 +0200 Subject: [PATCH 29/97] Combine the README with the doc landing page. --- README.rst | 4 +--- docs/index.rst | 40 +++------------------------------------- 2 files changed, 4 insertions(+), 40 deletions(-) diff --git a/README.rst b/README.rst index e87b1bd6..4ea8683e 100644 --- a/README.rst +++ b/README.rst @@ -103,9 +103,7 @@ Online demo Notebook will look similar to this: .. image:: https://user-images.githubusercontent.com/1155573/56820861-5c1c1880-6823-11e9-802a-ce01c5ec574f.gif :alt: Open Live Demo - :width: 50 px - :scale: 10 % - + :width: 480 px Release Notes diff --git a/docs/index.rst b/docs/index.rst index 1fd4ba63..e4d72527 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,43 +1,9 @@ -========== -jsonschema -========== - - .. module:: jsonschema +.. include:: ../README.rst -``jsonschema`` is an implementation of `JSON Schema `_ -for Python (supporting 2.7+ including Python 3). - -.. 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' - - -You can find further information (installation instructions, mailing list) -as well as the source code and issue tracker on our -`GitHub page `__. - -Contents: +Contents +-------- .. toctree:: :maxdepth: 2 -- GitLab From b7aadb7489d552f616a403e780ed3b10a19b9349 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 4 Sep 2019 08:19:24 +0200 Subject: [PATCH 30/97] Lunix spelling. --- docs/spelling-wordlist.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt index d745513a..8fe083c9 100644 --- a/docs/spelling-wordlist.txt +++ b/docs/spelling-wordlist.txt @@ -15,6 +15,7 @@ indices # ipv4/6, sigh... ipv iterable +iteratively jsonschema metaschema pre @@ -30,3 +31,6 @@ validator validators versioned schemas + +Berman +Freenode -- GitLab From 120b5162a1e6b59d2b6f0e96784de43c464bf5d1 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 4 Sep 2019 08:29:43 +0200 Subject: [PATCH 31/97] Fix a broken link. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 4ea8683e..dd033c5a 100644 --- a/README.rst +++ b/README.rst @@ -74,7 +74,7 @@ Features * `Lazy validation `_ that can iteratively report *all* validation errors. -* `Programmatic querying `_ +* `Programmatic querying `_ of which properties or items failed validation. -- GitLab From c741292e7c73f812f540daed4749f5c118ecf924 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 4 Sep 2019 08:47:01 +0200 Subject: [PATCH 32/97] Explicitly mention that benchmarks are not public. --- docs/faq.rst | 5 ++++- jsonschema/benchmarks/__init__.py | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/faq.rst b/docs/faq.rst index 768bd15b..9e6bca93 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -148,7 +148,10 @@ notice: * the contents of the ``jsonschema.tests`` package - * the ``compat.py`` module, which is for internal compatibility use + * the contents of the ``jsonschema.benchmarks`` package + + * the ``jsonschema.compat`` module, which is for internal + compatibility use * anything marked private diff --git a/jsonschema/benchmarks/__init__.py b/jsonschema/benchmarks/__init__.py index e69de29b..e3dcc689 100644 --- a/jsonschema/benchmarks/__init__.py +++ b/jsonschema/benchmarks/__init__.py @@ -0,0 +1,5 @@ +""" +Benchmarks for validation. + +This package is *not* public API. +""" -- GitLab From a5d9c3e5b828d7b9b17dbc041408702aad8206ed Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 4 Sep 2019 09:13:58 +0200 Subject: [PATCH 33/97] Don't run benchmarks under coverage. --- .coveragerc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coveragerc b/.coveragerc index 0294caff..0f24d2f0 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,4 +2,4 @@ [run] branch = True source = jsonschema -omit = */jsonschema/_reflect.py,*/jsonschema/__main__.py +omit = */jsonschema/_reflect.py,*/jsonschema/__main__.py,*/jsonschema/benchmarks/* -- GitLab From 6f05b2e8b7517667edf570418ca47ab37b7400b9 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 4 Sep 2019 09:23:16 +0200 Subject: [PATCH 34/97] Squashed 'json/' changes from e2f566f6..6b673312 6b673312 Merge pull request #276 from malcolmsparks/patch-1 4b55dc38 Renamed JUXT's Clojure implementation to jinx b173eaa2 Merge pull request #275 from Zac-HD/tweaks 3768953e Valid test for contains: false 798351be Valid test for contains: false git-subtree-dir: json git-subtree-split: 6b6733126e5cd571fc6b7a1a5a8190a09d6cb7b9 --- README.md | 2 +- tests/draft6/contains.json | 5 +++++ tests/draft7/contains.json | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1145f433..f65934c4 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,8 @@ This suite is being used by: ### Clojure ### +* [jinx](https://github.com/juxt/jinx) * [json-schema](https://github.com/tatut/json-schema) -* [JSON Schema for Clojure(Script) (JUXT)](https://github.com/juxt/json-schema) ### Coffeescript ### diff --git a/tests/draft6/contains.json b/tests/draft6/contains.json index b7ae5a25..67ecbd99 100644 --- a/tests/draft6/contains.json +++ b/tests/draft6/contains.json @@ -89,6 +89,11 @@ "description": "empty array is invalid", "data": [], "valid": false + }, + { + "description": "non-arrays are valid", + "data": "contains does not apply to strings", + "valid": true } ] } diff --git a/tests/draft7/contains.json b/tests/draft7/contains.json index b7ae5a25..67ecbd99 100644 --- a/tests/draft7/contains.json +++ b/tests/draft7/contains.json @@ -89,6 +89,11 @@ "description": "empty array is invalid", "data": [], "valid": false + }, + { + "description": "non-arrays are valid", + "data": "contains does not apply to strings", + "valid": true } ] } -- GitLab From d241afb695b072f311974cf64ba8f271b3dfcfaa Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 4 Sep 2019 11:15:24 +0200 Subject: [PATCH 35/97] FormatChecker.__repr__ This could use attrs, but probably some day checkers will become a pyrsistent.pmap, and we can do that then. --- jsonschema/_format.py | 3 +++ jsonschema/tests/test_format.py | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/jsonschema/_format.py b/jsonschema/_format.py index d3f1345e..51b9b503 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -39,6 +39,9 @@ class FormatChecker(object): else: self.checkers = dict((k, self.checkers[k]) for k in formats) + def __repr__(self): + return "".format(sorted(self.checkers)) + def checks(self, format, raises=()): """ Register a decorated function as validating a new format. diff --git a/jsonschema/tests/test_format.py b/jsonschema/tests/test_format.py index e9e5f995..14512c5b 100644 --- a/jsonschema/tests/test_format.py +++ b/jsonschema/tests/test_format.py @@ -78,3 +78,13 @@ class TestFormatChecker(TestCase): 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) + checker.checks("bar")(lambda thing: True) + checker.checks("baz")(lambda thing: True) + self.assertEqual( + repr(checker), + "", + ) -- GitLab From 2d1c4a397a38469daa96743523f8d1d73d782e04 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 4 Sep 2019 11:18:28 +0200 Subject: [PATCH 36/97] Minor style. --- jsonschema/tests/test_format.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jsonschema/tests/test_format.py b/jsonschema/tests/test_format.py index 14512c5b..254985f6 100644 --- a/jsonschema/tests/test_format.py +++ b/jsonschema/tests/test_format.py @@ -1,6 +1,5 @@ """ Tests for the parts of jsonschema related to the :validator:`format` property. - """ from unittest import TestCase -- GitLab From f796b23b25be7600efe7225961d0307642bd83d7 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 5 Sep 2019 08:25:17 +0200 Subject: [PATCH 37/97] Minor style. --- docs/jsonschema_role.py | 4 ---- jsonschema/__init__.py | 1 - jsonschema/_format.py | 4 ---- jsonschema/_utils.py | 10 ---------- jsonschema/exceptions.py | 4 ---- jsonschema/tests/test_exceptions.py | 6 ------ jsonschema/tests/test_validators.py | 1 - 7 files changed, 30 deletions(-) diff --git a/docs/jsonschema_role.py b/docs/jsonschema_role.py index 6c7b1440..637a71c7 100644 --- a/docs/jsonschema_role.py +++ b/docs/jsonschema_role.py @@ -24,7 +24,6 @@ def setup(app): app (sphinx.application.Sphinx): the Sphinx application context - """ app.add_config_value("cache_path", "_cache", "") @@ -49,7 +48,6 @@ def fetch_or_load(spec_path): cache_path: the path to a cached specification - """ headers = {} @@ -81,7 +79,6 @@ def docutils_sucks(spec): It doesn't allow using a class because it does stupid stuff like try to set attributes on the callable object rather than just keeping a dict. - """ base_url = VALIDATION_SPEC @@ -120,7 +117,6 @@ def docutils_sucks(spec): a 2-tuple of nodes to insert into the document and an iterable of system messages, both possibly empty - """ if text == "$ref": diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index 0da56aac..642843a5 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -6,7 +6,6 @@ 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. - """ from jsonschema.exceptions import ( diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 51b9b503..aa040902 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -28,7 +28,6 @@ class FormatChecker(object): The known formats to validate. This argument can be used to limit which formats will be used during validation. - """ checkers = {} @@ -60,7 +59,6 @@ class FormatChecker(object): The exception object will be accessible as the `jsonschema.exceptions.ValidationError.cause` attribute of the resulting validation error. - """ def _checks(func): @@ -88,7 +86,6 @@ class FormatChecker(object): Raises: FormatError: if the instance does not conform to ``format`` - """ if format not in self.checkers: @@ -122,7 +119,6 @@ class FormatChecker(object): Returns: bool: whether it conformed - """ try: diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 79c2bc9a..ceb88019 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -9,7 +9,6 @@ from jsonschema.compat import MutableMapping, str_types, urlsplit class URIDict(MutableMapping): """ Dictionary which uses normalized URIs as keys. - """ def normalize(self, uri): @@ -41,7 +40,6 @@ class URIDict(MutableMapping): class Unset(object): """ An as-of-yet unset attribute or unprovided default parameter. - """ def __repr__(self): @@ -51,7 +49,6 @@ class Unset(object): def load_schema(name): """ Load a schema from ./schemas/``name``.json and return it. - """ data = pkgutil.get_data("jsonschema", "schemas/{0}.json".format(name)) @@ -61,7 +58,6 @@ def load_schema(name): def indent(string, times=1): """ A dumb version of `textwrap.indent` from Python 3.3. - """ return "\n".join(" " * (4 * times) + line for line in string.splitlines()) @@ -78,7 +74,6 @@ def format_as_index(indices): indices (sequence): The indices to format. - """ if not indices: @@ -94,7 +89,6 @@ def find_additional_properties(instance, schema): / or ``patternProperties``. Assumes ``instance`` is dict-like already. - """ properties = schema.get("properties", {}) @@ -109,7 +103,6 @@ def find_additional_properties(instance, schema): def extras_msg(extras): """ Create an error message for extra items or properties. - """ if len(extras) == 1: @@ -127,7 +120,6 @@ def types_msg(instance, types): be considered to be a description of that object and used as its type. Otherwise the message is simply the reprs of the given ``types``. - """ reprs = [] @@ -147,7 +139,6 @@ def flatten(suitable_for_isinstance): * an arbitrary nested tree of tuples Return a flattened tuple of the given argument. - """ types = set() @@ -167,7 +158,6 @@ def ensure_list(thing): Wrap ``thing`` in a list if it's a single str. Otherwise, return it unchanged. - """ if isinstance(thing, str_types): diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 9d6949da..691dcffe 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -250,7 +250,6 @@ class ErrorTree(object): def __contains__(self, index): """ Check whether ``instance[index]`` has any errors. - """ return index in self._contents @@ -263,7 +262,6 @@ class ErrorTree(object): is not known by this tree, whatever error would be raised by ``instance.__getitem__`` will be propagated (usually this is some subclass of `exceptions.LookupError`. - """ if self._instance is not _unset and index not in self: @@ -317,7 +315,6 @@ def by_relevance(weak=WEAK_MATCHES, strong=STRONG_MATCHES): strong (set): a collection of validator names to consider to be "strong" - """ def relevance(error): validator = error.validator @@ -365,7 +362,6 @@ def best_match(errors, key=relevance): 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) diff --git a/jsonschema/tests/test_exceptions.py b/jsonschema/tests/test_exceptions.py index e83801f0..eae00d76 100644 --- a/jsonschema/tests/test_exceptions.py +++ b/jsonschema/tests/test_exceptions.py @@ -35,7 +35,6 @@ class TestBestMatch(TestCase): """ A property you *must* match is probably better than one you have to match a part of. - """ validator = Draft4Validator( @@ -56,7 +55,6 @@ class TestBestMatch(TestCase): I.e. since only one of the schemas must match, we look for the most relevant one. - """ validator = Draft4Validator( @@ -82,7 +80,6 @@ class TestBestMatch(TestCase): I.e. since only one of the schemas must match, we look for the most relevant one. - """ validator = Draft4Validator( @@ -104,7 +101,6 @@ class TestBestMatch(TestCase): """ Now, if the error is allOf, we traverse but select the *most* relevant error from the context, because all schemas here must match anyways. - """ validator = Draft4Validator( @@ -281,7 +277,6 @@ class TestErrorTree(TestCase): 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( @@ -441,7 +436,6 @@ class TestErrorInitReprStr(TestCase): Check for https://github.com/Julian/jsonschema/issues/164 which rendered exceptions unusable when a `ValidationError` involved instances with an `__eq__` method that returned truthy values. - """ class DontEQMeBro(object): diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 5a6fac34..42720cc4 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -1155,7 +1155,6 @@ class ValidatorTestMixin(MetaSchemaTestsMixin, object): """ Legacy RefResolvers support only the context manager form of resolution. - """ class LegacyRefResolver(object): -- GitLab From bbf080b20df23234e8cf3e23d2c7a241bc31a434 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 5 Sep 2019 18:05:59 +0200 Subject: [PATCH 38/97] Minor fixes for CLI help. --- jsonschema/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsonschema/cli.py b/jsonschema/cli.py index 45acb741..78779a81 100644 --- a/jsonschema/cli.py +++ b/jsonschema/cli.py @@ -31,7 +31,7 @@ parser.add_argument( dest="instances", type=_json_file, help=( - "a path to a JSON instance (i.e. filename.json)" + "a path to a JSON instance (i.e. filename.json) " "to validate (may be specified multiple times)" ), ) @@ -60,7 +60,7 @@ parser.add_argument( ) parser.add_argument( "schema", - help="the JSON Schema to validate with (i.e. filename.schema)", + help="the JSON Schema to validate with (i.e. schema.json)", type=_json_file, ) -- GitLab From 601168ca8aa41f39cf46953a6bee89e7c6f127a4 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 5 Sep 2019 18:17:05 +0200 Subject: [PATCH 39/97] Minor style. --- jsonschema/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema/cli.py b/jsonschema/cli.py index 78779a81..ab3335b2 100644 --- a/jsonschema/cli.py +++ b/jsonschema/cli.py @@ -55,7 +55,7 @@ parser.add_argument( ) parser.add_argument( "--version", - action='version', + action="version", version=__version__, ) parser.add_argument( -- GitLab From a5a5a45cfa7ac901462ca8afcab544f3c2de9e1d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 22 Sep 2019 12:55:37 -0400 Subject: [PATCH 40/97] Squashed 'json/' changes from 6b673312..2903943b 2903943b Merge pull request #277 from json-schema-org/non-string-formats 95425df4 Move tests for builtin formats ignoring non-strings upstream. aa71850e Merge pull request #278 from gregsdennis/master 4b638034 updated 2019-09 references to correct schema uri 8656a718 moved 2019-08 tests to 2019-09; fixed a few 2019-06 $refs 0f888a8f Make ajv's tests not fail the build. 3922a3c2 Run the suite sanity checks on Py3. 9eda690f Minor style. git-subtree-dir: json git-subtree-split: 2903943b4c31a33a9dc8b017174deefdf46f5213 --- .travis.yml | 5 +- bin/jsonschema_suite | 4 +- .../additionalItems.json | 0 .../additionalProperties.json | 0 .../{draft2019-08 => draft2019-09}/allOf.json | 0 .../{draft2019-08 => draft2019-09}/anyOf.json | 0 .../boolean_schema.json | 0 .../{draft2019-08 => draft2019-09}/const.json | 0 .../contains.json | 0 .../default.json | 0 .../{draft2019-08 => draft2019-09}/defs.json | 4 +- .../dependencies.json | 0 .../{draft2019-08 => draft2019-09}/enum.json | 0 .../exclusiveMaximum.json | 0 .../exclusiveMinimum.json | 0 tests/draft2019-09/format.json | 614 ++++++++++++++++++ .../if-then-else.json | 0 .../{draft2019-08 => draft2019-09}/items.json | 0 .../maxItems.json | 0 .../maxLength.json | 0 .../maxProperties.json | 0 .../maximum.json | 0 .../minItems.json | 0 .../minLength.json | 0 .../minProperties.json | 0 .../minimum.json | 0 .../multipleOf.json | 0 tests/{draft2019-08 => draft2019-09}/not.json | 0 .../{draft2019-08 => draft2019-09}/oneOf.json | 0 .../optional/bignum.json | 0 .../optional/content.json | 0 .../optional/ecmascript-regex.json | 0 .../optional/format/date-time.json | 0 .../optional/format/date.json | 0 .../optional/format/email.json | 0 .../optional/format/hostname.json | 0 .../optional/format/idn-email.json | 0 .../optional/format/idn-hostname.json | 0 .../optional/format/ipv4.json | 0 .../optional/format/ipv6.json | 0 .../optional/format/iri-reference.json | 0 .../optional/format/iri.json | 0 .../optional/format/json-pointer.json | 0 .../optional/format/regex.json | 0 .../format/relative-json-pointer.json | 0 .../optional/format/time.json | 0 .../optional/format/uri-reference.json | 0 .../optional/format/uri-template.json | 4 +- .../optional/format/uri.json | 0 .../optional/zeroTerminatedFloats.json | 0 .../pattern.json | 0 .../patternProperties.json | 0 .../properties.json | 0 .../propertyNames.json | 0 tests/{draft2019-08 => draft2019-09}/ref.json | 2 +- .../refRemote.json | 0 .../required.json | 0 .../{draft2019-08 => draft2019-09}/type.json | 0 .../uniqueItems.json | 0 tests/draft3/format.json | 362 +++++++++++ tests/draft4/format.json | 218 +++++++ tests/draft6/format.json | 326 ++++++++++ tests/draft6/optional/format.json | 4 +- tests/draft7/format.json | 614 ++++++++++++++++++ .../draft7/optional/format/uri-template.json | 4 +- 65 files changed, 2144 insertions(+), 17 deletions(-) rename tests/{draft2019-08 => draft2019-09}/additionalItems.json (100%) rename tests/{draft2019-08 => draft2019-09}/additionalProperties.json (100%) rename tests/{draft2019-08 => draft2019-09}/allOf.json (100%) rename tests/{draft2019-08 => draft2019-09}/anyOf.json (100%) rename tests/{draft2019-08 => draft2019-09}/boolean_schema.json (100%) rename tests/{draft2019-08 => draft2019-09}/const.json (100%) rename tests/{draft2019-08 => draft2019-09}/contains.json (100%) rename tests/{draft2019-08 => draft2019-09}/default.json (100%) rename tests/{draft2019-08 => draft2019-09}/defs.json (77%) rename tests/{draft2019-08 => draft2019-09}/dependencies.json (100%) rename tests/{draft2019-08 => draft2019-09}/enum.json (100%) rename tests/{draft2019-08 => draft2019-09}/exclusiveMaximum.json (100%) rename tests/{draft2019-08 => draft2019-09}/exclusiveMinimum.json (100%) create mode 100644 tests/draft2019-09/format.json rename tests/{draft2019-08 => draft2019-09}/if-then-else.json (100%) rename tests/{draft2019-08 => draft2019-09}/items.json (100%) rename tests/{draft2019-08 => draft2019-09}/maxItems.json (100%) rename tests/{draft2019-08 => draft2019-09}/maxLength.json (100%) rename tests/{draft2019-08 => draft2019-09}/maxProperties.json (100%) rename tests/{draft2019-08 => draft2019-09}/maximum.json (100%) rename tests/{draft2019-08 => draft2019-09}/minItems.json (100%) rename tests/{draft2019-08 => draft2019-09}/minLength.json (100%) rename tests/{draft2019-08 => draft2019-09}/minProperties.json (100%) rename tests/{draft2019-08 => draft2019-09}/minimum.json (100%) rename tests/{draft2019-08 => draft2019-09}/multipleOf.json (100%) rename tests/{draft2019-08 => draft2019-09}/not.json (100%) rename tests/{draft2019-08 => draft2019-09}/oneOf.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/bignum.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/content.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/ecmascript-regex.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/date-time.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/date.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/email.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/hostname.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/idn-email.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/idn-hostname.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/ipv4.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/ipv6.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/iri-reference.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/iri.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/json-pointer.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/regex.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/relative-json-pointer.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/time.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/uri-reference.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/format/uri-template.json (92%) rename tests/{draft2019-08 => draft2019-09}/optional/format/uri.json (100%) rename tests/{draft2019-08 => draft2019-09}/optional/zeroTerminatedFloats.json (100%) rename tests/{draft2019-08 => draft2019-09}/pattern.json (100%) rename tests/{draft2019-08 => draft2019-09}/patternProperties.json (100%) rename tests/{draft2019-08 => draft2019-09}/properties.json (100%) rename tests/{draft2019-08 => draft2019-09}/propertyNames.json (100%) rename tests/{draft2019-08 => draft2019-09}/ref.json (99%) rename tests/{draft2019-08 => draft2019-09}/refRemote.json (100%) rename tests/{draft2019-08 => draft2019-09}/required.json (100%) rename tests/{draft2019-08 => draft2019-09}/type.json (100%) rename tests/{draft2019-08 => draft2019-09}/uniqueItems.json (100%) create mode 100644 tests/draft3/format.json create mode 100644 tests/draft4/format.json create mode 100644 tests/draft6/format.json create mode 100644 tests/draft7/format.json diff --git a/.travis.yml b/.travis.yml index 9c508231..f65e40bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,8 @@ language: python -python: "2.7" +python: "3.7" node_js: "9" install: - pip install tox - - npm install script: - tox - - npm test + - npm install && npm test || true diff --git a/bin/jsonschema_suite b/bin/jsonschema_suite index 7c181f9d..8c5bbc99 100755 --- a/bin/jsonschema_suite +++ b/bin/jsonschema_suite @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 from __future__ import print_function from pprint import pformat import argparse @@ -149,7 +149,7 @@ class SanityTests(unittest.TestCase): expected = { os.path.join(REMOTES_DIR, path): contents - for path, contents in REMOTES.iteritems() + for path, contents in REMOTES.items() } missing = set(files).symmetric_difference(expected) diff --git a/tests/draft2019-08/additionalItems.json b/tests/draft2019-09/additionalItems.json similarity index 100% rename from tests/draft2019-08/additionalItems.json rename to tests/draft2019-09/additionalItems.json diff --git a/tests/draft2019-08/additionalProperties.json b/tests/draft2019-09/additionalProperties.json similarity index 100% rename from tests/draft2019-08/additionalProperties.json rename to tests/draft2019-09/additionalProperties.json diff --git a/tests/draft2019-08/allOf.json b/tests/draft2019-09/allOf.json similarity index 100% rename from tests/draft2019-08/allOf.json rename to tests/draft2019-09/allOf.json diff --git a/tests/draft2019-08/anyOf.json b/tests/draft2019-09/anyOf.json similarity index 100% rename from tests/draft2019-08/anyOf.json rename to tests/draft2019-09/anyOf.json diff --git a/tests/draft2019-08/boolean_schema.json b/tests/draft2019-09/boolean_schema.json similarity index 100% rename from tests/draft2019-08/boolean_schema.json rename to tests/draft2019-09/boolean_schema.json diff --git a/tests/draft2019-08/const.json b/tests/draft2019-09/const.json similarity index 100% rename from tests/draft2019-08/const.json rename to tests/draft2019-09/const.json diff --git a/tests/draft2019-08/contains.json b/tests/draft2019-09/contains.json similarity index 100% rename from tests/draft2019-08/contains.json rename to tests/draft2019-09/contains.json diff --git a/tests/draft2019-08/default.json b/tests/draft2019-09/default.json similarity index 100% rename from tests/draft2019-08/default.json rename to tests/draft2019-09/default.json diff --git a/tests/draft2019-08/defs.json b/tests/draft2019-09/defs.json similarity index 77% rename from tests/draft2019-08/defs.json rename to tests/draft2019-09/defs.json index e3c298d3..f2fbec42 100644 --- a/tests/draft2019-08/defs.json +++ b/tests/draft2019-09/defs.json @@ -1,7 +1,7 @@ [ { "description": "valid definition", - "schema": {"$ref": "http://json-schema.org/draft/2019-06/schema#"}, + "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, "tests": [ { "description": "valid definition schema", @@ -12,7 +12,7 @@ }, { "description": "invalid definition", - "schema": {"$ref": "http://json-schema.org/draft/2019-06/schema#"}, + "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, "tests": [ { "description": "invalid definition schema", diff --git a/tests/draft2019-08/dependencies.json b/tests/draft2019-09/dependencies.json similarity index 100% rename from tests/draft2019-08/dependencies.json rename to tests/draft2019-09/dependencies.json diff --git a/tests/draft2019-08/enum.json b/tests/draft2019-09/enum.json similarity index 100% rename from tests/draft2019-08/enum.json rename to tests/draft2019-09/enum.json diff --git a/tests/draft2019-08/exclusiveMaximum.json b/tests/draft2019-09/exclusiveMaximum.json similarity index 100% rename from tests/draft2019-08/exclusiveMaximum.json rename to tests/draft2019-09/exclusiveMaximum.json diff --git a/tests/draft2019-08/exclusiveMinimum.json b/tests/draft2019-09/exclusiveMinimum.json similarity index 100% rename from tests/draft2019-08/exclusiveMinimum.json rename to tests/draft2019-09/exclusiveMinimum.json diff --git a/tests/draft2019-09/format.json b/tests/draft2019-09/format.json new file mode 100644 index 00000000..93305f5c --- /dev/null +++ b/tests/draft2019-09/format.json @@ -0,0 +1,614 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IDN e-mail addresses", + "schema": {"format": "idn-email"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of regexes", + "schema": {"format": "regex"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ipv4"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IDN hostnames", + "schema": {"format": "idn-hostname"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of hostnames", + "schema": {"format": "hostname"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date strings", + "schema": {"format": "date"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of time strings", + "schema": {"format": "time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of JSON pointers", + "schema": {"format": "json-pointer"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of relative JSON pointers", + "schema": {"format": "relative-json-pointer"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IRIs", + "schema": {"format": "iri"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IRI references", + "schema": {"format": "iri-reference"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URI references", + "schema": {"format": "uri-reference"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URI templates", + "schema": {"format": "uri-template"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff --git a/tests/draft2019-08/if-then-else.json b/tests/draft2019-09/if-then-else.json similarity index 100% rename from tests/draft2019-08/if-then-else.json rename to tests/draft2019-09/if-then-else.json diff --git a/tests/draft2019-08/items.json b/tests/draft2019-09/items.json similarity index 100% rename from tests/draft2019-08/items.json rename to tests/draft2019-09/items.json diff --git a/tests/draft2019-08/maxItems.json b/tests/draft2019-09/maxItems.json similarity index 100% rename from tests/draft2019-08/maxItems.json rename to tests/draft2019-09/maxItems.json diff --git a/tests/draft2019-08/maxLength.json b/tests/draft2019-09/maxLength.json similarity index 100% rename from tests/draft2019-08/maxLength.json rename to tests/draft2019-09/maxLength.json diff --git a/tests/draft2019-08/maxProperties.json b/tests/draft2019-09/maxProperties.json similarity index 100% rename from tests/draft2019-08/maxProperties.json rename to tests/draft2019-09/maxProperties.json diff --git a/tests/draft2019-08/maximum.json b/tests/draft2019-09/maximum.json similarity index 100% rename from tests/draft2019-08/maximum.json rename to tests/draft2019-09/maximum.json diff --git a/tests/draft2019-08/minItems.json b/tests/draft2019-09/minItems.json similarity index 100% rename from tests/draft2019-08/minItems.json rename to tests/draft2019-09/minItems.json diff --git a/tests/draft2019-08/minLength.json b/tests/draft2019-09/minLength.json similarity index 100% rename from tests/draft2019-08/minLength.json rename to tests/draft2019-09/minLength.json diff --git a/tests/draft2019-08/minProperties.json b/tests/draft2019-09/minProperties.json similarity index 100% rename from tests/draft2019-08/minProperties.json rename to tests/draft2019-09/minProperties.json diff --git a/tests/draft2019-08/minimum.json b/tests/draft2019-09/minimum.json similarity index 100% rename from tests/draft2019-08/minimum.json rename to tests/draft2019-09/minimum.json diff --git a/tests/draft2019-08/multipleOf.json b/tests/draft2019-09/multipleOf.json similarity index 100% rename from tests/draft2019-08/multipleOf.json rename to tests/draft2019-09/multipleOf.json diff --git a/tests/draft2019-08/not.json b/tests/draft2019-09/not.json similarity index 100% rename from tests/draft2019-08/not.json rename to tests/draft2019-09/not.json diff --git a/tests/draft2019-08/oneOf.json b/tests/draft2019-09/oneOf.json similarity index 100% rename from tests/draft2019-08/oneOf.json rename to tests/draft2019-09/oneOf.json diff --git a/tests/draft2019-08/optional/bignum.json b/tests/draft2019-09/optional/bignum.json similarity index 100% rename from tests/draft2019-08/optional/bignum.json rename to tests/draft2019-09/optional/bignum.json diff --git a/tests/draft2019-08/optional/content.json b/tests/draft2019-09/optional/content.json similarity index 100% rename from tests/draft2019-08/optional/content.json rename to tests/draft2019-09/optional/content.json diff --git a/tests/draft2019-08/optional/ecmascript-regex.json b/tests/draft2019-09/optional/ecmascript-regex.json similarity index 100% rename from tests/draft2019-08/optional/ecmascript-regex.json rename to tests/draft2019-09/optional/ecmascript-regex.json diff --git a/tests/draft2019-08/optional/format/date-time.json b/tests/draft2019-09/optional/format/date-time.json similarity index 100% rename from tests/draft2019-08/optional/format/date-time.json rename to tests/draft2019-09/optional/format/date-time.json diff --git a/tests/draft2019-08/optional/format/date.json b/tests/draft2019-09/optional/format/date.json similarity index 100% rename from tests/draft2019-08/optional/format/date.json rename to tests/draft2019-09/optional/format/date.json diff --git a/tests/draft2019-08/optional/format/email.json b/tests/draft2019-09/optional/format/email.json similarity index 100% rename from tests/draft2019-08/optional/format/email.json rename to tests/draft2019-09/optional/format/email.json diff --git a/tests/draft2019-08/optional/format/hostname.json b/tests/draft2019-09/optional/format/hostname.json similarity index 100% rename from tests/draft2019-08/optional/format/hostname.json rename to tests/draft2019-09/optional/format/hostname.json diff --git a/tests/draft2019-08/optional/format/idn-email.json b/tests/draft2019-09/optional/format/idn-email.json similarity index 100% rename from tests/draft2019-08/optional/format/idn-email.json rename to tests/draft2019-09/optional/format/idn-email.json diff --git a/tests/draft2019-08/optional/format/idn-hostname.json b/tests/draft2019-09/optional/format/idn-hostname.json similarity index 100% rename from tests/draft2019-08/optional/format/idn-hostname.json rename to tests/draft2019-09/optional/format/idn-hostname.json diff --git a/tests/draft2019-08/optional/format/ipv4.json b/tests/draft2019-09/optional/format/ipv4.json similarity index 100% rename from tests/draft2019-08/optional/format/ipv4.json rename to tests/draft2019-09/optional/format/ipv4.json diff --git a/tests/draft2019-08/optional/format/ipv6.json b/tests/draft2019-09/optional/format/ipv6.json similarity index 100% rename from tests/draft2019-08/optional/format/ipv6.json rename to tests/draft2019-09/optional/format/ipv6.json diff --git a/tests/draft2019-08/optional/format/iri-reference.json b/tests/draft2019-09/optional/format/iri-reference.json similarity index 100% rename from tests/draft2019-08/optional/format/iri-reference.json rename to tests/draft2019-09/optional/format/iri-reference.json diff --git a/tests/draft2019-08/optional/format/iri.json b/tests/draft2019-09/optional/format/iri.json similarity index 100% rename from tests/draft2019-08/optional/format/iri.json rename to tests/draft2019-09/optional/format/iri.json diff --git a/tests/draft2019-08/optional/format/json-pointer.json b/tests/draft2019-09/optional/format/json-pointer.json similarity index 100% rename from tests/draft2019-08/optional/format/json-pointer.json rename to tests/draft2019-09/optional/format/json-pointer.json diff --git a/tests/draft2019-08/optional/format/regex.json b/tests/draft2019-09/optional/format/regex.json similarity index 100% rename from tests/draft2019-08/optional/format/regex.json rename to tests/draft2019-09/optional/format/regex.json diff --git a/tests/draft2019-08/optional/format/relative-json-pointer.json b/tests/draft2019-09/optional/format/relative-json-pointer.json similarity index 100% rename from tests/draft2019-08/optional/format/relative-json-pointer.json rename to tests/draft2019-09/optional/format/relative-json-pointer.json diff --git a/tests/draft2019-08/optional/format/time.json b/tests/draft2019-09/optional/format/time.json similarity index 100% rename from tests/draft2019-08/optional/format/time.json rename to tests/draft2019-09/optional/format/time.json diff --git a/tests/draft2019-08/optional/format/uri-reference.json b/tests/draft2019-09/optional/format/uri-reference.json similarity index 100% rename from tests/draft2019-08/optional/format/uri-reference.json rename to tests/draft2019-09/optional/format/uri-reference.json diff --git a/tests/draft2019-08/optional/format/uri-template.json b/tests/draft2019-09/optional/format/uri-template.json similarity index 92% rename from tests/draft2019-08/optional/format/uri-template.json rename to tests/draft2019-09/optional/format/uri-template.json index d8396a5a..33ab76ee 100644 --- a/tests/draft2019-08/optional/format/uri-template.json +++ b/tests/draft2019-09/optional/format/uri-template.json @@ -1,9 +1,7 @@ [ { "description": "format: uri-template", - "schema": { - "format": "uri-template" - }, + "schema": {"format": "uri-template"}, "tests": [ { "description": "a valid uri-template", diff --git a/tests/draft2019-08/optional/format/uri.json b/tests/draft2019-09/optional/format/uri.json similarity index 100% rename from tests/draft2019-08/optional/format/uri.json rename to tests/draft2019-09/optional/format/uri.json diff --git a/tests/draft2019-08/optional/zeroTerminatedFloats.json b/tests/draft2019-09/optional/zeroTerminatedFloats.json similarity index 100% rename from tests/draft2019-08/optional/zeroTerminatedFloats.json rename to tests/draft2019-09/optional/zeroTerminatedFloats.json diff --git a/tests/draft2019-08/pattern.json b/tests/draft2019-09/pattern.json similarity index 100% rename from tests/draft2019-08/pattern.json rename to tests/draft2019-09/pattern.json diff --git a/tests/draft2019-08/patternProperties.json b/tests/draft2019-09/patternProperties.json similarity index 100% rename from tests/draft2019-08/patternProperties.json rename to tests/draft2019-09/patternProperties.json diff --git a/tests/draft2019-08/properties.json b/tests/draft2019-09/properties.json similarity index 100% rename from tests/draft2019-08/properties.json rename to tests/draft2019-09/properties.json diff --git a/tests/draft2019-08/propertyNames.json b/tests/draft2019-09/propertyNames.json similarity index 100% rename from tests/draft2019-08/propertyNames.json rename to tests/draft2019-09/propertyNames.json diff --git a/tests/draft2019-08/ref.json b/tests/draft2019-09/ref.json similarity index 99% rename from tests/draft2019-08/ref.json rename to tests/draft2019-09/ref.json index dbeb7d3b..d872426f 100644 --- a/tests/draft2019-08/ref.json +++ b/tests/draft2019-09/ref.json @@ -175,7 +175,7 @@ }, { "description": "remote ref, containing refs itself", - "schema": {"$ref": "http://json-schema.org/draft/2019-06/schema#"}, + "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, "tests": [ { "description": "remote ref valid", diff --git a/tests/draft2019-08/refRemote.json b/tests/draft2019-09/refRemote.json similarity index 100% rename from tests/draft2019-08/refRemote.json rename to tests/draft2019-09/refRemote.json diff --git a/tests/draft2019-08/required.json b/tests/draft2019-09/required.json similarity index 100% rename from tests/draft2019-08/required.json rename to tests/draft2019-09/required.json diff --git a/tests/draft2019-08/type.json b/tests/draft2019-09/type.json similarity index 100% rename from tests/draft2019-08/type.json rename to tests/draft2019-09/type.json diff --git a/tests/draft2019-08/uniqueItems.json b/tests/draft2019-09/uniqueItems.json similarity index 100% rename from tests/draft2019-08/uniqueItems.json rename to tests/draft2019-09/uniqueItems.json diff --git a/tests/draft3/format.json b/tests/draft3/format.json new file mode 100644 index 00000000..82793362 --- /dev/null +++ b/tests/draft3/format.json @@ -0,0 +1,362 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ip-address"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of hostnames", + "schema": {"format": "host-name"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of regular expressions", + "schema": {"format": "regex"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date strings", + "schema": {"format": "date"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of time strings", + "schema": {"format": "time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of CSS colors", + "schema": {"format": "color"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff --git a/tests/draft4/format.json b/tests/draft4/format.json new file mode 100644 index 00000000..61e4b62a --- /dev/null +++ b/tests/draft4/format.json @@ -0,0 +1,218 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ipv4"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of hostnames", + "schema": {"format": "hostname"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff --git a/tests/draft6/format.json b/tests/draft6/format.json new file mode 100644 index 00000000..32e81524 --- /dev/null +++ b/tests/draft6/format.json @@ -0,0 +1,326 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ipv4"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of hostnames", + "schema": {"format": "hostname"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of JSON pointers", + "schema": {"format": "json-pointer"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URI references", + "schema": {"format": "uri-reference"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URI templates", + "schema": {"format": "uri-template"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff --git a/tests/draft6/optional/format.json b/tests/draft6/optional/format.json index 74743ff6..3dd265fe 100644 --- a/tests/draft6/optional/format.json +++ b/tests/draft6/optional/format.json @@ -199,9 +199,7 @@ }, { "description": "format: uri-template", - "schema": { - "format": "uri-template" - }, + "schema": {"format": "uri-template"}, "tests": [ { "description": "a valid uri-template", diff --git a/tests/draft7/format.json b/tests/draft7/format.json new file mode 100644 index 00000000..93305f5c --- /dev/null +++ b/tests/draft7/format.json @@ -0,0 +1,614 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IDN e-mail addresses", + "schema": {"format": "idn-email"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of regexes", + "schema": {"format": "regex"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ipv4"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IDN hostnames", + "schema": {"format": "idn-hostname"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of hostnames", + "schema": {"format": "hostname"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date strings", + "schema": {"format": "date"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of time strings", + "schema": {"format": "time"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of JSON pointers", + "schema": {"format": "json-pointer"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of relative JSON pointers", + "schema": {"format": "relative-json-pointer"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IRIs", + "schema": {"format": "iri"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of IRI references", + "schema": {"format": "iri-reference"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URI references", + "schema": {"format": "uri-reference"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "validation of URI templates", + "schema": {"format": "uri-template"}, + "tests": [ + { + "description": "ignores integers", + "data": 12, + "valid": true + }, + { + "description": "ignores floats", + "data": 13.7, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores booleans", + "data": false, + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff --git a/tests/draft7/optional/format/uri-template.json b/tests/draft7/optional/format/uri-template.json index d8396a5a..33ab76ee 100644 --- a/tests/draft7/optional/format/uri-template.json +++ b/tests/draft7/optional/format/uri-template.json @@ -1,9 +1,7 @@ [ { "description": "format: uri-template", - "schema": { - "format": "uri-template" - }, + "schema": {"format": "uri-template"}, "tests": [ { "description": "a valid uri-template", -- GitLab From d89333bebdb5768ccf5a0d86d9f1379f91c067e6 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 22 Sep 2019 12:57:39 -0400 Subject: [PATCH 41/97] Moved upstream via json-schema-org/JSON-Schema-Test-Suite#277. --- jsonschema/tests/test_validators.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 42720cc4..6b446de6 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -1348,35 +1348,6 @@ class TestDraft7Validator(ValidatorTestMixin, TestCase): invalid = {"type": "integer"}, "foo" -class TestBuiltinFormats(TestCase): - """ - The built-in (specification-defined) formats do not raise type errors. - - If an instance or value is not a string, it should be ignored. - """ - - # These tests belong upstream. - # See https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/246 - - -for Validator, checker in ( - (validators.Draft3Validator, jsonschema.draft3_format_checker), - (validators.Draft4Validator, jsonschema.draft4_format_checker), - (validators.Draft6Validator, jsonschema.draft6_format_checker), - (validators.Draft7Validator, jsonschema.draft7_format_checker), -): - for format in checker.checkers: - def test(self, checker=checker, format=format): - validator = Validator({"format": format}, format_checker=checker) - validator.validate(123) - - name = "test_{}_{}_ignores_non_strings".format( - Validator.__name__, format, - ) - test.__name__ = name - setattr(TestBuiltinFormats, name, test) - - class TestValidatorFor(SynchronousTestCase): def test_draft_3(self): schema = {"$schema": "http://json-schema.org/draft-03/schema"} -- GitLab From 182f1ed3ff31980911764ed5288f6adc766eb203 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 22 Sep 2019 13:05:05 -0400 Subject: [PATCH 42/97] Style. --- jsonschema/tests/test_validators.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 6b446de6..3d6816db 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -15,7 +15,6 @@ import attr from jsonschema import FormatChecker, TypeChecker, exceptions, validators from jsonschema.compat import PY3, pathname2url from jsonschema.tests._helpers import bug -import jsonschema def startswith(validator, startswith, instance, schema): -- GitLab From 6a7155a854d57e3f13f9dec15f2ade0820dbca2a Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 26 Sep 2019 16:30:32 -0400 Subject: [PATCH 43/97] Switch to the newer importlib_metadata. It's basically replaced pkg_resources these days. See: https://importlib-metadata.readthedocs.io/en/latest/index.html --- jsonschema/__init__.py | 4 ++-- setup.cfg | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index 642843a5..f0bcd0d3 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -28,5 +28,5 @@ from jsonschema.validators import ( validate, ) -from pkg_resources import get_distribution -__version__ = get_distribution(__name__).version +import importlib_metadata +__version__ = importlib_metadata.version("jsonschema") diff --git a/setup.cfg b/setup.cfg index 70e1712e..d811ef9e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,6 +27,7 @@ packages = find: setup_requires = setuptools_scm install_requires = attrs>=17.4.0 + importlib_metadata pyrsistent>=0.14.0 setuptools six>=1.11.0 -- GitLab From 2e2034e5049c5edf1399a7cc5fe91e77248b61a6 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 26 Sep 2019 17:00:34 -0400 Subject: [PATCH 44/97] Spulling. --- docs/spelling-wordlist.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt index 8fe083c9..f1aaef4b 100644 --- a/docs/spelling-wordlist.txt +++ b/docs/spelling-wordlist.txt @@ -17,7 +17,9 @@ ipv iterable iteratively jsonschema +majorly metaschema +online pre programmatically recurses -- GitLab From 6bf09562d789203e849804b8d1f14cb042cfcd64 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 26 Sep 2019 17:17:13 -0400 Subject: [PATCH 45/97] 3.3 is dead, and all the tests seem to still pass. --- jsonschema/compat.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/jsonschema/compat.py b/jsonschema/compat.py index b8bc643f..47e09804 100644 --- a/jsonschema/compat.py +++ b/jsonschema/compat.py @@ -20,7 +20,7 @@ if PY3: from functools import lru_cache from io import StringIO as NativeIO from urllib.parse import ( - unquote, urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit + unquote, urljoin, urlunsplit, SplitResult, urlsplit ) from urllib.request import pathname2url, urlopen str_types = str, @@ -29,9 +29,7 @@ if PY3: else: from itertools import izip as zip # noqa from io import BytesIO as NativeIO - from urlparse import ( - urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit # noqa - ) + from urlparse import urljoin, urlunsplit, SplitResult, urlsplit from urllib import pathname2url, unquote # noqa import urllib2 # noqa def urlopen(*args, **kwargs): @@ -44,14 +42,6 @@ else: from functools32 import lru_cache -# On python < 3.3 fragments are not handled properly with unknown schemes -def urlsplit(url): - scheme, netloc, path, query, fragment = _urlsplit(url) - if "#" in path: - path, fragment = path.split("#", 1) - return SplitResult(scheme, netloc, path, query, fragment) - - def urldefrag(url): if "#" in url: s, n, p, q, frag = urlsplit(url) -- GitLab From 93f4cd8383d67d4140d27194dc3f4f03a4fe0875 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 28 Sep 2019 20:05:16 -0400 Subject: [PATCH 46/97] Use test-requirements for test requirements. --- tox.ini | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tox.ini b/tox.ini index 486dc257..c25bdcdd 100644 --- a/tox.ini +++ b/tox.ini @@ -49,19 +49,15 @@ commands = # soon anways. build: rm -rf {toxinidir}/jsonschema.egg-info deps = - -r{toxinidir}/test-requirements.txt - build: pep517 - tests,coverage,codecov: twisted - tests: lxml - tests: sphinx + perf: pyperf + + tests,coverage,codecov: -r{toxinidir}/test-requirements.txt coverage,codecov: coverage codecov: codecov - perf: pyperf - [testenv:demo] deps = jupyter commands = -- GitLab From 98f8a66954d82e4d49010c48c8855c096bbd9677 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 29 Sep 2019 00:49:40 -0400 Subject: [PATCH 47/97] Try re-enabling pypy3. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index c25bdcdd..e604dd7d 100644 --- a/tox.ini +++ b/tox.ini @@ -24,7 +24,7 @@ commands = perf,tests: {envbindir}/python -m pip install '{toxinidir}[format]' tests: {envbindir}/trial {posargs:jsonschema} - py{py,27,37}-tests: {envpython} -m doctest {toxinidir}/README.rst + tests: {envpython} -m doctest {toxinidir}/README.rst perf: mkdir {envtmpdir}/benchmarks/ perf: {envpython} {toxinidir}/jsonschema/benchmarks/issue232.py --inherit-environ JSON_SCHEMA_TEST_SUITE --output {envtmpdir}/benchmarks/issue232.json -- GitLab From 05fe96aa3669635a6f01359bf80a312002b4d7cd Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 2 Oct 2019 22:35:36 -0400 Subject: [PATCH 48/97] Squashed 'json/' changes from 2903943b..586515ef 586515ef Bump up the length of acceptable descriptions. 0518c651 Merge remote-tracking branch 'Zac-HD/ecma-regex' c0b24317 Tests for ECMA 262 regex dialect b6f79ee6 Merge pull request #281 from Zac-HD/unique-array-of-items 7c206159 Check uniqueItems with array items 2ebedeb9 Regenerate the remotes [just for trailing newlines essentially.] 98bb02a4 Output the trailing newline. 3f44bc76 Uh, this actually should be a native string. f7cc4cbe Sanity check on a non-dying Python. git-subtree-dir: json git-subtree-split: 586515efac8085ea3621c22f7b4d4d01f6349d6e --- bin/jsonschema_suite | 13 +- remotes/folder/folderInteger.json | 2 +- remotes/integer.json | 2 +- remotes/name-defs.json | 8 +- remotes/name.json | 8 +- remotes/subSchemas.json | 4 +- .../optional/ecmascript-regex.json | 181 ++++++++++++++++++ tests/draft2019-09/uniqueItems.json | 84 ++++++++ tests/draft3/uniqueItems.json | 84 ++++++++ tests/draft4/optional/ecmascript-regex.json | 181 ++++++++++++++++++ tests/draft4/uniqueItems.json | 84 ++++++++ tests/draft6/optional/ecmascript-regex.json | 181 ++++++++++++++++++ tests/draft6/uniqueItems.json | 84 ++++++++ tests/draft7/optional/ecmascript-regex.json | 181 ++++++++++++++++++ tests/draft7/uniqueItems.json | 84 ++++++++ tox.ini | 5 +- 16 files changed, 1171 insertions(+), 15 deletions(-) diff --git a/bin/jsonschema_suite b/bin/jsonschema_suite index 8c5bbc99..6b1c4864 100755 --- a/bin/jsonschema_suite +++ b/bin/jsonschema_suite @@ -99,11 +99,13 @@ class SanityTests(unittest.TestCase): def test_all_descriptions_have_reasonable_length(self): for case in cases(self.test_files): - descript = case["description"] + description = case["description"] self.assertLess( - len(descript), - 60, - "%r is too long! (keep it to less than 60 chars)" % (descript,) + len(description), + 70, + "%r is too long! (keep it to less than 70 chars)" % ( + description, + ), ) def test_all_descriptions_are_unique(self): @@ -217,8 +219,9 @@ def main(arguments): if e.errno != errno.EEXIST: raise - with open(filepath, "wb") as out_file: + with open(filepath, "w") as out_file: json.dump(schema, out_file, indent=4, sort_keys=True) + out_file.write("\n") elif arguments.command == "serve": try: from flask import Flask, jsonify diff --git a/remotes/folder/folderInteger.json b/remotes/folder/folderInteger.json index dbe5c758..8b50ea30 100644 --- a/remotes/folder/folderInteger.json +++ b/remotes/folder/folderInteger.json @@ -1,3 +1,3 @@ { "type": "integer" -} \ No newline at end of file +} diff --git a/remotes/integer.json b/remotes/integer.json index dbe5c758..8b50ea30 100644 --- a/remotes/integer.json +++ b/remotes/integer.json @@ -1,3 +1,3 @@ { "type": "integer" -} \ No newline at end of file +} diff --git a/remotes/name-defs.json b/remotes/name-defs.json index 1a4fe4ac..1dab4a43 100644 --- a/remotes/name-defs.json +++ b/remotes/name-defs.json @@ -2,8 +2,12 @@ "$defs": { "orNull": { "anyOf": [ - {"type": "null"}, - {"$ref": "#"} + { + "type": "null" + }, + { + "$ref": "#" + } ] } }, diff --git a/remotes/name.json b/remotes/name.json index 19ba0935..fceacb80 100644 --- a/remotes/name.json +++ b/remotes/name.json @@ -2,8 +2,12 @@ "definitions": { "orNull": { "anyOf": [ - {"type": "null"}, - {"$ref": "#"} + { + "type": "null" + }, + { + "$ref": "#" + } ] } }, diff --git a/remotes/subSchemas.json b/remotes/subSchemas.json index 8b6d8f84..9f8030bc 100644 --- a/remotes/subSchemas.json +++ b/remotes/subSchemas.json @@ -1,8 +1,8 @@ { "integer": { "type": "integer" - }, + }, "refToInteger": { "$ref": "#/integer" } -} \ No newline at end of file +} diff --git a/tests/draft2019-09/optional/ecmascript-regex.json b/tests/draft2019-09/optional/ecmascript-regex.json index 08dc9360..81643f8c 100644 --- a/tests/draft2019-09/optional/ecmascript-regex.json +++ b/tests/draft2019-09/optional/ecmascript-regex.json @@ -9,5 +9,186 @@ "valid": false } ] + }, + { + "description": "ECMA 262 regex converts \\a to ascii BEL", + "schema": { + "type": "string", + "pattern": "^\\a$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\a", + "valid": false + }, + { + "description": "matches", + "data": "\u0007", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and upper letter", + "schema": { + "type": "string", + "pattern": "^\\cC$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cC", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and lower letter", + "schema": { + "type": "string", + "pattern": "^\\cc$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cc", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\d matches ascii digits only", + "schema": { + "type": "string", + "pattern": "^\\d$" + }, + "tests": [ + { + "description": "ASCII zero matches", + "data": "0", + "valid": true + }, + { + "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", + "data": "߀", + "valid": false + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) does not match", + "data": "\\u07c0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\D matches everything but ascii digits", + "schema": { + "type": "string", + "pattern": "^\\D$" + }, + "tests": [ + { + "description": "ASCII zero does not match", + "data": "0", + "valid": false + }, + { + "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", + "data": "߀", + "valid": true + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) matches", + "data": "\\u07c0", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\w matches ascii letters only", + "schema": { + "type": "string", + "pattern": "^\\w$" + }, + "tests": [ + { + "description": "ASCII 'a' matches", + "data": "a", + "valid": true + }, + { + "description": "latin-1 e-acute does not match (unlike e.g. Python)", + "data": "é", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\w matches everything but ascii letters", + "schema": { + "type": "string", + "pattern": "^\\W$" + }, + "tests": [ + { + "description": "ASCII 'a' does not match", + "data": "a", + "valid": false + }, + { + "description": "latin-1 e-acute matches (unlike e.g. Python)", + "data": "é", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\s matches ascii whitespace only", + "schema": { + "type": "string", + "pattern": "^\\s$" + }, + "tests": [ + { + "description": "ASCII space matches", + "data": " ", + "valid": true + }, + { + "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "data": "\\u00a0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\S matches everything but ascii whitespace", + "schema": { + "type": "string", + "pattern": "^\\S$" + }, + "tests": [ + { + "description": "ASCII space does not match", + "data": " ", + "valid": false + }, + { + "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "data": "\\u00a0", + "valid": true + } + ] } ] diff --git a/tests/draft2019-09/uniqueItems.json b/tests/draft2019-09/uniqueItems.json index 8885ed00..d312ad71 100644 --- a/tests/draft2019-09/uniqueItems.json +++ b/tests/draft2019-09/uniqueItems.json @@ -85,5 +85,89 @@ "valid": false } ] + }, + { + "description": "uniqueItems with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is not valid", + "data": [false, true, "foo", "foo"], + "valid": false + }, + { + "description": "non-unique array extended from [true, false] is not valid", + "data": [true, false, "foo", "foo"], + "valid": false + } + ] + }, + { + "description": "uniqueItems with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] } ] diff --git a/tests/draft3/uniqueItems.json b/tests/draft3/uniqueItems.json index c1f4ab99..59e3542c 100644 --- a/tests/draft3/uniqueItems.json +++ b/tests/draft3/uniqueItems.json @@ -75,5 +75,89 @@ "valid": false } ] + }, + { + "description": "uniqueItems with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is not valid", + "data": [false, true, "foo", "foo"], + "valid": false + }, + { + "description": "non-unique array extended from [true, false] is not valid", + "data": [true, false, "foo", "foo"], + "valid": false + } + ] + }, + { + "description": "uniqueItems with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] } ] diff --git a/tests/draft4/optional/ecmascript-regex.json b/tests/draft4/optional/ecmascript-regex.json index 08dc9360..81643f8c 100644 --- a/tests/draft4/optional/ecmascript-regex.json +++ b/tests/draft4/optional/ecmascript-regex.json @@ -9,5 +9,186 @@ "valid": false } ] + }, + { + "description": "ECMA 262 regex converts \\a to ascii BEL", + "schema": { + "type": "string", + "pattern": "^\\a$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\a", + "valid": false + }, + { + "description": "matches", + "data": "\u0007", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and upper letter", + "schema": { + "type": "string", + "pattern": "^\\cC$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cC", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and lower letter", + "schema": { + "type": "string", + "pattern": "^\\cc$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cc", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\d matches ascii digits only", + "schema": { + "type": "string", + "pattern": "^\\d$" + }, + "tests": [ + { + "description": "ASCII zero matches", + "data": "0", + "valid": true + }, + { + "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", + "data": "߀", + "valid": false + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) does not match", + "data": "\\u07c0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\D matches everything but ascii digits", + "schema": { + "type": "string", + "pattern": "^\\D$" + }, + "tests": [ + { + "description": "ASCII zero does not match", + "data": "0", + "valid": false + }, + { + "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", + "data": "߀", + "valid": true + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) matches", + "data": "\\u07c0", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\w matches ascii letters only", + "schema": { + "type": "string", + "pattern": "^\\w$" + }, + "tests": [ + { + "description": "ASCII 'a' matches", + "data": "a", + "valid": true + }, + { + "description": "latin-1 e-acute does not match (unlike e.g. Python)", + "data": "é", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\w matches everything but ascii letters", + "schema": { + "type": "string", + "pattern": "^\\W$" + }, + "tests": [ + { + "description": "ASCII 'a' does not match", + "data": "a", + "valid": false + }, + { + "description": "latin-1 e-acute matches (unlike e.g. Python)", + "data": "é", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\s matches ascii whitespace only", + "schema": { + "type": "string", + "pattern": "^\\s$" + }, + "tests": [ + { + "description": "ASCII space matches", + "data": " ", + "valid": true + }, + { + "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "data": "\\u00a0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\S matches everything but ascii whitespace", + "schema": { + "type": "string", + "pattern": "^\\S$" + }, + "tests": [ + { + "description": "ASCII space does not match", + "data": " ", + "valid": false + }, + { + "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "data": "\\u00a0", + "valid": true + } + ] } ] diff --git a/tests/draft4/uniqueItems.json b/tests/draft4/uniqueItems.json index 8885ed00..d312ad71 100644 --- a/tests/draft4/uniqueItems.json +++ b/tests/draft4/uniqueItems.json @@ -85,5 +85,89 @@ "valid": false } ] + }, + { + "description": "uniqueItems with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is not valid", + "data": [false, true, "foo", "foo"], + "valid": false + }, + { + "description": "non-unique array extended from [true, false] is not valid", + "data": [true, false, "foo", "foo"], + "valid": false + } + ] + }, + { + "description": "uniqueItems with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] } ] diff --git a/tests/draft6/optional/ecmascript-regex.json b/tests/draft6/optional/ecmascript-regex.json index 08dc9360..81643f8c 100644 --- a/tests/draft6/optional/ecmascript-regex.json +++ b/tests/draft6/optional/ecmascript-regex.json @@ -9,5 +9,186 @@ "valid": false } ] + }, + { + "description": "ECMA 262 regex converts \\a to ascii BEL", + "schema": { + "type": "string", + "pattern": "^\\a$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\a", + "valid": false + }, + { + "description": "matches", + "data": "\u0007", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and upper letter", + "schema": { + "type": "string", + "pattern": "^\\cC$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cC", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and lower letter", + "schema": { + "type": "string", + "pattern": "^\\cc$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cc", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\d matches ascii digits only", + "schema": { + "type": "string", + "pattern": "^\\d$" + }, + "tests": [ + { + "description": "ASCII zero matches", + "data": "0", + "valid": true + }, + { + "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", + "data": "߀", + "valid": false + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) does not match", + "data": "\\u07c0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\D matches everything but ascii digits", + "schema": { + "type": "string", + "pattern": "^\\D$" + }, + "tests": [ + { + "description": "ASCII zero does not match", + "data": "0", + "valid": false + }, + { + "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", + "data": "߀", + "valid": true + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) matches", + "data": "\\u07c0", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\w matches ascii letters only", + "schema": { + "type": "string", + "pattern": "^\\w$" + }, + "tests": [ + { + "description": "ASCII 'a' matches", + "data": "a", + "valid": true + }, + { + "description": "latin-1 e-acute does not match (unlike e.g. Python)", + "data": "é", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\w matches everything but ascii letters", + "schema": { + "type": "string", + "pattern": "^\\W$" + }, + "tests": [ + { + "description": "ASCII 'a' does not match", + "data": "a", + "valid": false + }, + { + "description": "latin-1 e-acute matches (unlike e.g. Python)", + "data": "é", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\s matches ascii whitespace only", + "schema": { + "type": "string", + "pattern": "^\\s$" + }, + "tests": [ + { + "description": "ASCII space matches", + "data": " ", + "valid": true + }, + { + "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "data": "\\u00a0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\S matches everything but ascii whitespace", + "schema": { + "type": "string", + "pattern": "^\\S$" + }, + "tests": [ + { + "description": "ASCII space does not match", + "data": " ", + "valid": false + }, + { + "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "data": "\\u00a0", + "valid": true + } + ] } ] diff --git a/tests/draft6/uniqueItems.json b/tests/draft6/uniqueItems.json index 8885ed00..d312ad71 100644 --- a/tests/draft6/uniqueItems.json +++ b/tests/draft6/uniqueItems.json @@ -85,5 +85,89 @@ "valid": false } ] + }, + { + "description": "uniqueItems with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is not valid", + "data": [false, true, "foo", "foo"], + "valid": false + }, + { + "description": "non-unique array extended from [true, false] is not valid", + "data": [true, false, "foo", "foo"], + "valid": false + } + ] + }, + { + "description": "uniqueItems with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] } ] diff --git a/tests/draft7/optional/ecmascript-regex.json b/tests/draft7/optional/ecmascript-regex.json index 08dc9360..81643f8c 100644 --- a/tests/draft7/optional/ecmascript-regex.json +++ b/tests/draft7/optional/ecmascript-regex.json @@ -9,5 +9,186 @@ "valid": false } ] + }, + { + "description": "ECMA 262 regex converts \\a to ascii BEL", + "schema": { + "type": "string", + "pattern": "^\\a$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\a", + "valid": false + }, + { + "description": "matches", + "data": "\u0007", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and upper letter", + "schema": { + "type": "string", + "pattern": "^\\cC$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cC", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and lower letter", + "schema": { + "type": "string", + "pattern": "^\\cc$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cc", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\d matches ascii digits only", + "schema": { + "type": "string", + "pattern": "^\\d$" + }, + "tests": [ + { + "description": "ASCII zero matches", + "data": "0", + "valid": true + }, + { + "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", + "data": "߀", + "valid": false + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) does not match", + "data": "\\u07c0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\D matches everything but ascii digits", + "schema": { + "type": "string", + "pattern": "^\\D$" + }, + "tests": [ + { + "description": "ASCII zero does not match", + "data": "0", + "valid": false + }, + { + "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", + "data": "߀", + "valid": true + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) matches", + "data": "\\u07c0", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\w matches ascii letters only", + "schema": { + "type": "string", + "pattern": "^\\w$" + }, + "tests": [ + { + "description": "ASCII 'a' matches", + "data": "a", + "valid": true + }, + { + "description": "latin-1 e-acute does not match (unlike e.g. Python)", + "data": "é", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\w matches everything but ascii letters", + "schema": { + "type": "string", + "pattern": "^\\W$" + }, + "tests": [ + { + "description": "ASCII 'a' does not match", + "data": "a", + "valid": false + }, + { + "description": "latin-1 e-acute matches (unlike e.g. Python)", + "data": "é", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\s matches ascii whitespace only", + "schema": { + "type": "string", + "pattern": "^\\s$" + }, + "tests": [ + { + "description": "ASCII space matches", + "data": " ", + "valid": true + }, + { + "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "data": "\\u00a0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\S matches everything but ascii whitespace", + "schema": { + "type": "string", + "pattern": "^\\S$" + }, + "tests": [ + { + "description": "ASCII space does not match", + "data": " ", + "valid": false + }, + { + "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "data": "\\u00a0", + "valid": true + } + ] } ] diff --git a/tests/draft7/uniqueItems.json b/tests/draft7/uniqueItems.json index 8885ed00..d0a94d8c 100644 --- a/tests/draft7/uniqueItems.json +++ b/tests/draft7/uniqueItems.json @@ -85,5 +85,89 @@ "valid": false } ] + }, + { + "description": "uniqueItems with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is not valid", + "data": [false, true, "foo", "foo"], + "valid": false + }, + { + "description": "non-unique array extended from [true, false] is not valid", + "data": [true, false, "foo", "foo"], + "valid": false + } + ] + }, + { + "description": "uniqueItems with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] } ] diff --git a/tox.ini b/tox.ini index 5301222a..9c4e9499 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,9 @@ [tox] minversion = 1.6 -envlist = py27 +envlist = sanity skipsdist = True -[testenv] +[testenv:sanity] +# used just for validating the structure of the test case files themselves deps = jsonschema commands = {envpython} bin/jsonschema_suite check -- GitLab From e62b64b3433d05bceb4a2059c2a13067040826bf Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 4 Oct 2019 10:22:30 -0400 Subject: [PATCH 49/97] Squashed 'json/' changes from 586515ef..2d554504 2d554504 Merge pull request #284 from Zac-HD/newlines c8f87892 Add trailine-newline tests for $ pattern git-subtree-dir: json git-subtree-split: 2d554504e53e40ce9438411787d698916f35de8e --- .../optional/ecmascript-regex.json | 19 +++++++++++++++++++ tests/draft4/optional/ecmascript-regex.json | 19 +++++++++++++++++++ tests/draft6/optional/ecmascript-regex.json | 19 +++++++++++++++++++ tests/draft7/optional/ecmascript-regex.json | 19 +++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/tests/draft2019-09/optional/ecmascript-regex.json b/tests/draft2019-09/optional/ecmascript-regex.json index 81643f8c..7a0cb77e 100644 --- a/tests/draft2019-09/optional/ecmascript-regex.json +++ b/tests/draft2019-09/optional/ecmascript-regex.json @@ -10,6 +10,25 @@ } ] }, + { + "description": "ECMA 262 regex $ does not match trailing newline", + "schema": { + "type": "string", + "pattern": "^abc$" + }, + "tests": [ + { + "description": "matches in Python, but should not in jsonschema", + "data": "abc\n", + "valid": false + }, + { + "description": "should match", + "data": "abc", + "valid": true + } + ] + }, { "description": "ECMA 262 regex converts \\a to ascii BEL", "schema": { diff --git a/tests/draft4/optional/ecmascript-regex.json b/tests/draft4/optional/ecmascript-regex.json index 81643f8c..7a0cb77e 100644 --- a/tests/draft4/optional/ecmascript-regex.json +++ b/tests/draft4/optional/ecmascript-regex.json @@ -10,6 +10,25 @@ } ] }, + { + "description": "ECMA 262 regex $ does not match trailing newline", + "schema": { + "type": "string", + "pattern": "^abc$" + }, + "tests": [ + { + "description": "matches in Python, but should not in jsonschema", + "data": "abc\n", + "valid": false + }, + { + "description": "should match", + "data": "abc", + "valid": true + } + ] + }, { "description": "ECMA 262 regex converts \\a to ascii BEL", "schema": { diff --git a/tests/draft6/optional/ecmascript-regex.json b/tests/draft6/optional/ecmascript-regex.json index 81643f8c..7a0cb77e 100644 --- a/tests/draft6/optional/ecmascript-regex.json +++ b/tests/draft6/optional/ecmascript-regex.json @@ -10,6 +10,25 @@ } ] }, + { + "description": "ECMA 262 regex $ does not match trailing newline", + "schema": { + "type": "string", + "pattern": "^abc$" + }, + "tests": [ + { + "description": "matches in Python, but should not in jsonschema", + "data": "abc\n", + "valid": false + }, + { + "description": "should match", + "data": "abc", + "valid": true + } + ] + }, { "description": "ECMA 262 regex converts \\a to ascii BEL", "schema": { diff --git a/tests/draft7/optional/ecmascript-regex.json b/tests/draft7/optional/ecmascript-regex.json index 81643f8c..7a0cb77e 100644 --- a/tests/draft7/optional/ecmascript-regex.json +++ b/tests/draft7/optional/ecmascript-regex.json @@ -10,6 +10,25 @@ } ] }, + { + "description": "ECMA 262 regex $ does not match trailing newline", + "schema": { + "type": "string", + "pattern": "^abc$" + }, + "tests": [ + { + "description": "matches in Python, but should not in jsonschema", + "data": "abc\n", + "valid": false + }, + { + "description": "should match", + "data": "abc", + "valid": true + } + ] + }, { "description": "ECMA 262 regex converts \\a to ascii BEL", "schema": { -- GitLab From dc8da1a292e0a481665aee94869da05ddc9c4d31 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 4 Oct 2019 14:03:43 -0400 Subject: [PATCH 50/97] Shhhhhhh --- tox.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tox.ini b/tox.ini index e604dd7d..20dc0ba5 100644 --- a/tox.ini +++ b/tox.ini @@ -100,7 +100,7 @@ commands = basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' html +commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' html deps = -r{toxinidir}/docs/requirements.txt {toxinidir} @@ -118,7 +118,7 @@ deps = basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' doctest +commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' doctest deps = -r{toxinidir}/docs/requirements.txt {toxinidir} @@ -127,7 +127,7 @@ deps = basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' linkcheck +commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' linkcheck deps = -r{toxinidir}/docs/requirements.txt {toxinidir} @@ -136,7 +136,7 @@ deps = basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -T -W {posargs}' spelling +commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' spelling deps = -r{toxinidir}/docs/requirements.txt {toxinidir} -- GitLab From 1d7661a29a19fc928dcce31c7fe1efb9cf4c7c06 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 4 Oct 2019 14:08:50 -0400 Subject: [PATCH 51/97] Minor rename for consistency with other projects. --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 20dc0ba5..c82fd5c8 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ envlist = safety secrets style - docs-{html,doc8,doctest,linkcheck,spelling} + docs-{html,doctest,linkcheck,spelling,style} skipsdist = True [testenv] @@ -105,7 +105,7 @@ deps = -r{toxinidir}/docs/requirements.txt {toxinidir} -[testenv:docs-doc8] +[testenv:docs-style] basepython = pypy3 changedir = docs commands = doc8 {posargs} {toxinidir}/docs -- GitLab From 217d02744477ac7d9c71dede16a0a4f614561665 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 4 Oct 2019 14:10:41 -0400 Subject: [PATCH 52/97] Add a bandit env, but don't run it by default. It's a bit noisy, but potentially useful too. --- tox.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tox.ini b/tox.ini index c82fd5c8..82fbd011 100644 --- a/tox.ini +++ b/tox.ini @@ -58,6 +58,10 @@ deps = coverage,codecov: coverage codecov: codecov +[testenv:bandit] +deps = bandit +commands = {envbindir}/bandit --recursive {toxinidir}/jsonschema + [testenv:demo] deps = jupyter commands = -- GitLab From 3f1e286230508f335debca1c4c818ef53ac2e5a9 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 4 Oct 2019 14:14:07 -0400 Subject: [PATCH 53/97] Use sphinx build via -m rather than make. Gives it at least a shot at working on Windows. --- tox.ini | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tox.ini b/tox.ini index 82fbd011..f3b00f98 100644 --- a/tox.ini +++ b/tox.ini @@ -104,25 +104,16 @@ commands = basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' html +commands = {envpython} -m sphinx -b html {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt {toxinidir} -[testenv:docs-style] -basepython = pypy3 -changedir = docs -commands = doc8 {posargs} {toxinidir}/docs -deps = - doc8 - pygments - pygments-github-lexers - [testenv:docs-doctest] basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' doctest +commands = {envpython} -m sphinx -b doctest {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt {toxinidir} @@ -131,7 +122,7 @@ deps = basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' linkcheck +commands = {envpython} -m sphinx -b linkcheck {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt {toxinidir} @@ -140,11 +131,20 @@ deps = basepython = pypy3 changedir = docs whitelist_externals = make -commands = make -f {toxinidir}/docs/Makefile BUILDDIR={envtmpdir}/build SPHINXOPTS='-a -c {toxinidir}/docs/ -n -q -T -W {posargs}' spelling +commands = {envpython} -m sphinx -b spelling {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt {toxinidir} +[testenv:docs-style] +basepython = pypy3 +changedir = docs +commands = doc8 {posargs} {toxinidir}/docs +deps = + doc8 + pygments + pygments-github-lexers + [doc8] ignore-path = version.txt, -- GitLab From 28c762a4caa2d050b1e6daa83d99b567fbdf07d8 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 4 Oct 2019 15:45:13 -0400 Subject: [PATCH 54/97] Go away. --- tox.ini | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tox.ini b/tox.ini index f3b00f98..9612e3d5 100644 --- a/tox.ini +++ b/tox.ini @@ -145,12 +145,6 @@ deps = pygments pygments-github-lexers -[doc8] -ignore-path = - version.txt, - .*/, - _*/ - [testenv:codecov] passenv = CODECOV* CI TRAVIS TRAVIS_* setenv = {[testenv:coverage]setenv} -- GitLab From 0cb551ab5fe6001134a9aa0baf73e890f4d9b7e3 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 5 Oct 2019 08:41:17 -0400 Subject: [PATCH 55/97] Oh right that's why it was inconsistently named. Because travis will run docs-style under pypy too because it matches 'style'. I can't even... --- tox.ini | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 9612e3d5..a33bd7f3 100644 --- a/tox.ini +++ b/tox.ini @@ -84,6 +84,7 @@ deps = detect-secrets commands = {envbindir}/detect-secrets scan {toxinidir} [testenv:style] +basepython = pypy3 deps = ebb-lint>=0.19.1.0 commands = @@ -156,5 +157,5 @@ commands = [travis] python = - pypy: pypy, readme, safety, secrets, style - pypy3: pypy3, demo, docs + pypy: pypy, readme, safety, secrets + pypy3: pypy3, demo, docs, style -- GitLab From 51fc2f7a90ea8609090ddfd2a45ca4724e594462 Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Fri, 4 Oct 2019 11:50:48 +1000 Subject: [PATCH 56/97] Use JS regex syntax Note that js_regex.compile has a cache, just like re.compile, so calling it in loops does a lot of dict lookups but very little work. --- jsonschema/_utils.py | 7 ++++--- jsonschema/_validators.py | 6 +++--- jsonschema/tests/test_jsonschema_test_suite.py | 3 +++ jsonschema/tests/test_validators.py | 6 +++--- setup.cfg | 1 + 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index ceb88019..161f4a36 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -1,7 +1,8 @@ import itertools import json import pkgutil -import re + +import js_regex from jsonschema.compat import MutableMapping, str_types, urlsplit @@ -92,10 +93,10 @@ def find_additional_properties(instance, schema): """ properties = schema.get("properties", {}) - patterns = "|".join(schema.get("patternProperties", {})) + patterns = "|".join(sorted(schema.get("patternProperties", {}))) for property in instance: if property not in properties: - if patterns and re.search(patterns, property): + if patterns and js_regex.compile(patterns).search(property): continue yield property diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index 179fec09..39ff9058 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -1,4 +1,4 @@ -import re +import js_regex from jsonschema._utils import ( ensure_list, @@ -19,7 +19,7 @@ def patternProperties(validator, patternProperties, instance, schema): for pattern, subschema in iteritems(patternProperties): for k, v in iteritems(instance): - if re.search(pattern, k): + if js_regex.compile(pattern).search(k): for error in validator.descend( v, subschema, path=k, schema_path=pattern, ): @@ -197,7 +197,7 @@ def uniqueItems(validator, uI, instance, schema): def pattern(validator, patrn, instance, schema): if ( validator.is_type(instance, "string") and - not re.search(patrn, instance) + not js_regex.compile(patrn).search(instance) ): yield ValidationError("%r does not match %r" % (instance, patrn)) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 45d7c96e..5dbe49df 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -90,6 +90,7 @@ TestDraft4 = DRAFT4.to_unittest_testcase( DRAFT4.optional_tests_of(name="format"), DRAFT4.optional_tests_of(name="bignum"), DRAFT4.optional_tests_of(name="zeroTerminatedFloats"), + DRAFT4.optional_tests_of(name="ecmascript-regex"), Validator=Draft4Validator, format_checker=draft4_format_checker, skip=lambda test: ( @@ -138,6 +139,7 @@ TestDraft6 = DRAFT6.to_unittest_testcase( DRAFT6.optional_tests_of(name="format"), DRAFT6.optional_tests_of(name="bignum"), DRAFT6.optional_tests_of(name="zeroTerminatedFloats"), + DRAFT4.optional_tests_of(name="ecmascript-regex"), Validator=Draft6Validator, format_checker=draft6_format_checker, skip=lambda test: ( @@ -187,6 +189,7 @@ TestDraft7 = DRAFT7.to_unittest_testcase( DRAFT7.optional_tests_of(name="bignum"), DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), DRAFT7.optional_tests_of(name="content"), + DRAFT4.optional_tests_of(name="ecmascript-regex"), Validator=Draft7Validator, format_checker=draft7_format_checker, skip=lambda test: ( diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 3d6816db..cc326319 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -849,7 +849,7 @@ class TestValidationErrorDetails(TestCase): "children": { "type": "object", "patternProperties": { - "^.*$": { + u"^.*$": { "$ref": "#/definitions/node", }, }, @@ -951,8 +951,8 @@ class TestValidationErrorDetails(TestCase): instance = {"bar": 1, "foo": 2} schema = { "patternProperties": { - "bar": {"type": "string"}, - "foo": {"minimum": 5}, + u"bar": {"type": "string"}, + u"foo": {"minimum": 5}, }, } diff --git a/setup.cfg b/setup.cfg index d811ef9e..13448834 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,6 +28,7 @@ setup_requires = setuptools_scm install_requires = attrs>=17.4.0 importlib_metadata + js-regex>=1.0.0 pyrsistent>=0.14.0 setuptools six>=1.11.0 -- GitLab From 034886ff37fd51a094eece68b617622152d32a78 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 7 Oct 2019 07:59:49 -0400 Subject: [PATCH 57/97] Use the corresponding tests. --- jsonschema/tests/test_jsonschema_test_suite.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 5dbe49df..26a9fd9c 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -139,7 +139,7 @@ TestDraft6 = DRAFT6.to_unittest_testcase( DRAFT6.optional_tests_of(name="format"), DRAFT6.optional_tests_of(name="bignum"), DRAFT6.optional_tests_of(name="zeroTerminatedFloats"), - DRAFT4.optional_tests_of(name="ecmascript-regex"), + DRAFT6.optional_tests_of(name="ecmascript-regex"), Validator=Draft6Validator, format_checker=draft6_format_checker, skip=lambda test: ( @@ -189,7 +189,7 @@ TestDraft7 = DRAFT7.to_unittest_testcase( DRAFT7.optional_tests_of(name="bignum"), DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), DRAFT7.optional_tests_of(name="content"), - DRAFT4.optional_tests_of(name="ecmascript-regex"), + DRAFT7.optional_tests_of(name="ecmascript-regex"), Validator=Draft7Validator, format_checker=draft7_format_checker, skip=lambda test: ( -- GitLab From 572e563cdacebfd6c3a8619470b10d34f923ec34 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 7 Oct 2019 07:59:57 -0400 Subject: [PATCH 58/97] Minor style. --- jsonschema/tests/test_jsonschema_test_suite.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 26a9fd9c..3d766728 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -68,8 +68,8 @@ else: TestDraft3 = DRAFT3.to_unittest_testcase( DRAFT3.tests(), - DRAFT3.optional_tests_of(name="format"), DRAFT3.optional_tests_of(name="bignum"), + DRAFT3.optional_tests_of(name="format"), DRAFT3.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft3Validator, format_checker=draft3_format_checker, @@ -87,10 +87,10 @@ TestDraft3 = DRAFT3.to_unittest_testcase( TestDraft4 = DRAFT4.to_unittest_testcase( DRAFT4.tests(), - DRAFT4.optional_tests_of(name="format"), DRAFT4.optional_tests_of(name="bignum"), - DRAFT4.optional_tests_of(name="zeroTerminatedFloats"), DRAFT4.optional_tests_of(name="ecmascript-regex"), + DRAFT4.optional_tests_of(name="format"), + DRAFT4.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft4Validator, format_checker=draft4_format_checker, skip=lambda test: ( @@ -136,10 +136,10 @@ TestDraft4 = DRAFT4.to_unittest_testcase( TestDraft6 = DRAFT6.to_unittest_testcase( DRAFT6.tests(), - DRAFT6.optional_tests_of(name="format"), DRAFT6.optional_tests_of(name="bignum"), - DRAFT6.optional_tests_of(name="zeroTerminatedFloats"), DRAFT6.optional_tests_of(name="ecmascript-regex"), + DRAFT6.optional_tests_of(name="format"), + DRAFT6.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft6Validator, format_checker=draft6_format_checker, skip=lambda test: ( @@ -187,9 +187,9 @@ TestDraft7 = DRAFT7.to_unittest_testcase( DRAFT7.tests(), DRAFT7.format_tests(), DRAFT7.optional_tests_of(name="bignum"), - DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), DRAFT7.optional_tests_of(name="content"), DRAFT7.optional_tests_of(name="ecmascript-regex"), + DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft7Validator, format_checker=draft7_format_checker, skip=lambda test: ( -- GitLab From cdee16959760fe0cd599074cb5d7199eb6ef0d54 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 7 Oct 2019 08:00:00 -0400 Subject: [PATCH 59/97] Squashed 'json/' changes from 2d554504..433ab2f0 433ab2f0 Merge pull request #286 from Zac-HD/not-patterns dbaa3aac Fix data - escape unicode, not regex pattern git-subtree-dir: json git-subtree-split: 433ab2f0fd6b981527e838cd149c91d823bdc367 --- tests/draft2019-09/optional/ecmascript-regex.json | 8 ++++---- tests/draft4/optional/ecmascript-regex.json | 8 ++++---- tests/draft6/optional/ecmascript-regex.json | 8 ++++---- tests/draft7/optional/ecmascript-regex.json | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/draft2019-09/optional/ecmascript-regex.json b/tests/draft2019-09/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft2019-09/optional/ecmascript-regex.json +++ b/tests/draft2019-09/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] diff --git a/tests/draft4/optional/ecmascript-regex.json b/tests/draft4/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft4/optional/ecmascript-regex.json +++ b/tests/draft4/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] diff --git a/tests/draft6/optional/ecmascript-regex.json b/tests/draft6/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft6/optional/ecmascript-regex.json +++ b/tests/draft6/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] diff --git a/tests/draft7/optional/ecmascript-regex.json b/tests/draft7/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft7/optional/ecmascript-regex.json +++ b/tests/draft7/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] -- GitLab From b3f0aad72611c4d518477125bd31d028fa3015d5 Mon Sep 17 00:00:00 2001 From: Zac-HD Date: Mon, 7 Oct 2019 23:31:25 +1100 Subject: [PATCH 60/97] Validate `format: regex` with js-regex --- jsonschema/_format.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jsonschema/_format.py b/jsonschema/_format.py index aa040902..2f4721ff 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -3,6 +3,8 @@ import re import socket import struct +import js_regex + from jsonschema.compat import str_types from jsonschema.exceptions import FormatError @@ -297,11 +299,11 @@ else: return is_datetime("1970-01-01T" + instance) -@_checks_drafts(name="regex", raises=re.error) +@_checks_drafts(name="regex", raises=(re.error, js_regex.NotJavascriptRegex)) def is_regex(instance): if not isinstance(instance, str_types): return True - return re.compile(instance) + return js_regex.compile(instance) @_checks_drafts(draft3="date", draft7="date", raises=ValueError) -- GitLab From 8012a786ff8ab4f57c8e128f458c4061540f1983 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 7 Oct 2019 16:36:14 -0400 Subject: [PATCH 61/97] Squashed 'json/' changes from 2d554504..4e6c78b4 4e6c78b4 Make the draft3 ECMA regex tests consistently named. 433ab2f0 Merge pull request #286 from Zac-HD/not-patterns dbaa3aac Fix data - escape unicode, not regex pattern git-subtree-dir: json git-subtree-split: 4e6c78b4d878aa427d7b41e7b65cde0ea6f503ea --- tests/draft2019-09/optional/ecmascript-regex.json | 8 ++++---- .../optional/{jsregex.json => ecmascript-regex.json} | 0 tests/draft4/optional/ecmascript-regex.json | 8 ++++---- tests/draft6/optional/ecmascript-regex.json | 8 ++++---- tests/draft7/optional/ecmascript-regex.json | 8 ++++---- 5 files changed, 16 insertions(+), 16 deletions(-) rename tests/draft3/optional/{jsregex.json => ecmascript-regex.json} (100%) diff --git a/tests/draft2019-09/optional/ecmascript-regex.json b/tests/draft2019-09/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft2019-09/optional/ecmascript-regex.json +++ b/tests/draft2019-09/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] diff --git a/tests/draft3/optional/jsregex.json b/tests/draft3/optional/ecmascript-regex.json similarity index 100% rename from tests/draft3/optional/jsregex.json rename to tests/draft3/optional/ecmascript-regex.json diff --git a/tests/draft4/optional/ecmascript-regex.json b/tests/draft4/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft4/optional/ecmascript-regex.json +++ b/tests/draft4/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] diff --git a/tests/draft6/optional/ecmascript-regex.json b/tests/draft6/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft6/optional/ecmascript-regex.json +++ b/tests/draft6/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] diff --git a/tests/draft7/optional/ecmascript-regex.json b/tests/draft7/optional/ecmascript-regex.json index 7a0cb77e..d82e0feb 100644 --- a/tests/draft7/optional/ecmascript-regex.json +++ b/tests/draft7/optional/ecmascript-regex.json @@ -105,7 +105,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", - "data": "\\u07c0", + "data": "\u07c0", "valid": false } ] @@ -129,7 +129,7 @@ }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", - "data": "\\u07c0", + "data": "\u07c0", "valid": true } ] @@ -186,7 +186,7 @@ }, { "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": false } ] @@ -205,7 +205,7 @@ }, { "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", - "data": "\\u00a0", + "data": "\u00a0", "valid": true } ] -- GitLab From 00ee84bec4264852fd8c291a178dcfc8883c61cb Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 7 Oct 2019 20:37:49 -0400 Subject: [PATCH 62/97] Add a version specifically for the role, and declare we're safe in parallel. --- docs/jsonschema_role.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/jsonschema_role.py b/docs/jsonschema_role.py index 637a71c7..a3e7a071 100644 --- a/docs/jsonschema_role.py +++ b/docs/jsonschema_role.py @@ -12,6 +12,7 @@ import certifi from lxml import html +__version__ = "1.0.0" VALIDATION_SPEC = "https://json-schema.org/draft-04/json-schema-validation.html" @@ -38,6 +39,8 @@ def setup(app): spec = fetch_or_load(path) app.add_role("validator", docutils_sucks(spec)) + return dict(version=__version__, parallel_read_safe=True) + def fetch_or_load(spec_path): """ -- GitLab From 2c4390a1ddbc35e445003f3f8df93aefa2dd4e82 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 7 Oct 2019 21:41:15 -0400 Subject: [PATCH 63/97] Update the docs to point to draft 7 in the Sphinx role. --- docs/jsonschema_role.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/jsonschema_role.py b/docs/jsonschema_role.py index a3e7a071..6f61cdb8 100644 --- a/docs/jsonschema_role.py +++ b/docs/jsonschema_role.py @@ -13,7 +13,7 @@ from lxml import html __version__ = "1.0.0" -VALIDATION_SPEC = "https://json-schema.org/draft-04/json-schema-validation.html" +VALIDATION_SPEC = "https://json-schema.org/draft-07/json-schema-validation.html" def setup(app): @@ -85,8 +85,8 @@ def docutils_sucks(spec): """ base_url = VALIDATION_SPEC - ref_url = "https://json-schema.org/draft-04/json-schema-core.html#rfc.section.4.1" - schema_url = "https://json-schema.org/draft-04/json-schema-core.html#rfc.section.6" + ref_url = "https://json-schema.org/draft-07/json-schema-core.html#rfc.section.8.3" + schema_url = "https://json-schema.org/draft-07/json-schema-core.html#rfc.section.7" def validator(name, raw_text, text, lineno, inliner): """ -- GitLab From 077feca5c176dd740b30d3f1084b6622076129e7 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 9 Oct 2019 11:06:09 -0400 Subject: [PATCH 64/97] Changelog bump. --- CHANGELOG.rst | 6 ++++++ README.rst | 11 ++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1a77a1e8..3c99c366 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,9 @@ +v3.1.0 +------ + +* Regular expressions throughout schemas now respect the ECMA 262 dialect, as + recommended by the specification (#609). + v3.0.2 ------ diff --git a/README.rst b/README.rst index dd033c5a..dbbbae74 100644 --- a/README.rst +++ b/README.rst @@ -109,13 +109,10 @@ Online demo Notebook will look similar to this: Release Notes ------------- -Version 3.0 brings support for Draft 7 (and 6). The interface for redefining -types has also been majorly overhauled to support easier redefinition of the -types a Validator will accept or allow. - -jsonschema is also now tested under Windows via AppVeyor. - -Thanks to all who contributed pull requests along the way. +v3.1 brings support for ECMA 262 dialect regexes throughout schemas, as +recommended by the specification. Big thanks to @Zac-HD for authoring +support in a new `js-regex `_ +library. Running the Test Suite -- GitLab From 4d9764e8cf13218695aca72e6dd77cfa03b68643 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 9 Oct 2019 11:56:54 -0400 Subject: [PATCH 65/97] No need for make now. --- tox.ini | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tox.ini b/tox.ini index a33bd7f3..9bd232ac 100644 --- a/tox.ini +++ b/tox.ini @@ -104,7 +104,6 @@ commands = [testenv:docs-html] basepython = pypy3 changedir = docs -whitelist_externals = make commands = {envpython} -m sphinx -b html {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt @@ -113,7 +112,6 @@ deps = [testenv:docs-doctest] basepython = pypy3 changedir = docs -whitelist_externals = make commands = {envpython} -m sphinx -b doctest {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt @@ -122,7 +120,6 @@ deps = [testenv:docs-linkcheck] basepython = pypy3 changedir = docs -whitelist_externals = make commands = {envpython} -m sphinx -b linkcheck {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt @@ -131,7 +128,6 @@ deps = [testenv:docs-spelling] basepython = pypy3 changedir = docs -whitelist_externals = make commands = {envpython} -m sphinx -b spelling {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt -- GitLab From b5ed4ef0232ca8a8d240bcd63765de0ced6ab1d5 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 9 Oct 2019 11:59:33 -0400 Subject: [PATCH 66/97] Spelling. Also ugh. -q for spelling hides the actual misspelled words. Will need to fix that at some point. --- README.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index dbbbae74..422e04d2 100644 --- a/README.rst +++ b/README.rst @@ -109,10 +109,15 @@ Online demo Notebook will look similar to this: Release Notes ------------- -v3.1 brings support for ECMA 262 dialect regexes throughout schemas, as -recommended by the specification. Big thanks to @Zac-HD for authoring -support in a new `js-regex `_ -library. +v3.1 brings support for ECMA 262 dialect regular expressions +throughout schemas, as recommended by the specification. Big +thanks to @Zac-HD for authoring support in a new `js-regex +`_ library. + +.. spelling:: + + Zac + HD Running the Test Suite -- GitLab From ccdeeb3be39022e7f007a28402a04ba0f028a542 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 9 Oct 2019 13:00:52 -0400 Subject: [PATCH 67/97] Sigh. reST tools fight, go! --- README.rst | 5 ----- docs/spelling-wordlist.txt | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 422e04d2..f8d8e67b 100644 --- a/README.rst +++ b/README.rst @@ -114,11 +114,6 @@ throughout schemas, as recommended by the specification. Big thanks to @Zac-HD for authoring support in a new `js-regex `_ library. -.. spelling:: - - Zac - HD - Running the Test Suite ---------------------- diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt index f1aaef4b..63fa2200 100644 --- a/docs/spelling-wordlist.txt +++ b/docs/spelling-wordlist.txt @@ -34,5 +34,8 @@ validators versioned schemas +Zac +HD + Berman Freenode -- GitLab From 7ee391c6f94cd43e57806c41340515b5e866727f Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 9 Oct 2019 15:10:02 -0400 Subject: [PATCH 68/97] Revert "Respect ECMA regex syntax for schemas." This reverts commit 1a02f547fda27f2b267fcbd03711fe36e50b7026, reversing changes made to cbb222c145b71abb51e743ad48083c8ba5fa0cdb. --- jsonschema/_format.py | 6 ++---- jsonschema/_utils.py | 7 +++---- jsonschema/_validators.py | 6 +++--- jsonschema/tests/test_jsonschema_test_suite.py | 11 ++++------- jsonschema/tests/test_validators.py | 6 +++--- setup.cfg | 1 - 6 files changed, 15 insertions(+), 22 deletions(-) diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 2f4721ff..aa040902 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -3,8 +3,6 @@ import re import socket import struct -import js_regex - from jsonschema.compat import str_types from jsonschema.exceptions import FormatError @@ -299,11 +297,11 @@ else: return is_datetime("1970-01-01T" + instance) -@_checks_drafts(name="regex", raises=(re.error, js_regex.NotJavascriptRegex)) +@_checks_drafts(name="regex", raises=re.error) def is_regex(instance): if not isinstance(instance, str_types): return True - return js_regex.compile(instance) + return re.compile(instance) @_checks_drafts(draft3="date", draft7="date", raises=ValueError) diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 161f4a36..ceb88019 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -1,8 +1,7 @@ import itertools import json import pkgutil - -import js_regex +import re from jsonschema.compat import MutableMapping, str_types, urlsplit @@ -93,10 +92,10 @@ def find_additional_properties(instance, schema): """ properties = schema.get("properties", {}) - patterns = "|".join(sorted(schema.get("patternProperties", {}))) + patterns = "|".join(schema.get("patternProperties", {})) for property in instance: if property not in properties: - if patterns and js_regex.compile(patterns).search(property): + if patterns and re.search(patterns, property): continue yield property diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index 39ff9058..179fec09 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -1,4 +1,4 @@ -import js_regex +import re from jsonschema._utils import ( ensure_list, @@ -19,7 +19,7 @@ def patternProperties(validator, patternProperties, instance, schema): for pattern, subschema in iteritems(patternProperties): for k, v in iteritems(instance): - if js_regex.compile(pattern).search(k): + if re.search(pattern, k): for error in validator.descend( v, subschema, path=k, schema_path=pattern, ): @@ -197,7 +197,7 @@ def uniqueItems(validator, uI, instance, schema): def pattern(validator, patrn, instance, schema): if ( validator.is_type(instance, "string") and - not js_regex.compile(patrn).search(instance) + not re.search(patrn, instance) ): yield ValidationError("%r does not match %r" % (instance, patrn)) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 3d766728..45d7c96e 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -68,8 +68,8 @@ else: TestDraft3 = DRAFT3.to_unittest_testcase( DRAFT3.tests(), - DRAFT3.optional_tests_of(name="bignum"), DRAFT3.optional_tests_of(name="format"), + DRAFT3.optional_tests_of(name="bignum"), DRAFT3.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft3Validator, format_checker=draft3_format_checker, @@ -87,9 +87,8 @@ TestDraft3 = DRAFT3.to_unittest_testcase( TestDraft4 = DRAFT4.to_unittest_testcase( DRAFT4.tests(), - DRAFT4.optional_tests_of(name="bignum"), - DRAFT4.optional_tests_of(name="ecmascript-regex"), DRAFT4.optional_tests_of(name="format"), + DRAFT4.optional_tests_of(name="bignum"), DRAFT4.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft4Validator, format_checker=draft4_format_checker, @@ -136,9 +135,8 @@ TestDraft4 = DRAFT4.to_unittest_testcase( TestDraft6 = DRAFT6.to_unittest_testcase( DRAFT6.tests(), - DRAFT6.optional_tests_of(name="bignum"), - DRAFT6.optional_tests_of(name="ecmascript-regex"), DRAFT6.optional_tests_of(name="format"), + DRAFT6.optional_tests_of(name="bignum"), DRAFT6.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft6Validator, format_checker=draft6_format_checker, @@ -187,9 +185,8 @@ 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="ecmascript-regex"), DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), + DRAFT7.optional_tests_of(name="content"), Validator=Draft7Validator, format_checker=draft7_format_checker, skip=lambda test: ( diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index cc326319..3d6816db 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -849,7 +849,7 @@ class TestValidationErrorDetails(TestCase): "children": { "type": "object", "patternProperties": { - u"^.*$": { + "^.*$": { "$ref": "#/definitions/node", }, }, @@ -951,8 +951,8 @@ class TestValidationErrorDetails(TestCase): instance = {"bar": 1, "foo": 2} schema = { "patternProperties": { - u"bar": {"type": "string"}, - u"foo": {"minimum": 5}, + "bar": {"type": "string"}, + "foo": {"minimum": 5}, }, } diff --git a/setup.cfg b/setup.cfg index 13448834..d811ef9e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,7 +28,6 @@ setup_requires = setuptools_scm install_requires = attrs>=17.4.0 importlib_metadata - js-regex>=1.0.0 pyrsistent>=0.14.0 setuptools six>=1.11.0 -- GitLab From 204c0c6df35c9ba51aeba03e384435014204ba3d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 11 Oct 2019 19:07:35 -0400 Subject: [PATCH 69/97] Add an explicit test for #611. --- jsonschema/tests/test_validators.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 3d6816db..07be4f08 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -1182,6 +1182,12 @@ class ValidatorTestMixin(MetaSchemaTestsMixin, object): def test_string_a_bytestring_is_a_string(self): self.Validator({"type": "string"}).validate(b"foo") + def test_patterns_can_be_native_strings(self): + """ + See https://github.com/Julian/jsonschema/issues/611. + """ + self.Validator({"pattern": "foo"}).validate("foo") + def test_it_can_validate_with_decimals(self): schema = {"items": {"type": "number"}} Validator = validators.extend( -- GitLab From a40ce64825a231211f831dcd90ae626562f592dd Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 14 Oct 2019 15:48:11 -0400 Subject: [PATCH 70/97] Squashed 'json/' changes from 4e6c78b4..689d2f28 689d2f28 Add a 'latest' symlink. e26d9bce Move the anchor-related tests to an anchor file. 19e7dfe9 Change location-independent IDs to use $anchor. git-subtree-dir: json git-subtree-split: 689d2f28182720d3778ca91c149f725a6ce73f71 --- tests/draft2019-09/anchor.json | 87 ++++++++++++++++++++++++++++++++++ tests/draft2019-09/ref.json | 84 -------------------------------- tests/latest | 1 + 3 files changed, 88 insertions(+), 84 deletions(-) create mode 100644 tests/draft2019-09/anchor.json create mode 120000 tests/latest diff --git a/tests/draft2019-09/anchor.json b/tests/draft2019-09/anchor.json new file mode 100644 index 00000000..06b0ba4d --- /dev/null +++ b/tests/draft2019-09/anchor.json @@ -0,0 +1,87 @@ +[ + { + "description": "Location-independent identifier", + "schema": { + "allOf": [{ + "$ref": "#foo" + }], + "$defs": { + "A": { + "$anchor": "foo", + "type": "integer" + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "Location-independent identifier with absolute URI", + "schema": { + "allOf": [{ + "$ref": "http://localhost:1234/bar#foo" + }], + "$defs": { + "A": { + "$id": "http://localhost:1234/bar", + "$anchor": "foo", + "type": "integer" + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "Location-independent identifier with base URI change in subschema", + "schema": { + "$id": "http://localhost:1234/root", + "allOf": [{ + "$ref": "http://localhost:1234/nested.json#foo" + }], + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$anchor": "foo", + "type": "integer" + } + } + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + } +] diff --git a/tests/draft2019-09/ref.json b/tests/draft2019-09/ref.json index d872426f..285de55c 100644 --- a/tests/draft2019-09/ref.json +++ b/tests/draft2019-09/ref.json @@ -355,89 +355,5 @@ "valid": false } ] - }, - { - "description": "Location-independent identifier", - "schema": { - "allOf": [{ - "$ref": "#foo" - }], - "$defs": { - "A": { - "$id": "#foo", - "type": "integer" - } - } - }, - "tests": [ - { - "data": 1, - "description": "match", - "valid": true - }, - { - "data": "a", - "description": "mismatch", - "valid": false - } - ] - }, - { - "description": "Location-independent identifier with absolute URI", - "schema": { - "allOf": [{ - "$ref": "http://localhost:1234/bar#foo" - }], - "$defs": { - "A": { - "$id": "http://localhost:1234/bar#foo", - "type": "integer" - } - } - }, - "tests": [ - { - "data": 1, - "description": "match", - "valid": true - }, - { - "data": "a", - "description": "mismatch", - "valid": false - } - ] - }, - { - "description": "Location-independent identifier with base URI change in subschema", - "schema": { - "$id": "http://localhost:1234/root", - "allOf": [{ - "$ref": "http://localhost:1234/nested.json#foo" - }], - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#foo", - "type": "integer" - } - } - } - } - }, - "tests": [ - { - "data": 1, - "description": "match", - "valid": true - }, - { - "data": "a", - "description": "mismatch", - "valid": false - } - ] } ] diff --git a/tests/latest b/tests/latest new file mode 120000 index 00000000..90f70dba --- /dev/null +++ b/tests/latest @@ -0,0 +1 @@ +draft2019-09 \ No newline at end of file -- GitLab From d7aa9ef44706c9b7fd479018e6a5c0682de9f0e0 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 17 Oct 2019 09:22:30 -0400 Subject: [PATCH 71/97] Minor style. --- jsonschema/tests/test_jsonschema_test_suite.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 45d7c96e..ebccf297 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -68,8 +68,8 @@ else: TestDraft3 = DRAFT3.to_unittest_testcase( DRAFT3.tests(), - DRAFT3.optional_tests_of(name="format"), DRAFT3.optional_tests_of(name="bignum"), + DRAFT3.optional_tests_of(name="format"), DRAFT3.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft3Validator, format_checker=draft3_format_checker, @@ -87,8 +87,8 @@ TestDraft3 = DRAFT3.to_unittest_testcase( TestDraft4 = DRAFT4.to_unittest_testcase( DRAFT4.tests(), - DRAFT4.optional_tests_of(name="format"), DRAFT4.optional_tests_of(name="bignum"), + DRAFT4.optional_tests_of(name="format"), DRAFT4.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft4Validator, format_checker=draft4_format_checker, @@ -135,8 +135,8 @@ TestDraft4 = DRAFT4.to_unittest_testcase( TestDraft6 = DRAFT6.to_unittest_testcase( DRAFT6.tests(), - DRAFT6.optional_tests_of(name="format"), DRAFT6.optional_tests_of(name="bignum"), + DRAFT6.optional_tests_of(name="format"), DRAFT6.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft6Validator, format_checker=draft6_format_checker, @@ -185,8 +185,8 @@ TestDraft7 = DRAFT7.to_unittest_testcase( DRAFT7.tests(), DRAFT7.format_tests(), DRAFT7.optional_tests_of(name="bignum"), - DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), DRAFT7.optional_tests_of(name="content"), + DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft7Validator, format_checker=draft7_format_checker, skip=lambda test: ( -- GitLab From 0d827f38bbfc5ae728e04aa8bd92e9ae0e9efa01 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 17 Oct 2019 18:28:25 -0400 Subject: [PATCH 72/97] Py38. --- .travis.yml | 1 + setup.cfg | 1 + tox.ini | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ede965b8..d31d77e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ python: - 3.5 - 3.6 - 3.7 + - 3.8 - pypy - pypy3 diff --git a/setup.cfg b/setup.cfg index d811ef9e..590229f2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,6 +19,7 @@ classifiers = Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy diff --git a/tox.ini b/tox.ini index 9bd232ac..8baf9702 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{35,36,37,py,py3}-{build,tests} + py{35,36,37,38,py,py3}-{build,tests} demo readme safety -- GitLab From 9835833e04d79f79fc88a0c1268b4fc4b5782204 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 19 Oct 2019 12:43:34 -0400 Subject: [PATCH 73/97] Travis: org -> com --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index f8d8e67b..ccfb55d0 100644 --- a/README.rst +++ b/README.rst @@ -12,9 +12,9 @@ jsonschema :alt: Supported Python versions :target: https://pypi.org/project/jsonschema/ -.. |Travis| image:: https://travis-ci.org/Julian/jsonschema.svg?branch=master +.. |Travis| image:: https://travis-ci.com/Julian/jsonschema.svg?branch=master :alt: Travis build status - :target: https://travis-ci.org/Julian/jsonschema + :target: https://travis-ci.com/Julian/jsonschema .. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/adtt0aiaihy6muyn/branch/master?svg=true :alt: AppVeyor build status -- GitLab From 6bf900261bb1e67f3ba0f3f0d1586bec12ee1942 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 19 Oct 2019 13:38:04 -0400 Subject: [PATCH 74/97] Codecov.io is super flaky. --- docs/conf.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 83499f00..1ec003ce 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,6 +4,7 @@ from textwrap import dedent import os +import re import sys import jsonschema @@ -238,6 +239,15 @@ texinfo_documents = [ # 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("codecov.io")] + # -- Options for sphinxcontrib-spelling ----------------------------------- spelling_word_list_filename = "spelling-wordlist.txt" -- GitLab From af37707780faf8793ba0734929d7d96f0d31ebee Mon Sep 17 00:00:00 2001 From: Nicolas Aimetti Date: Wed, 23 Oct 2019 11:12:41 -0300 Subject: [PATCH 75/97] non GPL format option --- jsonschema/_format.py | 47 +++++++---- jsonschema/_format_validators.py | 138 +++++++++++++++++++++++++++++++ setup.cfg | 4 + tox.ini | 7 +- 4 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 jsonschema/_format_validators.py diff --git a/jsonschema/_format.py b/jsonschema/_format.py index aa040902..67189f0f 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -248,7 +248,24 @@ else: try: import rfc3987 except ImportError: - pass + from jsonschema._format_validators import validate_rfc3986 + + @_checks_drafts(name="uri",) + def is_uri(instance): + if not isinstance(instance, str_types): + return True + return validate_rfc3986(instance, rule="URI") + + @_checks_drafts( + draft6="uri-reference", + draft7="uri-reference", + raises=ValueError, + ) + def is_uri_reference(instance): + if not isinstance(instance, str_types): + return True + return validate_rfc3986(instance, rule="URI_reference") + else: @_checks_drafts(draft7="iri", raises=ValueError) def is_iri(instance): @@ -280,21 +297,23 @@ else: try: - import strict_rfc3339 + from strict_rfc3339 import validate_rfc3339 except ImportError: - pass -else: - @_checks_drafts(name="date-time") - def is_datetime(instance): - if not isinstance(instance, str_types): - return True - return strict_rfc3339.validate_rfc3339(instance) + from jsonschema._format_validators import validate_rfc3339 - @_checks_drafts(draft7="time") - def is_time(instance): - if not isinstance(instance, str_types): - return True - return is_datetime("1970-01-01T" + instance) + +@_checks_drafts(name="date-time") +def is_datetime(instance): + if not isinstance(instance, str_types): + return True + return validate_rfc3339(instance) + + +@_checks_drafts(draft7="time") +def is_time(instance): + if not isinstance(instance, str_types): + return True + return is_datetime("1970-01-01T" + instance) @_checks_drafts(name="regex", raises=re.error) diff --git a/jsonschema/_format_validators.py b/jsonschema/_format_validators.py new file mode 100644 index 00000000..08d37f00 --- /dev/null +++ b/jsonschema/_format_validators.py @@ -0,0 +1,138 @@ +import re +import calendar +import six + +RFC3339_REGEX_FLAGS = 0 +if six.PY3: + RFC3339_REGEX_FLAGS |= re.ASCII + +RFC3339_REGEX = re.compile(r""" + ^ + (\d{4}) # Year + - + (0[1-9]|1[0-2]) # Month + - + (\d{2}) # Day + T + (?:[01]\d|2[0123]) # Hours + : + (?:[0-5]\d) # Minutes + : + (?:[0-5]\d) # Seconds + (?:\.\d+)? # Secfrac + (?: Z # UTC + | [+-](?:[01]\d|2[0123]):[0-5]\d # Offset + ) + $ +""", re.VERBOSE | RFC3339_REGEX_FLAGS) + + +def validate_rfc3339(date_string): + """ + Validates dates against RFC3339 datetime format + Leap seconds are no supported. + """ + m = RFC3339_REGEX.match(date_string) + if m is None: + return False + year, month, day = map(int, m.groups()) + if not year: + # Year 0 is not valid a valid date + return False + (_, max_day) = calendar.monthrange(year, month) + if not 1 <= day <= max_day: + return False + return True + + +# Following regex rules references the ABNF terminology from +# [RFC3986](https://tools.ietf.org/html/rfc3986#appendix-A) + +# IPv6 validation rule +IPv6_RE = ( + r"(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][" + r"0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1," + r"4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][" + r"0-9]?))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[" + r"0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1," + r"4}:)?[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][" + r"0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){," + r"2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][" + r"0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){," + r"3}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[" + r"01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1," + r"4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[" + r"0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[" + r"0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)" +) + + +# An authority is defined as: [ userinfo "@" ] host [ ":" port ] +AUTHORITY_RE = r""" + (?:(?:[a-zA-Z0-9_.~\-!$&'()*+,;=:]|%[0-9A-Fa-f]{{2}})*@)? # user info + (?: + \[(?:{ip_v6}|v[0-9A-Fa-f]+\.[a-zA-Z0-9_.~\-!$&'()*+,;=:]+)\] # IP-literal + | (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) # IPv4 + | (?:[a-zA-Z0-9_.~\-!$&'()*+,;=]|%[0-9A-Fa-f]{{2}})* # reg-name + ) # host + (?::[0-9]*)? # port +""".format(ip_v6=IPv6_RE,) +# Path char regex rule +PCHAR_RE = r"(?:[a-zA-Z0-9_.~\-!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})" +# Query and Fragment rules are exactly the same +QUERY_RE = r"(?:[a-zA-Z0-9_.~\-!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*" +# An URI is defined as: scheme ":" hier-part [ "?" query ] [ "#" fragment ] +URI_RE = r""" + [a-zA-Z][a-zA-Z0-9+.-]* #scheme + : + (?: + // + {authority} + (?:/{pchar}*)* # path-abempty + | /(?:{pchar}+ (?:/{pchar}*)*)? # path-absolute + | {pchar}+ (?:/{pchar}*)* # path-rootless + | # or nothing + ) # hier-part + (?:\?{query})? # Query + (?:\#{fragment})? # Fragment +""".format( + authority=AUTHORITY_RE, + query=QUERY_RE, + fragment=QUERY_RE, + pchar=PCHAR_RE +) + +# A relative-ref is defined as: relative-part [ "?" query ] [ "#" fragment ] +RELATIVE_REF_RE = r""" + (?: + // + {authority} + (?:/{pchar}*)* # path-abempty + | /(?:{pchar}+ (?:/{pchar}*)*)? # path-absolute + | (?:[a-zA-Z0-9_.~\-!$&'()*+,;=@]|%[0-9A-Fa-f]{{2}})+ (?:/{pchar}*)* # path-noscheme + | # or nothing + ) # relative-part + (?:\?{query})? # Query + (?:\#{fragment})? # Fragment +""".format( + authority=AUTHORITY_RE, + query=QUERY_RE, + fragment=QUERY_RE, + pchar=PCHAR_RE +) +# Compiled URI regex rule +URI_RE_COMP = re.compile(r"^{uri_re}$".format(uri_re=URI_RE), re.VERBOSE) +# Compiled URI-reference regex rule. URI-reference is defined as: URI / relative-ref +URI_REF_RE_COMP = re.compile(r"^(?:{uri_re}|{relative_ref})$".format( + uri_re=URI_RE, + relative_ref=RELATIVE_REF_RE, +), re.VERBOSE) + + +def validate_rfc3986(url, rule='URI'): + if rule == 'URI': + return URI_RE_COMP.match(url) + elif rule == 'URI_reference': + return URI_REF_RE_COMP.match(url) + else: + raise ValueError('Invalid rule') diff --git a/setup.cfg b/setup.cfg index d811ef9e..9eb09c22 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,10 @@ format = rfc3987 strict-rfc3339 webcolors +format_nongpl = + idna + jsonpointer>1.13 + webcolors [options.entry_points] console_scripts = diff --git a/tox.ini b/tox.ini index 9bd232ac..c4136f17 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{35,36,37,py,py3}-{build,tests} + py{35,36,37,py,py3}-{build,tests,tests_nongpl}, demo readme safety @@ -22,8 +22,9 @@ whitelist_externals = virtualenv commands = perf,tests: {envbindir}/python -m pip install '{toxinidir}[format]' + tests_nongpl: {envbindir}/python -m pip install '{toxinidir}[format_nongpl]' - tests: {envbindir}/trial {posargs:jsonschema} + tests,tests_nongpl: {envbindir}/trial {posargs:jsonschema} tests: {envpython} -m doctest {toxinidir}/README.rst perf: mkdir {envtmpdir}/benchmarks/ @@ -53,7 +54,7 @@ deps = perf: pyperf - tests,coverage,codecov: -r{toxinidir}/test-requirements.txt + tests,tests_nongpl,coverage,codecov: -r{toxinidir}/test-requirements.txt coverage,codecov: coverage codecov: codecov -- GitLab From 10f8a3e525f63f10555aeccd06e5d978e8a6958f Mon Sep 17 00:00:00 2001 From: Nicolas Aimetti Date: Mon, 28 Oct 2019 16:57:50 -0300 Subject: [PATCH 76/97] Add format validators as separate modules --- jsonschema/_format.py | 66 ++++++++------- jsonschema/_format_validators.py | 138 ------------------------------- setup.cfg | 2 + 3 files changed, 38 insertions(+), 168 deletions(-) delete mode 100644 jsonschema/_format_validators.py diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 67189f0f..9a194123 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -248,23 +248,27 @@ else: try: import rfc3987 except ImportError: - from jsonschema._format_validators import validate_rfc3986 - @_checks_drafts(name="uri",) - def is_uri(instance): - if not isinstance(instance, str_types): - return True - return validate_rfc3986(instance, rule="URI") - - @_checks_drafts( - draft6="uri-reference", - draft7="uri-reference", - raises=ValueError, - ) - def is_uri_reference(instance): - if not isinstance(instance, str_types): - return True - return validate_rfc3986(instance, rule="URI_reference") + try: + from rfc3986_validator import validate_rfc3986 + except ImportError: + pass + else: + @_checks_drafts(name="uri",) + def is_uri(instance): + if not isinstance(instance, str_types): + return True + return validate_rfc3986(instance, rule="URI") + + @_checks_drafts( + draft6="uri-reference", + draft7="uri-reference", + raises=ValueError, + ) + def is_uri_reference(instance): + if not isinstance(instance, str_types): + return True + return validate_rfc3986(instance, rule="URI_reference") else: @_checks_drafts(draft7="iri", raises=ValueError) @@ -299,21 +303,23 @@ else: try: from strict_rfc3339 import validate_rfc3339 except ImportError: - from jsonschema._format_validators import validate_rfc3339 - - -@_checks_drafts(name="date-time") -def is_datetime(instance): - if not isinstance(instance, str_types): - return True - return validate_rfc3339(instance) - + try: + from rfc3339_validator import validate_rfc3339 + except ImportError: + validate_rfc3339 = None + +if validate_rfc3339: + @_checks_drafts(name="date-time") + def is_datetime(instance): + if not isinstance(instance, str_types): + return True + return validate_rfc3339(instance) -@_checks_drafts(draft7="time") -def is_time(instance): - if not isinstance(instance, str_types): - return True - return is_datetime("1970-01-01T" + instance) + @_checks_drafts(draft7="time") + def is_time(instance): + if not isinstance(instance, str_types): + return True + return is_datetime("1970-01-01T" + instance) @_checks_drafts(name="regex", raises=re.error) diff --git a/jsonschema/_format_validators.py b/jsonschema/_format_validators.py deleted file mode 100644 index 08d37f00..00000000 --- a/jsonschema/_format_validators.py +++ /dev/null @@ -1,138 +0,0 @@ -import re -import calendar -import six - -RFC3339_REGEX_FLAGS = 0 -if six.PY3: - RFC3339_REGEX_FLAGS |= re.ASCII - -RFC3339_REGEX = re.compile(r""" - ^ - (\d{4}) # Year - - - (0[1-9]|1[0-2]) # Month - - - (\d{2}) # Day - T - (?:[01]\d|2[0123]) # Hours - : - (?:[0-5]\d) # Minutes - : - (?:[0-5]\d) # Seconds - (?:\.\d+)? # Secfrac - (?: Z # UTC - | [+-](?:[01]\d|2[0123]):[0-5]\d # Offset - ) - $ -""", re.VERBOSE | RFC3339_REGEX_FLAGS) - - -def validate_rfc3339(date_string): - """ - Validates dates against RFC3339 datetime format - Leap seconds are no supported. - """ - m = RFC3339_REGEX.match(date_string) - if m is None: - return False - year, month, day = map(int, m.groups()) - if not year: - # Year 0 is not valid a valid date - return False - (_, max_day) = calendar.monthrange(year, month) - if not 1 <= day <= max_day: - return False - return True - - -# Following regex rules references the ABNF terminology from -# [RFC3986](https://tools.ietf.org/html/rfc3986#appendix-A) - -# IPv6 validation rule -IPv6_RE = ( - r"(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][" - r"0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1," - r"4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][" - r"0-9]?))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[" - r"0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1," - r"4}:)?[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][" - r"0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){," - r"2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][" - r"0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){," - r"3}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[" - r"01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1," - r"4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[" - r"0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[" - r"0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)" -) - - -# An authority is defined as: [ userinfo "@" ] host [ ":" port ] -AUTHORITY_RE = r""" - (?:(?:[a-zA-Z0-9_.~\-!$&'()*+,;=:]|%[0-9A-Fa-f]{{2}})*@)? # user info - (?: - \[(?:{ip_v6}|v[0-9A-Fa-f]+\.[a-zA-Z0-9_.~\-!$&'()*+,;=:]+)\] # IP-literal - | (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) # IPv4 - | (?:[a-zA-Z0-9_.~\-!$&'()*+,;=]|%[0-9A-Fa-f]{{2}})* # reg-name - ) # host - (?::[0-9]*)? # port -""".format(ip_v6=IPv6_RE,) -# Path char regex rule -PCHAR_RE = r"(?:[a-zA-Z0-9_.~\-!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})" -# Query and Fragment rules are exactly the same -QUERY_RE = r"(?:[a-zA-Z0-9_.~\-!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*" -# An URI is defined as: scheme ":" hier-part [ "?" query ] [ "#" fragment ] -URI_RE = r""" - [a-zA-Z][a-zA-Z0-9+.-]* #scheme - : - (?: - // - {authority} - (?:/{pchar}*)* # path-abempty - | /(?:{pchar}+ (?:/{pchar}*)*)? # path-absolute - | {pchar}+ (?:/{pchar}*)* # path-rootless - | # or nothing - ) # hier-part - (?:\?{query})? # Query - (?:\#{fragment})? # Fragment -""".format( - authority=AUTHORITY_RE, - query=QUERY_RE, - fragment=QUERY_RE, - pchar=PCHAR_RE -) - -# A relative-ref is defined as: relative-part [ "?" query ] [ "#" fragment ] -RELATIVE_REF_RE = r""" - (?: - // - {authority} - (?:/{pchar}*)* # path-abempty - | /(?:{pchar}+ (?:/{pchar}*)*)? # path-absolute - | (?:[a-zA-Z0-9_.~\-!$&'()*+,;=@]|%[0-9A-Fa-f]{{2}})+ (?:/{pchar}*)* # path-noscheme - | # or nothing - ) # relative-part - (?:\?{query})? # Query - (?:\#{fragment})? # Fragment -""".format( - authority=AUTHORITY_RE, - query=QUERY_RE, - fragment=QUERY_RE, - pchar=PCHAR_RE -) -# Compiled URI regex rule -URI_RE_COMP = re.compile(r"^{uri_re}$".format(uri_re=URI_RE), re.VERBOSE) -# Compiled URI-reference regex rule. URI-reference is defined as: URI / relative-ref -URI_REF_RE_COMP = re.compile(r"^(?:{uri_re}|{relative_ref})$".format( - uri_re=URI_RE, - relative_ref=RELATIVE_REF_RE, -), re.VERBOSE) - - -def validate_rfc3986(url, rule='URI'): - if rule == 'URI': - return URI_RE_COMP.match(url) - elif rule == 'URI_reference': - return URI_REF_RE_COMP.match(url) - else: - raise ValueError('Invalid rule') diff --git a/setup.cfg b/setup.cfg index 9eb09c22..f3260236 100644 --- a/setup.cfg +++ b/setup.cfg @@ -44,6 +44,8 @@ format_nongpl = idna jsonpointer>1.13 webcolors + rfc3986-validator>0.1.0 + rfc3339-validator [options.entry_points] console_scripts = -- GitLab From 7ecdbcdc0ab86539065b2b9cc47008da4c8b9d2b Mon Sep 17 00:00:00 2001 From: Nicolas Aimetti Date: Thu, 31 Oct 2019 19:26:41 -0300 Subject: [PATCH 77/97] format_nongpl docs, and style fixes --- docs/spelling-wordlist.txt | 1 + docs/validate.rst | 29 +++++++++++++++++++++-------- jsonschema/_format.py | 3 +-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt index 63fa2200..496c56e1 100644 --- a/docs/spelling-wordlist.txt +++ b/docs/spelling-wordlist.txt @@ -39,3 +39,4 @@ HD Berman Freenode +GPL diff --git a/docs/validate.rst b/docs/validate.rst index 5a4448dd..8b159626 100644 --- a/docs/validate.rst +++ b/docs/validate.rst @@ -321,14 +321,26 @@ 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`` setuptools extra -- i.e. +``format`` or ``format_nongpl`` setuptools extra -- i.e. .. code-block:: sh $ pip install jsonschema[format] -which will install all of the below dependencies for all formats. The -more specific list of available checkers, along with their requirement +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:: @@ -342,7 +354,7 @@ Checker Notes ========================= ==================== ``color`` requires webcolors_ ``date`` -``date-time`` requires strict-rfc3339_ +``date-time`` requires strict-rfc3339_ or rfc3339-validator_ ``email`` ``hostname`` ``idn-hostname`` requires idna_ @@ -353,9 +365,9 @@ Checker Notes ``json-pointer`` requires jsonpointer_ ``regex`` ``relative-json-pointer`` requires jsonpointer_ -``time`` requires strict-rfc3339_ -``uri`` requires rfc3987_ -``uri-reference`` requires rfc3987_ +``time`` requires strict-rfc3339_ or rfc3339-validator_ +``uri`` requires rfc3987_ or rfc3986-validator_ +``uri-reference`` requires rfc3987_ or rfc3986-validator_ ========================= ==================== @@ -365,7 +377,8 @@ Checker Notes .. _rfc5322: https://tools.ietf.org/html/rfc5322#section-3.4.1 .. _strict-rfc3339: https://pypi.org/pypi/strict-rfc3339/ .. _webcolors: https://pypi.org/pypi/webcolors/ - +.. _rfc3339-validator: https://pypi.org/project/rfc3339-validator/ +.. _rfc3986-validator: https://pypi.org/project/rfc3986-validator/ .. note:: diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 9a194123..281a7cfc 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -248,13 +248,12 @@ else: try: import rfc3987 except ImportError: - try: from rfc3986_validator import validate_rfc3986 except ImportError: pass else: - @_checks_drafts(name="uri",) + @_checks_drafts(name="uri") def is_uri(instance): if not isinstance(instance, str_types): return True -- GitLab From e892d49fef170975489129db31d6e6cd6c2530a2 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 3 Nov 2019 15:58:41 -0500 Subject: [PATCH 78/97] Add a link to GitHub sponsors and Patreon. --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 1e3d93df..fc40c007 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,5 @@ # These are supported funding model platforms +github: "Julian" +patreon: "JulianWasTaken" tidelift: "pypi/jsonschema" -- GitLab From fe1c4dd1ed3285f39b3f971834bb04cffde9a3dd Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 3 Nov 2019 18:50:58 -0500 Subject: [PATCH 79/97] Shouldn't need to chdir for docs anymore. --- tox.ini | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tox.ini b/tox.ini index 8baf9702..d29f8e1b 100644 --- a/tox.ini +++ b/tox.ini @@ -103,7 +103,6 @@ commands = [testenv:docs-html] basepython = pypy3 -changedir = docs commands = {envpython} -m sphinx -b html {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt @@ -111,7 +110,6 @@ deps = [testenv:docs-doctest] basepython = pypy3 -changedir = docs commands = {envpython} -m sphinx -b doctest {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt @@ -119,7 +117,6 @@ deps = [testenv:docs-linkcheck] basepython = pypy3 -changedir = docs commands = {envpython} -m sphinx -b linkcheck {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt @@ -127,7 +124,6 @@ deps = [testenv:docs-spelling] basepython = pypy3 -changedir = docs commands = {envpython} -m sphinx -b spelling {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt @@ -135,7 +131,6 @@ deps = [testenv:docs-style] basepython = pypy3 -changedir = docs commands = doc8 {posargs} {toxinidir}/docs deps = doc8 -- GitLab From 5ca2fff768daf32e1eee211474f19177f1b023a9 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 7 Nov 2019 20:27:25 -0500 Subject: [PATCH 80/97] Bump doc requirements (via pip-compile) --- docs/requirements.in | 3 +++ docs/requirements.txt | 63 ++++++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 28 deletions(-) create mode 100644 docs/requirements.in diff --git a/docs/requirements.in b/docs/requirements.in new file mode 100644 index 00000000..0c4f8bca --- /dev/null +++ b/docs/requirements.in @@ -0,0 +1,3 @@ +lxml +sphinx +sphinxcontrib-spelling diff --git a/docs/requirements.txt b/docs/requirements.txt index 357bdc93..fd569829 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,29 +1,36 @@ -alabaster==0.7.12 -attrs==19.1.0 -Babel==2.7.0 -certifi==2019.6.16 -chardet==3.0.4 -docutils==0.15.2 -greenlet==0.4.13 -idna==2.8 -imagesize==1.1.0 -Jinja2==2.10.1 -lxml==4.4.0 -MarkupSafe==1.1.1 -packaging==19.1 -pyenchant==2.0.0 -Pygments==2.4.2 -pyparsing==2.4.2 -pytz==2019.2 -requests==2.22.0 -six==1.12.0 -snowballstemmer==1.9.0 -Sphinx==2.1.2 -sphinxcontrib-applehelp==1.0.1 -sphinxcontrib-devhelp==1.0.1 -sphinxcontrib-htmlhelp==1.0.2 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.2 -sphinxcontrib-serializinghtml==1.1.3 +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile requirements.in +# +alabaster==0.7.12 # via sphinx +babel==2.7.0 # via sphinx +certifi==2019.9.11 # via requests +chardet==3.0.4 # via requests +docutils==0.15.2 # via sphinx +idna==2.8 # via requests +imagesize==1.1.0 # via sphinx +jinja2==2.10.3 # via sphinx +lxml==4.4.1 +markupsafe==1.1.1 # via jinja2 +packaging==19.2 # via sphinx +pyenchant==2.0.0 # via sphinxcontrib-spelling +pygments==2.4.2 # via sphinx +pyparsing==2.4.4 # via packaging +pytz==2019.3 # via babel +requests==2.22.0 # via sphinx +six==1.13.0 # via packaging, sphinxcontrib-spelling +snowballstemmer==2.0.0 # via sphinx +sphinx==2.2.1 +sphinxcontrib-applehelp==1.0.1 # via sphinx +sphinxcontrib-devhelp==1.0.1 # via sphinx +sphinxcontrib-htmlhelp==1.0.2 # via sphinx +sphinxcontrib-jsmath==1.0.1 # via sphinx +sphinxcontrib-qthelp==1.0.2 # via sphinx +sphinxcontrib-serializinghtml==1.1.3 # via sphinx sphinxcontrib-spelling==4.3.0 -urllib3==1.25.3 +urllib3==1.25.6 # via requests + +# The following packages are considered to be unsafe in a requirements file: +# setuptools==41.6.0 # via sphinx -- GitLab From e08fbd71d4682a3ff59ebdcfe302190b8f442224 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 10 Nov 2019 10:16:43 -0500 Subject: [PATCH 81/97] Release notes for 3.1.1. --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3c99c366..f5a9abc0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,9 @@ +v3.1.1 +------ + +* Temporarily revert the switch to ``js-regex`` until #611 and #612 are + resolved. + v3.1.0 ------ -- GitLab From fe772c380c48eb14fc47bbd0a0c95888b9ea700a Mon Sep 17 00:00:00 2001 From: Adam Dobrawy Date: Sun, 17 Nov 2019 05:40:10 +0100 Subject: [PATCH 82/97] Use importlib from std (if possible) --- jsonschema/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index f0bcd0d3..3d8f3696 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -27,6 +27,8 @@ from jsonschema.validators import ( RefResolver, validate, ) - -import importlib_metadata -__version__ = importlib_metadata.version("jsonschema") +try: + from importlib import metadata +except ImportError: # for Python<3.8 + import importlib_metadata as metdata +__version__ = metadata.version("jsonschema") -- GitLab From 63f8d2c6d2198d5fe33e35ec34a483c2bdf06c55 Mon Sep 17 00:00:00 2001 From: Adam Dobrawy Date: Sun, 17 Nov 2019 06:13:06 +0100 Subject: [PATCH 83/97] Fix typo of 'metdata' --- jsonschema/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index 3d8f3696..6b630cdf 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -30,5 +30,5 @@ from jsonschema.validators import ( try: from importlib import metadata except ImportError: # for Python<3.8 - import importlib_metadata as metdata + import importlib_metadata as metadata __version__ = metadata.version("jsonschema") -- GitLab From 0e6c684a51c5593087b8bb419d54f79db591e7d6 Mon Sep 17 00:00:00 2001 From: Adam Dobrawy Date: Sun, 17 Nov 2019 06:25:44 +0100 Subject: [PATCH 84/97] Skip dependency importlib_metadata on PY 3.8 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 89885d84..c8290bd8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,7 +28,7 @@ packages = find: setup_requires = setuptools_scm install_requires = attrs>=17.4.0 - importlib_metadata + importlib_metadata;python_version<'3.8' pyrsistent>=0.14.0 setuptools six>=1.11.0 -- GitLab From 99868e2394fd3245b200763e9f28043b6d59f051 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 17 Nov 2019 19:26:59 -0500 Subject: [PATCH 85/97] Add a disclosure policy. --- .github/SECURITY.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000..fd524e94 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,21 @@ +# 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. -- GitLab From 2f734a7ce1395ac4ff2d394583fd46a2e8833a9b Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 18 Nov 2019 07:36:14 -0500 Subject: [PATCH 86/97] Release notes for 3.2.0. --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f5a9abc0..8f0a2700 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,9 @@ +v3.2.0 +------ + +* Added a ``format_nongpl`` setuptools extra, which installs only ``format`` + dependencies that are non-GPL (#619). + v3.1.1 ------ -- GitLab From b05bd7ef455ce04dcaa42b4980cd67ea336de272 Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 09:20:32 +0200 Subject: [PATCH 87/97] Add me to d/copyright --- debian/copyright | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/copyright b/debian/copyright index 2d29d121..c3d1ed64 100644 --- a/debian/copyright +++ b/debian/copyright @@ -27,6 +27,7 @@ Files: debian/* Copyright: 2012 Chuck Short 2012, Ghe Rivero 2013, Thomas Goirand + 2020, Michal Arbet License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- GitLab From 472ec8ef0e082c2515d96de89cecf48fc612304b Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 09:21:15 +0200 Subject: [PATCH 88/97] Add me to uploaders, bump standards version --- debian/control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index cb75afec..acfa9d15 100644 --- a/debian/control +++ b/debian/control @@ -4,6 +4,7 @@ Priority: optional Maintainer: Debian OpenStack Uploaders: Thomas Goirand , + Michal Arbet , Build-Depends: autopkgtest, debhelper-compat (= 12), @@ -23,7 +24,7 @@ Build-Depends-Indep: python3-pytest, python3-six, python3-twisted, -Standards-Version: 4.4.1 +Standards-Version: 4.5.0 Vcs-Git: https://salsa.debian.org/openstack-team/third-party/python-jsonschema.git Vcs-Browser: https://salsa.debian.org/openstack-team/third-party/python-jsonschema Homepage: https://github.com/Julian/jsonschema -- GitLab From a47f7a00a79b38508b68fe288b1ed3e899343bf8 Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 09:25:39 +0200 Subject: [PATCH 89/97] Remove remove-TestBuiltinFormats-hack.patch --- .../remove-TestBuiltinFormats-hack.patch | 45 ------------------- debian/patches/series | 1 - 2 files changed, 46 deletions(-) delete mode 100644 debian/patches/remove-TestBuiltinFormats-hack.patch diff --git a/debian/patches/remove-TestBuiltinFormats-hack.patch b/debian/patches/remove-TestBuiltinFormats-hack.patch deleted file mode 100644 index e80bc01e..00000000 --- a/debian/patches/remove-TestBuiltinFormats-hack.patch +++ /dev/null @@ -1,45 +0,0 @@ -Description: Remove TestBuiltinFormats hack - What upstream does is a hack that has all the chances to fail. Let's remove - this test. -Author: Thomas Goirand -Forwarded: no -Last-Update: 2019-09-24 - ---- python-jsonschema-3.0.2.orig/jsonschema/tests/test_validators.py -+++ python-jsonschema-3.0.2/jsonschema/tests/test_validators.py -@@ -1348,35 +1348,6 @@ class TestDraft7Validator(ValidatorTestM - invalid = {"type": "integer"}, "foo" - - --class TestBuiltinFormats(TestCase): -- """ -- The built-in (specification-defined) formats do not raise type errors. -- -- If an instance or value is not a string, it should be ignored. -- """ -- -- # These tests belong upstream. -- # See https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/246 -- -- --for Validator, checker in ( -- (validators.Draft3Validator, jsonschema.draft3_format_checker), -- (validators.Draft4Validator, jsonschema.draft4_format_checker), -- (validators.Draft6Validator, jsonschema.draft6_format_checker), -- (validators.Draft7Validator, jsonschema.draft7_format_checker), --): -- for format in checker.checkers: -- def test(self, checker=checker, format=format): -- validator = Validator({"format": format}, format_checker=checker) -- validator.validate(123) -- -- name = "test_{}_{}_ignores_non_strings".format( -- Validator.__name__, format, -- ) -- test.__name__ = name -- setattr(TestBuiltinFormats, name, test) -- -- - class TestValidatorFor(SynchronousTestCase): - def test_draft_3(self): - schema = {"$schema": "http://json-schema.org/draft-03/schema"} diff --git a/debian/patches/series b/debian/patches/series index bc7a8047..363f3bfe 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1 @@ -remove-TestBuiltinFormats-hack.patch remove-sphinxcontrib.spelling-from-doc-conf.py.patch -- GitLab From 570553536319f3fae66aa383576d10c407c45b77 Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 10:04:05 +0200 Subject: [PATCH 90/97] Add fix-lintian-privacy-breach.patch --- .../patches/fix-lintian-privacy-breach.patch | 62 +++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 63 insertions(+) create mode 100644 debian/patches/fix-lintian-privacy-breach.patch diff --git a/debian/patches/fix-lintian-privacy-breach.patch b/debian/patches/fix-lintian-privacy-breach.patch new file mode 100644 index 00000000..16d46b51 --- /dev/null +++ b/debian/patches/fix-lintian-privacy-breach.patch @@ -0,0 +1,62 @@ +Description: Remove external sources from doc. +Author: Michal Arbet +Forwarded: not-needed +Last-Update: 2020-05-05 + +diff --git a/README.rst b/README.rst +index ccfb55d..3f7d111 100644 +--- a/README.rst ++++ b/README.rst +@@ -4,31 +4,6 @@ jsonschema + + |PyPI| |Pythons| |Travis| |AppVeyor| |Codecov| |ReadTheDocs| + +-.. |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/ +- +-.. |Travis| image:: https://travis-ci.com/Julian/jsonschema.svg?branch=master +- :alt: Travis build status +- :target: https://travis-ci.com/Julian/jsonschema +- +-.. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/adtt0aiaihy6muyn/branch/master?svg=true +- :alt: AppVeyor build status +- :target: https://ci.appveyor.com/project/Julian/jsonschema +- +-.. |Codecov| image:: https://codecov.io/gh/Julian/jsonschema/branch/master/graph/badge.svg +- :alt: Codecov Code coverage +- :target: https://codecov.io/gh/Julian/jsonschema +- +-.. |ReadTheDocs| image:: https://readthedocs.org/projects/python-jsonschema/badge/?version=stable&style=flat +- :alt: ReadTheDocs status +- :target: https://python-jsonschema.readthedocs.io/en/stable/ +- +- + ``jsonschema`` is an implementation of `JSON Schema `_ + for Python (supporting 2.7+ including Python 3). + +@@ -91,19 +66,7 @@ Installation + Demo + ---- + +-Try ``jsonschema`` interactively in this online demo: +- +-.. image:: https://user-images.githubusercontent.com/1155573/56745335-8b158a00-6750-11e9-8776-83fa675939c4.png +- :target: https://notebooks.ai/demo/gh/Julian/jsonschema +- :alt: Open Live Demo +- +- +-Online demo Notebook will look similar to this: +- +- +-.. image:: https://user-images.githubusercontent.com/1155573/56820861-5c1c1880-6823-11e9-802a-ce01c5ec574f.gif +- :alt: Open Live Demo +- :width: 480 px ++Try ``jsonschema`` interactively in this online `demo `_. + + + Release Notes diff --git a/debian/patches/series b/debian/patches/series index 363f3bfe..48b887b3 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1,2 @@ remove-sphinxcontrib.spelling-from-doc-conf.py.patch +fix-lintian-privacy-breach.patch -- GitLab From 743a90af8d33e0cc78980c62aa6e549e775d1dc0 Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 11:16:36 +0200 Subject: [PATCH 91/97] Add Breaks: python3-json-pointer (<< 1.14) --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index acfa9d15..de574272 100644 --- a/debian/control +++ b/debian/control @@ -56,6 +56,8 @@ Depends: ${python3:Depends}, Suggests: python-jsonschema-doc, +Breaks: + python3-json-pointer (<< 1.14), Description: An(other) implementation of JSON Schema (Draft 3 and 4) - Python 3.x JSON Schema is a specification for a JSON-based format for defining the structure of JSON data. JSON Schema provides a contract for what -- GitLab From 8f816d6eb29fd821eaab5d4af1b1928b26c44124 Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 09:22:52 +0200 Subject: [PATCH 92/97] Release to experimental --- debian/changelog | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/debian/changelog b/debian/changelog index 3b52a9f6..c8c85d6d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +python-jsonschema (3.2.0-1) experimental; urgency=medium + + * New upstream version + * d/copyright: Add me to copyright + * d/control: + - Add me to uploaders + - Bump standards to 4.5.0 + - Breaks: python3-json-pointer (<< 1.14) (Closes: #949723) + * d/patches: + - Remove remove-TestBuiltinFormats-hack.patch + - Add fix-lintian-privacy-breach.patch + + -- Michal Arbet Tue, 05 May 2020 09:21:24 +0200 + python-jsonschema (3.0.2-4) unstable; urgency=medium * Add missing dependencies for autopkgtests. -- GitLab From b91641dda6b7cf404dfc60ca5283e5946888f956 Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 11:39:15 +0200 Subject: [PATCH 93/97] Add python3-importlib-metadata dependency --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index de574272..29607bed 100644 --- a/debian/control +++ b/debian/control @@ -16,6 +16,7 @@ Build-Depends: python3-sphinx, Build-Depends-Indep: python3-attr, + python3-importlib-metadata, python3-lxml, python3-mock, python3-nose, @@ -49,6 +50,7 @@ Package: python3-jsonschema Architecture: all Depends: python3-attr, + python3-importlib-metadata, python3-pkg-resources, python3-setuptools, python3-six, -- GitLab From 96038570c76eb98bdde8ab771e83678bdd0b6d4c Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 5 May 2020 11:44:34 +0200 Subject: [PATCH 94/97] Release to experimental --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index c8c85d6d..cd6d1c64 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-jsonschema (3.2.0-2) experimental; urgency=medium + + * d/control: Add {build}dependency python3-importlib-metadata + + -- Michal Arbet Tue, 05 May 2020 11:43:45 +0200 + python-jsonschema (3.2.0-1) experimental; urgency=medium * New upstream version -- GitLab From 9fa3fe1666332bd13a03422289f46e3e37e6a21c Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Fri, 8 May 2020 11:04:41 +0200 Subject: [PATCH 95/97] Uploading to unstable. --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index cd6d1c64..e903c265 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-jsonschema (3.2.0-3) unstable; urgency=medium + + * Uploading to unstable. + + -- Thomas Goirand Fri, 08 May 2020 11:04:26 +0200 + python-jsonschema (3.2.0-2) experimental; urgency=medium * d/control: Add {build}dependency python3-importlib-metadata -- GitLab From e693ae33a5d03017c5c306b35697df72afc6b561 Mon Sep 17 00:00:00 2001 From: Debian Janitor Date: Sat, 27 Jun 2020 17:36:46 +0000 Subject: [PATCH 96/97] debian/copyright: use spaces rather than tabs to start continuation lines. Fixes: lintian: tab-in-license-text See-also: https://lintian.debian.org/tags/tab-in-license-text.html --- debian/changelog | 6 ++++++ debian/copyright | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index e903c265..dd668ea8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-jsonschema (3.2.0-4) UNRELEASED; urgency=low + + * debian/copyright: use spaces rather than tabs to start continuation lines. + + -- Debian Janitor Sat, 27 Jun 2020 17:36:29 -0000 + python-jsonschema (3.2.0-3) unstable; urgency=medium * Uploading to unstable. diff --git a/debian/copyright b/debian/copyright index c3d1ed64..cc035155 100644 --- a/debian/copyright +++ b/debian/copyright @@ -25,9 +25,9 @@ License: MIT Files: debian/* Copyright: 2012 Chuck Short - 2012, Ghe Rivero - 2013, Thomas Goirand - 2020, Michal Arbet + 2012, Ghe Rivero + 2013, Thomas Goirand + 2020, Michal Arbet License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- GitLab From 6112ad64140617bcd2384f45208609178aa6d49c Mon Sep 17 00:00:00 2001 From: Debian Janitor Date: Sat, 27 Jun 2020 17:37:29 +0000 Subject: [PATCH 97/97] Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, Repository-Browse. Fixes: lintian: upstream-metadata-file-is-missing See-also: https://lintian.debian.org/tags/upstream-metadata-file-is-missing.html Fixes: lintian: upstream-metadata-missing-bug-tracking See-also: https://lintian.debian.org/tags/upstream-metadata-missing-bug-tracking.html Fixes: lintian: upstream-metadata-missing-repository See-also: https://lintian.debian.org/tags/upstream-metadata-missing-repository.html --- debian/changelog | 2 ++ debian/upstream/metadata | 5 +++++ 2 files changed, 7 insertions(+) create mode 100644 debian/upstream/metadata diff --git a/debian/changelog b/debian/changelog index dd668ea8..a877d776 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,8 @@ python-jsonschema (3.2.0-4) UNRELEASED; urgency=low * debian/copyright: use spaces rather than tabs to start continuation lines. + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, + Repository-Browse. -- Debian Janitor Sat, 27 Jun 2020 17:36:29 -0000 diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 00000000..9060ad9f --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,5 @@ +--- +Bug-Database: https://github.com/Julian/jsonschema/issues +Bug-Submit: https://github.com/Julian/jsonschema/issues/new +Repository: https://github.com/Julian/jsonschema.git +Repository-Browse: https://github.com/Julian/jsonschema -- GitLab