Skip to content

Commit dd812fa

Browse files
authored
Merge pull request #78 from Stranger6667/dd/pypy-support
PyPy support
2 parents 2312ec3 + 264ee19 commit dd812fa

File tree

5 files changed

+56
-27
lines changed

5 files changed

+56
-27
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,19 @@ jobs:
2626
runs-on: ubuntu-latest
2727
strategy:
2828
matrix:
29-
python-version: [3.6, 3.7, 3.8, 3.9]
29+
python-version: [3.6, 3.7, 3.8, 3.9, "pypy-3.6", "pypy-3.7"]
3030
fail-fast: false
3131
steps:
3232
- uses: actions/checkout@v2
3333
- name: Set up Python ${{ matrix.python-version }}
34-
uses: actions/setup-python@v1
34+
uses: actions/setup-python@v2
3535
with:
3636
python-version: ${{ matrix.python-version }}
3737
- name: Install dependencies
3838
run: python -m pip install --upgrade pip setuptools tox
3939
- name: Run tests
40-
run: python -m tox --recreate -e test
40+
# Disable coverage on PyPy
41+
run: python -m tox --recreate -e test $(${{ startsWith(matrix.python-version, 'pypy') }} && echo '-- -n auto --no-cov')
4142

4243
release:
4344
runs-on: ubuntu-latest

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Changelog
22

3+
- PyPy support (#77)
4+
35
#### 0.19.0 - 2021-01-06
46
- Generate empty lists when `maxItems > 0` but no elements are allowed (#75)
57
- Correct handling of regex patterns which are invalid in Python (#75)

src/hypothesis_jsonschema/_encode.py

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,53 @@
11
"""Canonical encoding for the JSONSchema semantics, where 1 == 1.0."""
22
import json
33
import math
4-
from json.encoder import _make_iterencode, encode_basestring_ascii # type: ignore
4+
import platform
55
from typing import Any, Dict, Tuple, Union
66

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

12+
if PYTHON_IMPLEMENTATION != "PyPy":
13+
from json.encoder import _make_iterencode, encode_basestring_ascii # type: ignore
14+
else: # pragma: no cover
15+
_make_iterencode = None
16+
encode_basestring_ascii = None
17+
18+
19+
def _floatstr(o: float) -> str:
20+
# This is the bit we're overriding - integer-valued floats are
21+
# encoded as integers, to support JSONschemas's uniqueness.
22+
assert math.isfinite(o)
23+
if o == int(o):
24+
return repr(int(o))
25+
return repr(o)
26+
1127

1228
class CanonicalisingJsonEncoder(json.JSONEncoder):
13-
def iterencode(self, o: Any, _one_shot: bool = False) -> Any:
14-
"""Replace a stdlib method, so we encode integer-valued floats as ints."""
15-
16-
def floatstr(o: float) -> str:
17-
# This is the bit we're overriding - integer-valued floats are
18-
# encoded as integers, to support JSONschemas's uniqueness.
19-
assert math.isfinite(o)
20-
if o == int(o):
21-
return repr(int(o))
22-
return repr(o)
23-
24-
return _make_iterencode(
25-
{},
26-
self.default,
27-
encode_basestring_ascii,
28-
self.indent,
29-
floatstr,
30-
self.key_separator,
31-
self.item_separator,
32-
self.sort_keys,
33-
self.skipkeys,
34-
_one_shot,
35-
)(o, 0)
29+
30+
if PYTHON_IMPLEMENTATION == "PyPy": # pragma: no cover
31+
32+
def _JSONEncoder__floatstr(self, o: float) -> str: # noqa: N802
33+
return _floatstr(o)
34+
35+
else:
36+
37+
def iterencode(self, o: Any, _one_shot: bool = False) -> Any:
38+
"""Replace a stdlib method, so we encode integer-valued floats as ints."""
39+
return _make_iterencode(
40+
{},
41+
self.default,
42+
encode_basestring_ascii,
43+
self.indent,
44+
_floatstr,
45+
self.key_separator,
46+
self.item_separator,
47+
self.sort_keys,
48+
self.skipkeys,
49+
_one_shot,
50+
)(o, 0)
3651

3752

3853
def encode_canonical_json(value: JSONType) -> str:

tests/test_canonicalise.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,16 @@ def test_canonicalises_to_expected(schema, expected):
451451
"additionalItems": FALSEY,
452452
},
453453
),
454+
(
455+
[
456+
{"items": [{}, {"type": "string"}], "additionalItems": False},
457+
{"items": {"type": "string"}},
458+
],
459+
{
460+
"items": [{"type": "string"}, {"type": "string"}],
461+
"additionalItems": FALSEY,
462+
},
463+
),
454464
]
455465
+ [
456466
([{lo: 0, hi: 9}, {lo: 1, hi: 10}], {lo: 1, hi: 9})

tests/test_from_schema.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ def test_invalid_regex_emit_warning(schema):
131131
"draft4/oneOf with missing optional property",
132132
"draft7/oneOf with missing optional property",
133133
# Sometimes unsatisfiable. TODO: improve canonicalisation to remove filters
134+
"JSCS configuration file", # https://github.com/Zac-HD/hypothesis-jsonschema/pull/78#issuecomment-803519293
134135
"Drone CI configuration file",
135136
"PHP Composer configuration file",
136137
"Pyrseas database schema versioning for Postgres databases, v0.8",

0 commit comments

Comments
 (0)