Skip to content

Commit 11a81a7

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 42f317e commit 11a81a7

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

jq.pyx

+9-5
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,11 @@ cdef class _JSONParser(object):
167167
cdef char* cbytes
168168
cdef ssize_t clen
169169
try:
170-
self._bytes = next(self._text_iter).encode("utf8")
170+
text = next(self._text_iter)
171+
if isinstance(text, bytes):
172+
self._bytes = text
173+
else:
174+
self._bytes = text.encode("utf8")
171175
PyBytes_AsStringAndSize(self._bytes, &cbytes, &clen)
172176
jv_parser_set_buf(self._parser, cbytes, clen, 1)
173177
except StopIteration:
@@ -431,9 +435,10 @@ def parse_json(text=_NO_VALUE, text_iter=_NO_VALUE):
431435
Either "text" or "text_iter" must be specified.
432436
433437
Args:
434-
text: A string containing the JSON stream to parse.
435-
text_iter: An iterator returning strings - pieces of the JSON stream
436-
to parse.
438+
text: A string or bytes object containing the JSON stream to
439+
parse.
440+
text_iter: An iterator returning strings or bytes - pieces of the
441+
JSON stream to parse.
437442
438443
Returns:
439444
An iterator returning parsed values.
@@ -454,7 +459,6 @@ def parse_json_file(fp):
454459
455460
Args:
456461
fp: The file-like object to read the JSON stream from.
457-
Must be in text mode.
458462
459463
Returns:
460464
An iterator returning parsed values.

tests/jq_tests.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,11 @@ def program_string_can_be_retrieved_from_program():
206206
assert_equal(".", program.program_string)
207207

208208
@istest
209-
def parse_json_both_text_and_text_iter_accepted():
209+
def parse_json_all_inputs_accepted():
210210
assert_equal(True, next(jq.parse_json(text="true")))
211211
assert_equal(True, next(jq.parse_json(text_iter=iter(["true"]))))
212+
assert_equal(True, next(jq.parse_json(text=b"true")))
213+
assert_equal(True, next(jq.parse_json(text_iter=iter([b"true"]))))
212214

213215
@istest
214216
def parse_json_file_works():

0 commit comments

Comments
 (0)