From 7eb0078ccc33dcc2ebe7cbfb04b1cdd15f47be59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Fri, 13 Aug 2021 17:08:19 +0200
Subject: [PATCH] fixed a bug, v2.10

---
 docs/{changelog.md => changelog.rst} |  7 ++++---
 docs/index.rst                       | 13 +++++++++++--
 minijson.pyx                         | 15 +++++++++------
 setup.cfg                            |  2 +-
 tests/test_minijson.py               | 13 +++++++++++++
 5 files changed, 38 insertions(+), 12 deletions(-)
 rename docs/{changelog.md => changelog.rst} (91%)

diff --git a/docs/changelog.md b/docs/changelog.rst
similarity index 91%
rename from docs/changelog.md
rename to docs/changelog.rst
index b053ff4..cf27b0a 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 bb2ebbe..c10c272 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 a6d9d4b..2b27067 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 157a4b7..49efe8b 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 c0cd29a..22052ae 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})
-- 
GitLab