Skip to content

Commit

Permalink
v2.7
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmaslanka committed Aug 6, 2021
1 parent 81e623a commit a9f2ab3
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 7 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Changelog is kept at [GitHub](https://github.com/Dronehub/minijson/releases),
here's only the changelog for the version in development

# v2.6
# v2.7

* added support for serializing and unserializing binary values
* added support for strict ordering
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ RUN python -m pip install Cython pytest coverage pytest-cov auditwheel doctor-wh
WORKDIR /tmp/compile
ADD . /tmp/compile/

ENV DEBUG=1

RUN python setup.py install && \
chmod ugo+x /tmp/compile/tests/test.sh

Expand Down
9 changes: 9 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,12 @@ There's also a class available for encoding. Use it like you would a normal Pyth

.. autoclass:: minijson.MiniJSONEncoder
:members:

.. warning:: The exact binary content output by :class:`~minijson.MiniJSONEncoder` will
depend on internal Python hash order. To have same dicts return the same representation, you
must use the parameter :code:`use_strict_order` in :class:`~minijson.MiniJSONEncoder`.

:class:`~minijson.MiniJSONEncoder` will then extract the items from the dictionary,
and sort them before dumping them to binary output.

Only then strict order will be guaranteed. Your keys must be comparable anyway.
20 changes: 16 additions & 4 deletions minijson.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -323,18 +323,23 @@ cdef class MiniJSONEncoder:
:param default: a default function used
:param use_double: whether to use doubles instead of floats to represent floating point numbers
:param use_strict_order: if set to True, dictionaries will be encoded by first
dumping them to items and sorting the resulting elements, essentially
two same dicts will be encoded in the same way.
:ivar use_double: (bool) whether to use doubles instead of floats (used when
:meth:`~minijson.MiniJSONEncoder.should_double_be_used` is not overrided)
"""
cdef:
object _default
public bint use_double
public bint use_strict_order

def __init__(self, default: tp.Optional[None] = None,
bint use_double = False):
bint use_double = False,
bint use_strict_order = False):
self._default = default
self.use_double = use_double
self.use_strict_order = use_strict_order

def should_double_be_used(self, y) -> bool:
"""
Expand Down Expand Up @@ -385,6 +390,7 @@ cdef class MiniJSONEncoder:
str field_name
unsigned int length
bytes b_data
list items
if data is None:
cio.write(b'\x08')
return 1
Expand Down Expand Up @@ -508,7 +514,10 @@ cdef class MiniJSONEncoder:
cio.write(b'\x12')
cio.write(STRUCT_L.pack(length))
length = 5
for field_name, elem in data.items():
items = list(data.items())
if self.use_strict_order:
items.sort()
for field_name, elem in items:
cio.write(bytearray([len(field_name)]))
cio.write(field_name.encode('utf-8'))
length += self.dump(elem, cio)
Expand All @@ -529,7 +538,10 @@ cdef class MiniJSONEncoder:
cio.write(STRUCT_L.pack(length))
offset = 5

for key, value in data.items():
items = list(data.items())
if self.use_strict_order:
items.sort()
for key, value in items:
offset += self.dump(key, cio)
offset += self.dump(value, cio)
return offset
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# coding: utf-8
[metadata]
version = 2.6
version = 2.7
name = minijson
long_description = file: README.md
long_description_content_type = text/markdown; charset=UTF-8
Expand Down
5 changes: 5 additions & 0 deletions tests/test_minijson.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

class TestMiniJSON(unittest.TestCase):

def test_encoder_strict_output(self):
enc = MiniJSONEncoder(use_strict_order=True)
enc.encode({"test": "2", "value": 2})
enc.encode({b"test": "2", b"value": 2})

def test_encoder_overrided_default(self):
class Encoder(MiniJSONEncoder):
def default(self, v):
Expand Down

0 comments on commit a9f2ab3

Please sign in to comment.