Skip to content

Commit

Permalink
Merge pull request #78 from Stranger6667/dd/pypy-support
Browse files Browse the repository at this point in the history
PyPy support
  • Loading branch information
Zac-HD authored Mar 23, 2021
2 parents 2312ec3 + 264ee19 commit dd812fa
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 27 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9, "pypy-3.6", "pypy-3.7"]
fail-fast: false
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: python -m pip install --upgrade pip setuptools tox
- name: Run tests
run: python -m tox --recreate -e test
# Disable coverage on PyPy
run: python -m tox --recreate -e test $(${{ startsWith(matrix.python-version, 'pypy') }} && echo '-- -n auto --no-cov')

release:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog

- PyPy support (#77)

#### 0.19.0 - 2021-01-06
- Generate empty lists when `maxItems > 0` but no elements are allowed (#75)
- Correct handling of regex patterns which are invalid in Python (#75)
Expand Down
63 changes: 39 additions & 24 deletions src/hypothesis_jsonschema/_encode.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,53 @@
"""Canonical encoding for the JSONSchema semantics, where 1 == 1.0."""
import json
import math
from json.encoder import _make_iterencode, encode_basestring_ascii # type: ignore
import platform
from typing import Any, Dict, Tuple, Union

# Mypy does not (yet!) support recursive type definitions.
# (and writing a few steps by hand is a DoS attack on the AST walker in Pytest)
PYTHON_IMPLEMENTATION = platform.python_implementation()
JSONType = Union[None, bool, float, str, list, Dict[str, Any]]

if PYTHON_IMPLEMENTATION != "PyPy":
from json.encoder import _make_iterencode, encode_basestring_ascii # type: ignore
else: # pragma: no cover
_make_iterencode = None
encode_basestring_ascii = None


def _floatstr(o: float) -> str:
# This is the bit we're overriding - integer-valued floats are
# encoded as integers, to support JSONschemas's uniqueness.
assert math.isfinite(o)
if o == int(o):
return repr(int(o))
return repr(o)


class CanonicalisingJsonEncoder(json.JSONEncoder):
def iterencode(self, o: Any, _one_shot: bool = False) -> Any:
"""Replace a stdlib method, so we encode integer-valued floats as ints."""

def floatstr(o: float) -> str:
# This is the bit we're overriding - integer-valued floats are
# encoded as integers, to support JSONschemas's uniqueness.
assert math.isfinite(o)
if o == int(o):
return repr(int(o))
return repr(o)

return _make_iterencode(
{},
self.default,
encode_basestring_ascii,
self.indent,
floatstr,
self.key_separator,
self.item_separator,
self.sort_keys,
self.skipkeys,
_one_shot,
)(o, 0)

if PYTHON_IMPLEMENTATION == "PyPy": # pragma: no cover

def _JSONEncoder__floatstr(self, o: float) -> str: # noqa: N802
return _floatstr(o)

else:

def iterencode(self, o: Any, _one_shot: bool = False) -> Any:
"""Replace a stdlib method, so we encode integer-valued floats as ints."""
return _make_iterencode(
{},
self.default,
encode_basestring_ascii,
self.indent,
_floatstr,
self.key_separator,
self.item_separator,
self.sort_keys,
self.skipkeys,
_one_shot,
)(o, 0)


def encode_canonical_json(value: JSONType) -> str:
Expand Down
10 changes: 10 additions & 0 deletions tests/test_canonicalise.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,16 @@ def test_canonicalises_to_expected(schema, expected):
"additionalItems": FALSEY,
},
),
(
[
{"items": [{}, {"type": "string"}], "additionalItems": False},
{"items": {"type": "string"}},
],
{
"items": [{"type": "string"}, {"type": "string"}],
"additionalItems": FALSEY,
},
),
]
+ [
([{lo: 0, hi: 9}, {lo: 1, hi: 10}], {lo: 1, hi: 9})
Expand Down
1 change: 1 addition & 0 deletions tests/test_from_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def test_invalid_regex_emit_warning(schema):
"draft4/oneOf with missing optional property",
"draft7/oneOf with missing optional property",
# Sometimes unsatisfiable. TODO: improve canonicalisation to remove filters
"JSCS configuration file", # https://github.com/Zac-HD/hypothesis-jsonschema/pull/78#issuecomment-803519293
"Drone CI configuration file",
"PHP Composer configuration file",
"Pyrseas database schema versioning for Postgres databases, v0.8",
Expand Down

0 comments on commit dd812fa

Please sign in to comment.