Skip to content

Commit 6b5542a

Browse files
authored
Merge pull request #62 from solute/add-orjson-handler
Add orjson support
2 parents 0901d6a + ae73477 commit 6b5542a

File tree

4 files changed

+82
-5
lines changed

4 files changed

+82
-5
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ A `SimpleJSONRPCServer` class has been added. It is intended to emulate the
6464

6565
## Requirements
6666

67-
This library supports `ujson`, `cjson` and `simplejson`, and looks for the
68-
parsers in that order (searching first for `ujson`, `cjson`, `simplejson`
69-
and finally for the *built-in* `json`).
67+
This library supports `orjson`, `ujson`, `cjson` and `simplejson`, and looks
68+
for the parsers in that order (searching first for `orjson`, `ujson`, `cjson`,
69+
`simplejson` and finally for the *built-in* `json`).
7070
One of these must be installed to use this library, although if you have a
7171
standard distribution of 2.7+, you should already have one.
72-
Keep in mind that `ujson` is supposed to be the quickest, I believe, so if you
72+
Keep in mind that `orjson` is supposed to be the quickest, I believe, so if you
7373
are going for full-on optimization you may want to pick it up.
7474

7575
## Installation

jsonrpclib/jsonlib.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,31 @@ def dumps_ujson(obj, encoding="utf-8"):
103103
return ujson.loads, dumps_ujson
104104

105105

106+
class OrJsonHandler(JsonHandler):
107+
"""
108+
Handler based on orjson
109+
"""
110+
111+
def get_methods(self):
112+
import orjson
113+
114+
def dumps_orjson(obj, encoding="utf-8"):
115+
return orjson.dumps(obj).decode(encoding)
116+
117+
return orjson.loads, dumps_orjson
118+
119+
106120
def get_handler():
107121
# type: () -> JsonHandler
108122
"""
109123
Returns the best available Json parser
110124
"""
111-
for handler_class in (UJsonHandler, SimpleJsonHandler, CJsonHandler):
125+
for handler_class in (
126+
OrJsonHandler,
127+
UJsonHandler,
128+
SimpleJsonHandler,
129+
CJsonHandler,
130+
):
112131
handler = handler_class()
113132
try:
114133
loader, dumper = handler.get_methods()

run_tests.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ echo "Initial tests..."
1111
export JSONRPCLIB_TEST_EXPECTED_LIB=json
1212
coverage run -m pytest || exit 1
1313

14+
echo "orJson tests..."
15+
pip install orjson && (
16+
export JSONRPCLIB_TEST_EXPECTED_LIB=orjson
17+
coverage run -m pytest tests/test_jsonlib.py || exit 1
18+
pip uninstall -y orjson
19+
)
20+
1421
echo "uJson tests..."
1522
pip install ujson && (
1623
export JSONRPCLIB_TEST_EXPECTED_LIB=ujson

tests/test_jsonlib.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ def test_best(self):
109109
except ImportError:
110110
pass
111111

112+
try:
113+
import orjson # pylint: disable=unused-import,import-outside-toplevel
114+
115+
available.add("orjson")
116+
except ImportError:
117+
pass
118+
112119
# Check the availability of the expected best handler
113120
expected_best = self._get_expected_best(available)
114121

@@ -271,3 +278,47 @@ def test_simplejson(self):
271278
finally:
272279
# Reload the module
273280
imp_reload(simplejson)
281+
282+
def test_orjson(self):
283+
"""
284+
Tests if the orjson methods are really used
285+
"""
286+
try:
287+
import orjson # pylint: disable=import-outside-toplevel
288+
except ImportError:
289+
return self.skipTest("orjson is missing: ignore")
290+
291+
# Check if the expected best is right
292+
self._check_expected_best("orjson")
293+
294+
try:
295+
# Force methods to raise an exception
296+
orjson.loads = _fake_loads
297+
298+
orjson.dumps = lambda *args, **kwargs: _fake_dumps(
299+
*args, **kwargs
300+
).encode() # orjson.dumps returns bytes
301+
302+
# Reload the module
303+
imp_reload(jsonlib)
304+
305+
# Check the handler
306+
handler = jsonlib.get_handler()
307+
self.assertIsInstance(handler, jsonlib.OrJsonHandler)
308+
309+
# Check the methods
310+
load_method, dump_method = jsonlib.get_handler_methods()
311+
self.assertIs(orjson.loads, _fake_loads)
312+
self.assertIs(load_method, _fake_loads)
313+
self.assertRaises(
314+
NotImplementedError, load_method, TEST_INPUT_MARKER
315+
)
316+
self.assertRaises(
317+
NotImplementedError, dump_method, TEST_OUTPUT_MARKER
318+
)
319+
self.assertRaises(
320+
NotImplementedError, dump_method, TEST_OUTPUT_MARKER, "encoding"
321+
)
322+
finally:
323+
# Reload the module
324+
imp_reload(orjson)

0 commit comments

Comments
 (0)