diff options
author | Julian Berman <Julian@GrayVines.com> | 2020-10-15 10:04:18 -0400 |
---|---|---|
committer | Julian Berman <Julian@GrayVines.com> | 2020-10-15 10:04:18 -0400 |
commit | ffcbebd48424e275e77ed45651262c5ac53fd444 (patch) | |
tree | b16c22ad756908ef0762ea974128de59a94339bf | |
parent | 1bfbb9064c0c2da5df5ea0f7ed03623f8418f278 (diff) | |
parent | e48d56cbd2b6c25d4a9483f53f79ec537b9a4a34 (diff) | |
download | jsonschema-ffcbebd48424e275e77ed45651262c5ac53fd444.tar.gz |
Merge remote-tracking branch 'origin/master' into fix_issue669
* origin/master:
Handle multipleOf overflow
Don't fail when codecov.io flakes.
pep517.build is dead or dying.
Temporarily skip the failing tests for #743.
Sigh, ugly, but assrtRegexpMatches is deprecated.
Squashed 'json/' changes from 21555a85..96742ba3
Squashed 'json/' changes from fce9e9b3..21555a85
Whoops, send coverage to codecov again.
Be able to run coverage on all toxenvs.
Remove outdated release notes.
Use the longer form of the CLI option for clarity.
Bump doc requirements (via pip-compile)
Remove the Py2 coding declaration.
Run pre-commit in CI.
Remove docformatter, it's too unwieldy.
Minor doc formatting.
Sigh, this appears to be a regex, not exact match, so it was ignoring everything.
Update pre-commit hooks.
35 files changed, 311 insertions, 155 deletions
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b43b57a..101000f 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -20,6 +20,8 @@ jobs: - name: Install tox run: python -m pip install tox - name: Collect & Upload Coverage - run: python -m tox -e codecov + # codecov.io is too flaky to fail for this right now + continue-on-error: true + run: python -m tox -e pypy3-format-codecov env: CODECOV_TOKEN: 2b38dae1-41c4-4435-a29d-79a1299e5617 diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml index decf5f0..23178f7 100644 --- a/.github/workflows/packaging.yml +++ b/.github/workflows/packaging.yml @@ -20,12 +20,9 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install pep517 - - name: Evade 'pypa/pep517#74' - run: python -m pip install -U setuptools setuptools-scm pip wheel - if: startsWith(matrix.python-version, 'pypy') + run: python -m pip install build - name: Create packages - run: python -m pep517.build . + run: python -m build . - uses: actions/upload-artifact@master with: name: dist-${{ matrix.os }}-${{ matrix.python-version }} diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..306e1ad --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,13 @@ +name: pre-commit + +on: + pull_request: + push: + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + - uses: pre-commit/action@v2.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a1dc799..bd3e906 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: json +exclude: json/ repos: - repo: https://github.com/pre-commit/pre-commit-hooks @@ -14,14 +14,6 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/timothycrosley/isort - rev: 5.3.2 + rev: 5.4.2 hooks: - id: isort -- repo: https://github.com/myint/docformatter - rev: v1.3.1 - hooks: - - id: docformatter - args: - - --in-place - - --pre-summary-newline - - --make-summary-multi-line @@ -51,7 +51,7 @@ It can also be used from console: .. code-block:: bash - $ jsonschema -i sample.json sample.schema + $ jsonschema --instance sample.json sample.schema Features -------- @@ -80,15 +80,6 @@ Installation $ pip install jsonschema -Release Notes -------------- - -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 -<https://pypi.org/project/js-regex/>`_ library. - - Running the Test Suite ---------------------- diff --git a/docs/conf.py b/docs/conf.py index fbf6f30..73e0e1f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- -# -# This file is execfile()d with the current directory set to its containing dir. - from textwrap import dedent import os import re diff --git a/docs/requirements.txt b/docs/requirements.txt index 11fbfe7..2b75db0 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -6,31 +6,31 @@ # alabaster==0.7.12 # via sphinx babel==2.8.0 # via sphinx -certifi==2020.4.5.1 # via requests +certifi==2020.6.20 # via requests chardet==3.0.4 # via requests docutils==0.16 # via sphinx -idna==2.9 # via requests +idna==2.10 # via requests imagesize==1.2.0 # via sphinx jinja2==2.11.2 # via sphinx -lxml==4.5.0 # via -r requirements.in +lxml==4.5.2 # via -r requirements.in markupsafe==1.1.1 # via jinja2 -packaging==20.3 # via sphinx -pyenchant==3.0.1 # via sphinxcontrib-spelling +packaging==20.4 # via sphinx +pyenchant==3.1.1 # via sphinxcontrib-spelling pygments==2.6.1 # via sphinx pyparsing==2.4.7 # via packaging pytz==2020.1 # via babel -requests==2.23.0 # via sphinx -six==1.14.0 # via packaging, sphinxcontrib-spelling +requests==2.24.0 # via sphinx +six==1.15.0 # via packaging snowballstemmer==2.0.0 # via sphinx -sphinx==3.0.3 # via -r requirements.in, sphinxcontrib-spelling +sphinx==3.2.1 # via -r requirements.in, sphinxcontrib-spelling sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==1.0.3 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.4 # via sphinx -sphinxcontrib-spelling==5.0.0 # via -r requirements.in -urllib3==1.25.9 # via requests +sphinxcontrib-spelling==5.3.0 # via -r requirements.in +urllib3==1.25.10 # via requests # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/json/tests/draft2019-09/enum.json b/json/tests/draft2019-09/enum.json index 6844578..f085097 100644 --- a/json/tests/draft2019-09/enum.json +++ b/json/tests/draft2019-09/enum.json @@ -33,6 +33,16 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false } ] }, diff --git a/json/tests/draft2019-09/if-then-else.json b/json/tests/draft2019-09/if-then-else.json index e0b873e..284e919 100644 --- a/json/tests/draft2019-09/if-then-else.json +++ b/json/tests/draft2019-09/if-then-else.json @@ -224,5 +224,35 @@ "valid": true } ] + }, + { + "description": "if appears at the end when serialized (keyword processing sequence)", + "schema": { + "then": { "const": "yes" }, + "else": { "const": "other" }, + "if": { "maxLength": 4 } + }, + "tests": [ + { + "description": "yes redirects to then and passes", + "data": "yes", + "valid": true + }, + { + "description": "other redirects to else and passes", + "data": "other", + "valid": true + }, + { + "description": "no redirects to then and fails", + "data": "no", + "valid": false + }, + { + "description": "invalid redirects to else and fails", + "data": "invalid", + "valid": false + } + ] } ] diff --git a/json/tests/draft2019-09/multipleOf.json b/json/tests/draft2019-09/multipleOf.json index ca3b761..faa87cf 100644 --- a/json/tests/draft2019-09/multipleOf.json +++ b/json/tests/draft2019-09/multipleOf.json @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff --git a/json/tests/draft2019-09/optional/ecmascript-regex.json b/json/tests/draft2019-09/optional/ecmascript-regex.json index b9412e0..6ed6cbe 100644 --- a/json/tests/draft2019-09/optional/ecmascript-regex.json +++ b/json/tests/draft2019-09/optional/ecmascript-regex.json @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", diff --git a/json/tests/draft2019-09/optional/float-overflow.json b/json/tests/draft2019-09/optional/float-overflow.json new file mode 100644 index 0000000..52ff982 --- /dev/null +++ b/json/tests/draft2019-09/optional/float-overflow.json @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff --git a/json/tests/draft2019-09/unevaluatedItems.json b/json/tests/draft2019-09/unevaluatedItems.json index 01c07be..32f13f8 100644 --- a/json/tests/draft2019-09/unevaluatedItems.json +++ b/json/tests/draft2019-09/unevaluatedItems.json @@ -87,12 +87,12 @@ }, "tests": [ { - "description": "with no unevaluted items", + "description": "with no unevaluated items", "data": ["foo"], "valid": true }, { - "description": "with unevaluted items", + "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } @@ -135,12 +135,12 @@ }, "tests": [ { - "description": "with no unevaluted items", + "description": "with no unevaluated items", "data": ["foo", 42], "valid": true }, { - "description": "with unevaluted items", + "description": "with unevaluated items", "data": ["foo", 42, true], "valid": false } @@ -228,22 +228,22 @@ }, "tests": [ { - "description": "when one schema matches and has no unevaluted items", + "description": "when one schema matches and has no unevaluated items", "data": ["foo", "bar"], "valid": true }, { - "description": "when one schema matches and has unevaluted items", + "description": "when one schema matches and has unevaluated items", "data": ["foo", "bar", 42], "valid": false }, { - "description": "when two schemas match and has no unevaluted items", + "description": "when two schemas match and has no unevaluated items", "data": ["foo", "bar", "baz"], "valid": true }, { - "description": "when two schemas match and has unevaluted items", + "description": "when two schemas match and has unevaluated items", "data": ["foo", "bar", "baz", 42], "valid": false } @@ -274,12 +274,12 @@ }, "tests": [ { - "description": "with no unevaluted items", + "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { - "description": "with unevaluted items", + "description": "with unevaluated items", "data": ["foo", "bar", 42], "valid": false } @@ -304,7 +304,7 @@ }, "tests": [ { - "description": "with unevaluted items", + "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } @@ -342,22 +342,22 @@ }, "tests": [ { - "description": "when if matches and it has no unevaluted items", + "description": "when if matches and it has no unevaluated items", "data": ["foo", "bar", "then"], "valid": true }, { - "description": "when if matches and it has unevaluted items", + "description": "when if matches and it has unevaluated items", "data": ["foo", "bar", "then", "else"], "valid": false }, { - "description": "when if doesn't match and it has no unevaluted items", + "description": "when if doesn't match and it has no unevaluated items", "data": ["foo", 42, 42, "else"], "valid": true }, { - "description": "when if doesn't match and it has unevaluted items", + "description": "when if doesn't match and it has unevaluated items", "data": ["foo", 42, 42, "else", 42], "valid": false } diff --git a/json/tests/draft3/ref.json b/json/tests/draft3/ref.json index 74e963c..77b2947 100644 --- a/json/tests/draft3/ref.json +++ b/json/tests/draft3/ref.json @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilde~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilde": {"$ref": "#/tilde~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ diff --git a/json/tests/draft4/enum.json b/json/tests/draft4/enum.json index 6844578..f085097 100644 --- a/json/tests/draft4/enum.json +++ b/json/tests/draft4/enum.json @@ -33,6 +33,16 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false } ] }, diff --git a/json/tests/draft4/multipleOf.json b/json/tests/draft4/multipleOf.json index ca3b761..faa87cf 100644 --- a/json/tests/draft4/multipleOf.json +++ b/json/tests/draft4/multipleOf.json @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff --git a/json/tests/draft4/optional/ecmascript-regex.json b/json/tests/draft4/optional/ecmascript-regex.json index b9412e0..6ed6cbe 100644 --- a/json/tests/draft4/optional/ecmascript-regex.json +++ b/json/tests/draft4/optional/ecmascript-regex.json @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", diff --git a/json/tests/draft4/optional/float-overflow.json b/json/tests/draft4/optional/float-overflow.json new file mode 100644 index 0000000..52ff982 --- /dev/null +++ b/json/tests/draft4/optional/float-overflow.json @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff --git a/json/tests/draft4/ref.json b/json/tests/draft4/ref.json index fc3e94b..f88e963 100644 --- a/json/tests/draft4/ref.json +++ b/json/tests/draft4/ref.json @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilde~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilde": {"$ref": "#/tilde~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ diff --git a/json/tests/draft6/enum.json b/json/tests/draft6/enum.json index 6844578..f085097 100644 --- a/json/tests/draft6/enum.json +++ b/json/tests/draft6/enum.json @@ -33,6 +33,16 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false } ] }, diff --git a/json/tests/draft6/multipleOf.json b/json/tests/draft6/multipleOf.json index ca3b761..faa87cf 100644 --- a/json/tests/draft6/multipleOf.json +++ b/json/tests/draft6/multipleOf.json @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff --git a/json/tests/draft6/optional/ecmascript-regex.json b/json/tests/draft6/optional/ecmascript-regex.json index b9412e0..6ed6cbe 100644 --- a/json/tests/draft6/optional/ecmascript-regex.json +++ b/json/tests/draft6/optional/ecmascript-regex.json @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", diff --git a/json/tests/draft6/optional/float-overflow.json b/json/tests/draft6/optional/float-overflow.json new file mode 100644 index 0000000..52ff982 --- /dev/null +++ b/json/tests/draft6/optional/float-overflow.json @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff --git a/json/tests/draft6/ref.json b/json/tests/draft6/ref.json index 8eaba56..0138382 100644 --- a/json/tests/draft6/ref.json +++ b/json/tests/draft6/ref.json @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilde~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilde": {"$ref": "#/tilde~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ diff --git a/json/tests/draft7/enum.json b/json/tests/draft7/enum.json index 6844578..f085097 100644 --- a/json/tests/draft7/enum.json +++ b/json/tests/draft7/enum.json @@ -33,6 +33,16 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false } ] }, diff --git a/json/tests/draft7/if-then-else.json b/json/tests/draft7/if-then-else.json index e0b873e..284e919 100644 --- a/json/tests/draft7/if-then-else.json +++ b/json/tests/draft7/if-then-else.json @@ -224,5 +224,35 @@ "valid": true } ] + }, + { + "description": "if appears at the end when serialized (keyword processing sequence)", + "schema": { + "then": { "const": "yes" }, + "else": { "const": "other" }, + "if": { "maxLength": 4 } + }, + "tests": [ + { + "description": "yes redirects to then and passes", + "data": "yes", + "valid": true + }, + { + "description": "other redirects to else and passes", + "data": "other", + "valid": true + }, + { + "description": "no redirects to then and fails", + "data": "no", + "valid": false + }, + { + "description": "invalid redirects to else and fails", + "data": "invalid", + "valid": false + } + ] } ] diff --git a/json/tests/draft7/multipleOf.json b/json/tests/draft7/multipleOf.json index ca3b761..faa87cf 100644 --- a/json/tests/draft7/multipleOf.json +++ b/json/tests/draft7/multipleOf.json @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff --git a/json/tests/draft7/optional/ecmascript-regex.json b/json/tests/draft7/optional/ecmascript-regex.json index b9412e0..6ed6cbe 100644 --- a/json/tests/draft7/optional/ecmascript-regex.json +++ b/json/tests/draft7/optional/ecmascript-regex.json @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", diff --git a/json/tests/draft7/optional/float-overflow.json b/json/tests/draft7/optional/float-overflow.json new file mode 100644 index 0000000..52ff982 --- /dev/null +++ b/json/tests/draft7/optional/float-overflow.json @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff --git a/json/tests/draft7/ref.json b/json/tests/draft7/ref.json index 5a8602e..01ba9fa 100644 --- a/json/tests/draft7/ref.json +++ b/json/tests/draft7/ref.json @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilde~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilde": {"$ref": "#/tilde~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 780a22d..a320b2d 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -134,6 +134,7 @@ def types_msg(instance, types): def flatten(suitable_for_isinstance): """ isinstance() can accept a bunch of really annoying different types: + * a single type * a tuple of types * an arbitrary nested tree of tuples diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index d7097ff..7e8c95a 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -1,3 +1,4 @@ +from fractions import Fraction import re from jsonschema._utils import ( @@ -166,7 +167,18 @@ def multipleOf(validator, dB, instance, schema): if isinstance(dB, float): quotient = instance / dB - failed = int(quotient) != quotient + try: + failed = int(quotient) != quotient + except OverflowError: + # When `instance` is large and `dB` is less than one, quotient can + # overflow to infinity; and then casting to int raises an error. + # + # In this case we fall back to Fraction logic, which is exact and + # cannot overflow. The performance is also acceptable: we try the + # fast all-float option first, and we know that fraction(dB) can have + # at most a few hundred digits in each part. The worst-case slowdown + # is therefore for already-slow enormous integers or Decimals. + failed = (Fraction(instance) / Fraction(dB)).denominator != 1 else: failed = instance % dB diff --git a/jsonschema/tests/test_types.py b/jsonschema/tests/test_types.py index 2280cc3..82071ca 100644 --- a/jsonschema/tests/test_types.py +++ b/jsonschema/tests/test_types.py @@ -1,7 +1,9 @@ """ -Tests on the new type interface. The actual correctness of the type checking -is handled in test_jsonschema_test_suite; these tests check that TypeChecker -functions correctly and can facilitate extensions to type checking +Tests for the `TypeChecker`-based type interface. + +The actual correctness of the type checking is handled in +`test_jsonschema_test_suite`; these tests check that TypeChecker +functions correctly at a more granular level. """ from collections import namedtuple from unittest import TestCase diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index fc6a355..2f017b9 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -1561,7 +1561,7 @@ class TestValidate(SynchronousTestCase): def test_validation_error_message(self): with self.assertRaises(exceptions.ValidationError) as e: validators.validate(12, {"type": "string"}) - self.assertRegexpMatches( + self.assertRegex( str(e.exception), "(?s)Failed validating u?'.*' in schema.*On instance", ) @@ -1569,7 +1569,7 @@ class TestValidate(SynchronousTestCase): def test_schema_error_message(self): with self.assertRaises(exceptions.SchemaError) as e: validators.validate(12, {"type": 12}) - self.assertRegexpMatches( + self.assertRegex( str(e.exception), "(?s)Failed validating u?'.*' in metaschema.*On schema", ) @@ -10,8 +10,14 @@ skipsdist = True [testenv] changedir = {envtmpdir} +passenv = CODECOV* CI setenv = JSON_SCHEMA_TEST_SUITE = {toxinidir}/json + + coverage,codecov: MAYBE_COVERAGE = coverage run -m + coverage,codecov: COVERAGE_RCFILE={toxinidir}/.coveragerc + coverage,codecov: COVERAGE_DEBUG_FILE={envtmpdir}/coverage-debug + coverage,codecov: COVERAGE_FILE={envtmpdir}/coverage-data whitelist_externals = mkdir commands = @@ -19,17 +25,21 @@ commands = format: {envpython} -m pip install '{toxinidir}[format]' format_nongpl: {envpython} -m pip install '{toxinidir}[format_nongpl]' - tests: {envpython} -m twisted.trial {posargs:jsonschema} + tests,coverage,codecov: {envpython} -m {env:MAYBE_COVERAGE:} twisted.trial {posargs:jsonschema} tests: {envpython} -m doctest {toxinidir}/README.rst + coverage: {envpython} -m coverage report --show-missing + coverage: {envpython} -m coverage html --directory={envtmpdir}/htmlcov + codecov: {envpython} -m coverage xml -o {envtmpdir}/coverage.xml + codecov: codecov --required --disable gcov --file {envtmpdir}/coverage.xml + perf: 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: {envpython} -m pep517.check {toxinidir} + build: {envpython} -m build {toxinidir} --outdir {envtmpdir}/dist deps = - build: pep517 + build: build perf: pyperf @@ -44,11 +54,11 @@ commands = {envbindir}/bandit --recursive {toxinidir}/jsonschema [testenv:readme] deps = + build docutils - pep517 twine commands = - {envpython} -m pep517.build --out-dir {envtmpdir}/dist {toxinidir} + {envpython} -m build --outdir {envtmpdir}/dist {toxinidir} {envpython} -m twine check {envtmpdir}/dist/* {envbindir}/rst2html5.py --halt=warning {toxinidir}/CHANGELOG.rst /dev/null @@ -69,17 +79,6 @@ deps = commands = {envpython} -m flake8 {posargs} {toxinidir}/jsonschema {toxinidir}/docs -[testenv:coverage] -setenv = - {[testenv]setenv} - COVERAGE_DEBUG_FILE={envtmpdir}/coverage-debug - COVERAGE_FILE={envtmpdir}/coverage-data -commands = - {envpython} -m pip install '{toxinidir}[format]' - {envpython} -m coverage run --rcfile={toxinidir}/.coveragerc -m twisted.trial jsonschema - {envpython} -m coverage report --rcfile={toxinidir}/.coveragerc --show-missing - {envpython} -m coverage html --directory={envtmpdir}/htmlcov --rcfile={toxinidir}/.coveragerc {posargs} - [testenv:docs-html] basepython = pypy3 commands = {envpython} -m sphinx -b html {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} @@ -115,12 +114,3 @@ deps = doc8 pygments pygments-github-lexers - -[testenv:codecov] -passenv = CODECOV* CI -setenv = {[testenv:coverage]setenv} -commands = - {envpython} -m pip install '{toxinidir}[format]' - {envpython} -m coverage run --rcfile={toxinidir}/.coveragerc -m twisted.trial jsonschema - {envpython} -m coverage xml -o {envtmpdir}/coverage.xml - codecov --required --disable gcov --file {envtmpdir}/coverage.xml |