diff --git a/docs/changelog.md b/docs/changelog.rst similarity index 91% rename from docs/changelog.md rename to docs/changelog.rst index b053ff41a8c702ff27d1517cbb91d163db9424c4..cf27b0a5eddd9574c79dbdb1f13dcbacf830071d 100644 --- a/docs/changelog.md +++ b/docs/changelog.rst @@ -1,10 +1,11 @@ Changelog ========= -Next version ------------- +v2.10 +----- -* _TBA_ +* fixed a bug in which if :meth:`minijson.MiniJSONEncoder.default` + returned a bytes object or a boolean, it would be classified as an invalid value. v2.9 ---- diff --git a/docs/index.rst b/docs/index.rst index bb2ebbeb843cca083c93ea7d6b63be097e81fec2..c10c272d415a88fc00c9e3ac4386dd7ec6342172 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,12 +14,21 @@ Welcome to MiniJSON's documentation! specification changelog -MiniJSON is a space-aware binary format for representing arbitary JSON. + +MiniJSON is a space-aware binary format for representing arbitary superset JSON. It's however most efficient when dealing with short (less than 16 elements) lists and objects, whose all keys are strings. +By superset I mean anything that is correct JSON, including binary strings, which JSON +doesn't code for. + You should avoid objects with keys different than strings, since they will always use a -4-byte length field. This is to be improved in a future release. +4-byte length field. This is to be improved in a future release. Key not being strings +is anyway invalid JSON_. + + +.. _JSON: https://www.w3schools.com/js/js_json_objects.asp + Indices and tables ================== diff --git a/minijson.pyx b/minijson.pyx index a6d9d4b3e6ae0acf6ec4ca5022013bd40da526dd..2b27067b22e1c0d1489572ff91d26a67c8751bdb 100644 --- a/minijson.pyx +++ b/minijson.pyx @@ -301,8 +301,8 @@ cpdef object loads(object data): return parse(data, 0)[1] -cdef inline bint is_jsonable(y): - return y is None or isinstance(y, (int, float, str, dict, list, tuple)) +cdef inline bint is_minijsonable(y): + return y is None or isinstance(y, (int, float, str, dict, list, tuple, bool, bytes)) cdef class MiniJSONEncoder: @@ -344,13 +344,16 @@ cdef class MiniJSONEncoder: def default(self, v): """ - Convert an object to a JSON-able representation. + Convert an object to a MiniJSON-able representation. + + A MiniJSONable representation is a dict, tuple, list, float, int, None, + a bool or a bytes. Overload this to provide your default function in other way that giving the callable as a parameter. :param v: object to convert - :return: a JSONable representation + :return: a Mini-JSONable representation """ if self._default is None: raise EncodingError('Unknown value type %s' % (v, )) @@ -542,8 +545,8 @@ cdef class MiniJSONEncoder: return offset else: v = self.default(data) - if not is_jsonable(v): - raise EncodingError('default returned a non-JSONable value!') + if not is_minijsonable(v): + raise EncodingError('default returned a non-MiniJSONable value!') return self.dump(v, cio) diff --git a/setup.cfg b/setup.cfg index 157a4b7383417e6fda75e5f231359fb5ff69fd1e..49efe8b380d2ace44a7a8d5786a0c6676bd09d65 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ # coding: utf-8 [metadata] -version = 2.10a1 +version = 2.10 name = minijson long_description = file: README.md long_description_content_type = text/markdown; charset=UTF-8 diff --git a/tests/test_minijson.py b/tests/test_minijson.py index c0cd29a42fbdc4b4cdf73e91743d9677ef00b849..22052aefcbad61a8e89578ca8be8256ee5b2c8d2 100644 --- a/tests/test_minijson.py +++ b/tests/test_minijson.py @@ -145,6 +145,19 @@ class TestMiniJSON(unittest.TestCase): self.assertEqual(loads(b), 4.5) switch_default_float() + + def test_minijson_encoder_returns_a_bool_and_a_bytes(self): + class Encoder(MiniJSONEncoder): + def default(self, v): + if isinstance(v, complex): + return True + else: + return b'test' + + e = Encoder() + e.encode(3+4j) + e.encode(object()) + def test_booleans(self): self.assertSameAfterDumpsAndLoads({'test': True, 'test2': False})