Skip to content

Commit a4fc266

Browse files
committed
Add support for orjson (optional)
This might become a hard dependency in the future, and replace use of `json` entirely, but for now it's an opt-in feature which should make parsing of large JSON files faster.
1 parent fb45fea commit a4fc266

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Unreleased
1111
.. vendor-insert-here
1212
1313
- Update vendored schemas (2024-02-05)
14+
- Support the use of `orjson` for faster JSON parsing when it is installed.
15+
This makes it an optional parser which is preferred over the default
16+
`json` module when it is available.
1417

1518
0.27.4
1619
------

src/check_jsonschema/parsers/__init__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
from __future__ import annotations
22

33
import io
4-
import json
54
import pathlib
65
import typing as t
76

87
import ruamel.yaml
98

109
from ..identify_filetype import path_to_type
11-
from . import json5, toml, yaml
10+
from . import json5, json_, toml, yaml
1211

13-
_PARSER_ERRORS: set[type[Exception]] = {json.JSONDecodeError, yaml.ParseError}
12+
_PARSER_ERRORS: set[type[Exception]] = {json_.JSONDecodeError, yaml.ParseError}
1413
DEFAULT_LOAD_FUNC_BY_TAG: dict[str, t.Callable[[t.IO[bytes]], t.Any]] = {
15-
"json": json.load,
14+
"json": json_.load,
1615
}
1716
SUPPORTED_FILE_FORMATS = ["json", "yaml"]
1817
if json5.ENABLED:

src/check_jsonschema/parsers/json_.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from __future__ import annotations
2+
3+
import json
4+
import typing as t
5+
6+
try:
7+
import orjson
8+
9+
has_orjson = True
10+
except ImportError:
11+
has_orjson = False
12+
13+
JSONDecodeError = json.JSONDecodeError
14+
15+
16+
def load(stream: t.IO[bytes]) -> t.Any:
17+
bin_data = stream.read()
18+
# if orjson is available, try it first
19+
if has_orjson:
20+
# in the event of a decode error, it may be that the data contains
21+
# `Infinity`, `-Infinity`, or `NaN`
22+
#
23+
# however, do not failover to stdlib JSON -- it is not obvious that there's any
24+
# need for check-jsonschema to support these invalid JSON datatypes
25+
# if users encounter issues with this behavior in the future, we can revisit how
26+
# JSON loading is handled
27+
return orjson.loads(bin_data)
28+
# failover to stdlib json
29+
return json.loads(bin_data)

tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ envlist =
66
py{312,311,310,39,38}
77
py310-{notoml,tomli-format}
88
py{38,312}-{json5,pyjson5}
9+
py{38,312}-{disable_orjson}
910
cov
1011
skip_missing_interpreters = true
1112
minversion = 4.0.0
@@ -22,6 +23,7 @@ deps =
2223
mindeps: click==8.0.0
2324
mindeps: requests==2.0.0
2425
mindeps: importlib-resources==1.4.0
26+
!disable_orjson: orjson
2527
json5: json5
2628
pyjson5: pyjson5
2729
tomli: tomli

0 commit comments

Comments
 (0)