Skip to content

Commit e393e2d

Browse files
authored
Merge pull request #100 from Stranger6667/dd/cache-validator
perf: Cache JSON Schema validators by their schema's JSON representation
2 parents afbb2a9 + 8c1fa03 commit e393e2d

File tree

6 files changed

+32
-9
lines changed

6 files changed

+32
-9
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
release:
6666
runs-on: ubuntu-latest
6767
needs: [check, test, test-slow]
68-
if: github.repository == 'Zac-HD/hypothesis-jsonschema' && github.ref == 'refs/heads/master'
68+
if: github.repository == 'python-jsonschema/hypothesis-jsonschema' && github.ref == 'refs/heads/master'
6969
steps:
7070
- uses: actions/checkout@v2
7171
- name: Set up Python 3.8

CHANGELOG.md

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

3+
#### 0.22.1 - 2023-02-07
4+
- Cache JSON Schema validators by their schema's JSON representation
5+
36
#### 0.22.0 - 2021-12-15
47
- never generate trailing newlines for regex patterns ending in `$`
58
(allowed by Python, but not by JSON Schema)

deps/check.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ flake8-docstrings
1010
flake8-mutable
1111
# flake8-noqa # See https://github.com/JBKahn/flake8-print/issues/50
1212
flake8-print
13-
flake8-simplify
1413
flake8-strftime
1514
mypy
1615
pep8-naming

deps/check.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
#
55
# pip-compile --output-file=deps/check.txt deps/check.in
66
#
7-
astor==0.8.1
8-
# via flake8-simplify
97
attrs==21.2.0
108
# via flake8-bugbear
119
autoflake==1.4
@@ -36,7 +34,6 @@ flake8==4.0.1
3634
# flake8-mutable
3735
# flake8-polyfill
3836
# flake8-print
39-
# flake8-simplify
4037
# flake8-strftime
4138
# pep8-naming
4239
flake8-2020==1.6.1
@@ -63,8 +60,6 @@ flake8-polyfill==1.0.2
6360
# pep8-naming
6461
flake8-print==4.0.0
6562
# via -r deps/check.in
66-
flake8-simplify==0.14.2
67-
# via -r deps/check.in
6863
flake8-strftime==0.3.2
6964
# via -r deps/check.in
7065
gitdb==4.0.9
@@ -77,7 +72,6 @@ importlib-metadata==4.2.0
7772
# flake8
7873
# flake8-2020
7974
# flake8-comprehensions
80-
# flake8-simplify
8175
# stevedore
8276
isort==5.10.1
8377
# via shed

src/hypothesis_jsonschema/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
The only public API is `from_schema`; check the docstring for details.
44
"""
55

6-
__version__ = "0.22.0"
6+
__version__ = "0.22.1"
77
__all__ = ["from_schema"]
88

99
from ._from_schema import from_schema

src/hypothesis_jsonschema/_canonicalise.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import math
1919
import re
2020
from fractions import Fraction
21+
from functools import lru_cache
2122
from typing import Any, Dict, List, Optional, Tuple, Union
2223

2324
import jsonschema
@@ -69,7 +70,33 @@ def next_down(val: float) -> float:
6970
return out
7071

7172

73+
class CacheableSchema:
74+
"""Cache schema by its JSON representation.
75+
76+
Canonicalisation is not required as schemas with the same JSON representation
77+
will have the same validator.
78+
"""
79+
80+
__slots__ = ("schema", "encoded")
81+
82+
def __init__(self, schema: Schema) -> None:
83+
self.schema = schema
84+
self.encoded = hash(json.dumps(schema, sort_keys=True))
85+
86+
def __eq__(self, other: "CacheableSchema") -> bool: # type: ignore
87+
return self.encoded == other.encoded
88+
89+
def __hash__(self) -> int:
90+
return self.encoded
91+
92+
7293
def _get_validator_class(schema: Schema) -> JSONSchemaValidator:
94+
return __get_validator_class(CacheableSchema(schema))
95+
96+
97+
@lru_cache(maxsize=128)
98+
def __get_validator_class(wrapper: CacheableSchema) -> JSONSchemaValidator:
99+
schema = wrapper.schema
73100
with contextlib.suppress(jsonschema.exceptions.SchemaError):
74101
validator = jsonschema.validators.validator_for(schema)
75102
validator.check_schema(schema)

0 commit comments

Comments
 (0)