Skip to content

Commit a10ecdd

Browse files
committed
parser: Accept bytes as input
In addition to (Unicode) strings, also accept "bytes" (and corresponding iterators) as input to the parser. This allows skipping the decode/encode step when reading raw data from a file or socket, e.g. with os.read(). This introduces small, but measurable performance increase for such cases.
1 parent 1cf3225 commit a10ecdd

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

Diff for: jq.pyx

+9-5
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,11 @@ cdef class _JSONParser(object):
163163
cdef char* cbytes
164164
cdef ssize_t clen
165165
try:
166-
self._bytes = next(self._text_iter).encode("utf8")
166+
text = next(self._text_iter)
167+
if isinstance(text, bytes):
168+
self._bytes = text
169+
else:
170+
self._bytes = text.encode("utf8")
167171
PyBytes_AsStringAndSize(self._bytes, &cbytes, &clen)
168172
jv_parser_set_buf(self._parser, cbytes, clen, 1)
169173
except StopIteration:
@@ -419,9 +423,10 @@ def parse_json(text=_NO_VALUE, text_iter=_NO_VALUE):
419423
Either "text" or "text_iter" must be specified.
420424
421425
Args:
422-
text: A string containing the JSON stream to parse.
423-
text_iter: An iterator returning strings - pieces of the JSON stream
424-
to parse.
426+
text: A string or bytes object containing the JSON stream to
427+
parse.
428+
text_iter: An iterator returning strings or bytes - pieces of the
429+
JSON stream to parse.
425430
426431
Returns:
427432
An iterator returning parsed values.
@@ -442,7 +447,6 @@ def parse_json_file(fp):
442447
443448
Args:
444449
fp: The file-like object to read the JSON stream from.
445-
Must be in text mode.
446450
447451
Returns:
448452
An iterator returning parsed values.

Diff for: tests/jq_tests.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,11 @@ def program_string_can_be_retrieved_from_program():
198198
assert_equal(".", program.program_string)
199199

200200
@istest
201-
def parse_json_both_text_and_text_iter_accepted():
201+
def parse_json_all_inputs_accepted():
202202
assert_equal(True, next(jq.parse_json(text="true")))
203203
assert_equal(True, next(jq.parse_json(text_iter=iter(["true"]))))
204+
assert_equal(True, next(jq.parse_json(text=b"true")))
205+
assert_equal(True, next(jq.parse_json(text_iter=iter([b"true"]))))
204206

205207
@istest
206208
def parse_json_file_works():

0 commit comments

Comments
 (0)