From a3b0b760a3f51bf4b1b34516770deac3b6b9efbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= Date: Thu, 10 Jun 2021 18:50:48 +0200 Subject: [PATCH] add support for non-bytesable objects --- CHANGELOG.md | 5 +++-- docs/usage.rst | 2 ++ minijson.pyx | 44 ++++++++++++++++++++++++++------------------ setup.cfg | 2 +- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8325bb..265136d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ Changelog is kept at [GitHub](https://github.com/Dronehub/minijson/releases), here's only the changelog for the version in development -# v2.2 +# v2.3 -* added support for PyPy and Python 3.5 +* loads will now take any object that can provide + it's `__bytes__` diff --git a/docs/usage.rst b/docs/usage.rst index ebd8324..807988e 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -50,6 +50,8 @@ arguments to the program, you can use functions below to serialize/unserialize t .. autofunction:: minijson.loads_object +Dumps returns objects of type :code:`bytes`. + Example: .. code-block:: python diff --git a/minijson.pyx b/minijson.pyx index 1a9428e..f6ec5a9 100644 --- a/minijson.pyx +++ b/minijson.pyx @@ -64,7 +64,7 @@ cdef inline tuple parse_list(bytes data, int elem_count, int starting_position): list lst = [] int i, ofs, offset = 0 for i in range(elem_count): - ofs, elem = parse(data, starting_position+offset) + ofs, elem = parse_bytes(data, starting_position+offset) offset += ofs lst.append(elem) return offset, lst @@ -91,7 +91,7 @@ cdef inline tuple parse_dict(bytes data, int elem_count, int starting_position): except UnicodeDecodeError as e: raise DecodingError('Invalid UTF-8 field name!') from e offset += ofs - ofs, elem = parse(data, starting_position+offset) + ofs, elem = parse_bytes(data, starting_position+offset) offset += ofs dct[s_field_name] = elem return offset, dct @@ -112,9 +112,9 @@ cdef inline tuple parse_sdict(bytes data, int elem_count, int starting_position) str s_field_name int i, ofs, offset = 0 for i in range(elem_count): - ofs, key = parse(data, starting_position+offset) + ofs, key = parse_bytes(data, starting_position+offset) offset += ofs - ofs, elem = parse(data, starting_position+offset) + ofs, elem = parse_bytes(data, starting_position+offset) offset += ofs dct[key] = elem return offset, dct @@ -129,17 +129,7 @@ cdef inline bint can_be_encoded_as_a_dict(dict dct): return True -cpdef tuple parse(bytes data, int starting_position): - """ - Parse given stream of data starting at a position - and return a tuple of (how many bytes does this piece of data take, the piece of data itself) - - :param data: stream of bytes to examine - :param starting_position: first position in the bytestring at which to look - :return: a tuple of (how many bytes does this piece of data take, the piece of data itself) - :rtype: tp.Tuple[int, tp.Any] - :raises DecodingError: invalid stream - """ +cdef tuple parse_bytes(bytes data, int starting_position): cdef: int value_type int string_length, elements, i, offset, length @@ -279,11 +269,29 @@ cpdef tuple parse(bytes data, int starting_position): except (IndexError, struct.error) as e: raise DecodingError('String too short!') from e -cpdef object loads(bytes data): + +cpdef tuple parse(object data, int starting_position): + """ + Parse given stream of data starting at a position + and return a tuple of (how many bytes does this piece of data take, the piece of data itself) + + :param data: stream of bytes to examine. Must be able to provide it's bytes value + via :code:`__bytes__` + :param starting_position: first position in the bytestring at which to look + :return: a tuple of (how many bytes does this piece of data take, the piece of data itself) + :rtype: tp.Tuple[int, tp.Any] + :raises DecodingError: invalid stream + """ + cdef bytes b_data = bytes(data) + return parse_bytes(b_data, starting_position) + + +cpdef object loads(object data): """ Reconstruct given JSON from a given value - :param data: MiniJSON value to reconstruct it from + :param data: MiniJSON value to reconstruct it from. + Must be able to provide bytes representation. :return: return value :raises DecodingError: something was wrong with the stream """ @@ -467,7 +475,7 @@ cpdef bytes dumps_object(object data): """ return dumps(data.__dict__) -cpdef object loads_object(bytes data, object obj_class): +cpdef object loads_object(data, object obj_class): """ Load a dict from a bytestream, unserialize it and use it as a kwargs to instantiate an object of given class diff --git a/setup.cfg b/setup.cfg index 2ee2c9b..dffcfdc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ # coding: utf-8 [metadata] -version = 2.2 +version = 2.3a1 name = minijson long_description = file: README.md long_description_content_type = text/markdown; charset=UTF-8