Hello community,

here is the log from the commit of package python-json5 for openSUSE:Leap:15.2 
checked in at 2020-04-18 18:41:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-json5 (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.python-json5.new.2738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-json5"

Sat Apr 18 18:41:07 2020 rev:2 rq:795313 version:0.9.4

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/python-json5/python-json5.changes      
2020-03-13 10:56:37.376402498 +0100
+++ /work/SRC/openSUSE:Leap:15.2/.python-json5.new.2738/python-json5.changes    
2020-04-18 18:41:09.469969730 +0200
@@ -1,0 +2,31 @@
+Thu Apr 16 11:47:01 UTC 2020 - [email protected]
+
+- version update to 0.9.4
+  * v0.9.4 (2020-03-26)
+    * [GitHub pull #38](https://github.com/dpranke/pyjson5/pull/38)
+      Fix from [email protected] for dumps() crashing when passed
+      an empty string as a key in an object.
+  * v0.9.3 (2020-03-17)
+    * [GitHub pull #35](https://github.com/dpranke/pyjson5/pull/35)
+      Fix from pastelmind@ for dump() not passing the right args to dumps().
+    * Fix from [email protected] to remove the tests directory from
+      the setup call, making the package a bit smaller.
+  * v0.9.2 (2020-03-02)
+    * [GitHub pull #34](https://github.com/dpranke/pyjson5/pull/34)
+      Fix from roosephu@ for a badly formatted nested list.
+  * v0.9.1 (2020-02-09)
+    * [GitHub issue #33](https://github.com/dpranke/pyjson5/issues/33):
+       Fix stray trailing comma when dumping an object with an invalid key.
+  * v0.9.0 (2020-01-30)
+    * [GitHub issue #29](https://github.com/dpranke/pyjson5/issues/29):
+       Fix an issue where objects keys that started with a reserved
+       word were incorrectly quoted.
+    * [GitHub issue #30](https://github.com/dpranke/pyjson5/issues/30):
+       Fix an issue where dumps() incorrectly thought a data structure
+       was cyclic in some cases.
+    * [GitHub issue #32](https://github.com/dpranke/pyjson5/issues/32):
+       Allow for non-string keys in dicts passed to ``dump()``/``dumps()``.
+       Add an ``allow_duplicate_keys=False`` to prevent possible
+       ill-formed JSON that might result.
+
+-------------------------------------------------------------------

Old:
----
  pyjson5-0.8.5.tar.gz

New:
----
  pyjson5-0.9.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-json5.spec ++++++
--- /var/tmp/diff_new_pack.nZUouH/_old  2020-04-18 18:41:09.825970481 +0200
+++ /var/tmp/diff_new_pack.nZUouH/_new  2020-04-18 18:41:09.829970490 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-json5
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,23 +12,25 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-json5
-Version:        0.8.5
+Version:        0.9.4
 Release:        0
-License:        Apache-2.0
 Summary:        A Python implementation of the JSON5 data format
-Url:            https://github.com/dpranke/pyjson5
+License:        Apache-2.0
 Group:          Development/Languages/Python
+URL:            https://github.com/dpranke/pyjson5
 Source:         
https://github.com/dpranke/pyjson5/archive/v%{version}.tar.gz#/pyjson5-%{version}.tar.gz
+BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
+Requires:       python-setuptools
 BuildArch:      noarch
-
 %python_subpackages
 
 %description
@@ -42,7 +44,6 @@
   * Objects and arrays may end with trailing commas.
   * Strings can be single-quoted, and multi-line string literals are allowed.
 
-
 %prep
 %setup -q -n pyjson5-%{version}
 
@@ -55,7 +56,7 @@
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-%python_exec setup.py test
+%pytest
 
 %files %{python_files}
 %doc README.md

++++++ pyjson5-0.8.5.tar.gz -> pyjson5-0.9.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyjson5-0.8.5/README.md new/pyjson5-0.9.4/README.md
--- old/pyjson5-0.8.5/README.md 2019-07-05 04:18:45.000000000 +0200
+++ new/pyjson5-0.9.4/README.md 2020-03-27 00:12:33.000000000 +0100
@@ -52,17 +52,51 @@
 
 ## Version History / Release Notes
 
+* v0.9.4 (2020-03-26)
+    * [GitHub pull #38](https://github.com/dpranke/pyjson5/pull/38)
+      Fix from [email protected] for dumps() crashing when passed
+      an empty string as a key in an object.
+
+* v0.9.3 (2020-03-17)
+    * [GitHub pull #35](https://github.com/dpranke/pyjson5/pull/35)
+      Fix from pastelmind@ for dump() not passing the right args to dumps().
+    * Fix from [email protected] to remove the tests directory from
+      the setup call, making the package a bit smaller.
+
+* v0.9.2 (2020-03-02)
+    * [GitHub pull #34](https://github.com/dpranke/pyjson5/pull/34)
+      Fix from roosephu@ for a badly formatted nested list.
+
+* v0.9.1 (2020-02-09)
+    * [GitHub issue #33](https://github.com/dpranke/pyjson5/issues/33):
+       Fix stray trailing comma when dumping an object with an invalid key.
+
+* v0.9.0 (2020-01-30)
+    * [GitHub issue #29](https://github.com/dpranke/pyjson5/issues/29):
+       Fix an issue where objects keys that started with a reserved
+       word were incorrectly quoted.
+    * [GitHub issue #30](https://github.com/dpranke/pyjson5/issues/30):
+       Fix an issue where dumps() incorrectly thought a data structure
+       was cyclic in some cases.
+    * [GitHub issue #32](https://github.com/dpranke/pyjson5/issues/32):
+       Allow for non-string keys in dicts passed to ``dump()``/``dumps()``.
+       Add an ``allow_duplicate_keys=False`` to prevent possible
+       ill-formed JSON that might result.
+
 * v0.8.5 (2019-07-04)
-     * [GitHub issue #25](https://github.com/dpranke/pyjson5/issues/25):
-       Add LICENSE and README.md to the dist.
-     * [GitHub issue #26](https://github.com/dpranke/pyjson5/issues/26):
-       Fix printing of empty arrays and objects with indentation, fix
-       misreporting of the position on parse failures in some cases.
+    * [GitHub issue #25](https://github.com/dpranke/pyjson5/issues/25):
+      Add LICENSE and README.md to the dist.
+    * [GitHub issue #26](https://github.com/dpranke/pyjson5/issues/26):
+      Fix printing of empty arrays and objects with indentation, fix
+      misreporting of the position on parse failures in some cases.
+
 * v0.8.4 (2019-06-11)
     * Updated the version history, too.
+
 * v0.8.3 (2019-06-11)
     * Tweaked the README, bumped the version, forgot to update the version
       history :).
+
 * v0.8.2 (2019-06-11)
     * Actually bump the version properly, to 0.8.2.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyjson5-0.8.5/json5/lib.py 
new/pyjson5-0.9.4/json5/lib.py
--- old/pyjson5-0.8.5/json5/lib.py      2019-07-05 04:18:45.000000000 +0200
+++ new/pyjson5-0.9.4/json5/lib.py      2020-03-27 00:12:33.000000000 +0100
@@ -140,156 +140,248 @@
     raise Exception('unknown el: ' + el)  # pragma: no cover
 
 
-def dumps(obj, quote_keys=False, trailing_commas=True, **kwargs):
-    """Serialize ``obj`` to a JSON5-formatted ``str``.
+def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
+         allow_nan=True, cls=None, indent=None, separators=None,
+         default=None, sort_keys=False,
+         quote_keys=False, trailing_commas=True,
+         allow_duplicate_keys=True,
+         **kwargs):
+    """Serialize ``obj`` to a JSON5-formatted stream to ``fp`` (a ``.write()``-
+    supporting file-like object).
 
     Supports the same arguments as ``json.dumps()``, except that:
 
     - The ``cls`` keyword is not supported.
-    - The ``encoding`` keyword is ignored; Unicode strings are always returned.
+    - The ``encoding`` keyword is ignored; Unicode strings are always written.
     - By default, object keys that are legal identifiers are not quoted;
       if you pass quote_keys=True, they will be.
     - By default, if lists and objects span multiple lines of output (i.e.,
       when ``indent`` >=0), the last item will have a trailing comma
       after it. If you pass ``trailing_commas=False, it will not.
-
-    Calling ``dumps(obj, quote_keys=True, trailing_commas=False)`` should
-    produce exactly the same output as ``json.dumps(obj).``
+    - If you use a number, a boolean, or None as a key value in a dict,
+      it will be converted to the corresponding json string value, e.g.
+      "1", "true", or "null". By default, dump() will match the `json`
+      modules behavior and produce ill-formed JSON if you mix keys of
+      different types that have the same converted value, e.g.:
+      {1: "foo", "1": "bar"} produces '{"1": "foo", "1": "bar"}', an
+      object with duplicated keys. If you pass allow_duplicate_keys=False,
+      an exception will be raised instead.
+
+    Calling ``dumps(obj, fp, quote_keys=True, trailing_commas=False,
+                    allow_duplicate_keys=True)``
+    should produce exactly the same output as ``json.dumps(obj, fp).``
     """
 
-    assert kwargs.get('cls', None) is None, 'Custom encoders are not supported'
+    fp.write(str(dumps(obj=obj, skipkeys=skipkeys, ensure_ascii=ensure_ascii,
+                       check_circular=check_circular, allow_nan=allow_nan,
+                       cls=cls, indent=indent, separators=separators,
+                       default=default, sort_keys=sort_keys,
+                       quote_keys=quote_keys, trailing_commas=trailing_commas,
+                       allow_duplicate_keys=allow_duplicate_keys)))
 
-    if kwargs.get('check_circular', True):
-        seen = set()
-    else:
-        seen = None
-    return _dumps(obj, seen, quote_keys=quote_keys,
-                  trailing_commas=trailing_commas,
-                  **kwargs)
 
-
-def dump(obj, fp, quote_keys=False, trailing_commas=True, **kwargs):
-    """Serialize ``obj`` to a JSON5-formatted stream to ``fp`` (a ``.write()``-
-    supporting file-like object).
+def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
+          allow_nan=True, cls=None, indent=None, separators=None,
+          default=None, sort_keys=False,
+          quote_keys=False, trailing_commas=True, allow_duplicate_keys=True,
+          **kwargs):
+    """Serialize ``obj`` to a JSON5-formatted ``str``.
 
     Supports the same arguments as ``json.dumps()``, except that:
 
     - The ``cls`` keyword is not supported.
-    - The ``encoding`` keyword is ignored; Unicode strings are always written.
+    - The ``encoding`` keyword is ignored; Unicode strings are always returned.
     - By default, object keys that are legal identifiers are not quoted;
       if you pass quote_keys=True, they will be.
     - By default, if lists and objects span multiple lines of output (i.e.,
       when ``indent`` >=0), the last item will have a trailing comma
       after it. If you pass ``trailing_commas=False, it will not.
+    - If you use a number, a boolean, or None as a key value in a dict,
+      it will be converted to the corresponding json string value, e.g.
+      "1", "true", or "null". By default, dump() will match the ``json``
+      module's behavior and produce ill-formed JSON if you mix keys of
+      different types that have the same converted value, e.g.:
+      {1: "foo", "1": "bar"} produces '{"1": "foo", "1": "bar"}', an
+      object with duplicated keys. If you pass ``allow_duplicate_keys=False``,
+      an exception will be raised instead.
+
 
-    Calling ``dumps(obj, fp, quote_keys=True, trailing_commas=False)`` should
-    produce exactly the same output as ``json.dumps(obj, fp).``
+    Calling ``dumps(obj, quote_keys=True, trailing_commas=False,
+                    allow_duplicate_keys=True)``
+    should produce exactly the same output as ``json.dumps(obj).``
     """
 
-    s = dumps(obj, quote_keys=quote_keys, trailing_commas=trailing_commas,
-              **kwargs)
-    fp.write(str(s))
+    assert kwargs.get('cls', None) is None, 'Custom encoders are not supported'
+
+    if separators is None:
+        if indent is None:
+            separators = (u', ', u': ')
+        else:
+            separators = (u',', u': ')
+
+    default = default or _raise_type_error
+
+    if check_circular:
+        seen = set()
+    else:
+        seen = None
+
+    level = 1
+    is_key = False
 
+    _, v = _dumps(obj, skipkeys, ensure_ascii, check_circular,
+                  allow_nan, indent, separators, default, sort_keys,
+                  quote_keys, trailing_commas, allow_duplicate_keys,
+                  seen, level, is_key)
+    return v
 
-def _dumps(obj, seen, **kwargs):
+
+def _dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, indent,
+           separators, default, sort_keys,
+           quote_keys, trailing_commas, allow_duplicate_keys,
+           seen, level, is_key):
+    s = None
     if obj is True:
-        return u'true'
+        s = u'true'
     if obj is False:
-        return u'false'
+        s = u'false'
     if obj is None:
-        return u'null'
+        s = u'null'
 
     t = type(obj)
     if t == type('') or t == type(u''):
-        return _dump_str(obj, kwargs.get('ensure_ascii', True))
+        if (is_key and _is_ident(obj) and not quote_keys
+            and not _is_reserved_word(obj)):
+            return True, obj
+        return True, _dump_str(obj, ensure_ascii)
     if t is float:
-        return _dump_float(obj, kwargs.get('allow_nan', True))
+        s = _dump_float(obj,allow_nan)
     if t is int:
-        return str(obj)
+        s = str(obj)
 
-    if seen is not None:
-        i = id(obj)
-        if i in seen:
-            raise ValueError('Circular reference detected.')
-        else:
-            seen.add(i)
+    if is_key:
+        if s is not None:
+            return True, '"%s"' % s
+        if skipkeys:
+            return False, None
+        raise TypeError('invalid key %s' % repr(obj))
+
+    if s is not None:
+        return True, s
 
-    indent = kwargs.get('indent', None)
-    if indent is None:
-        separators = kwargs.get('separators', (u', ', u': '))
-    else:
-        separators = kwargs.get('separators', (u',', u': '))
     if indent is not None:
-        level = kwargs.get('level', 1)
-        nl = '\n'
+        end_str = ''
+        if trailing_commas:
+            end_str = ','
         if type(indent) == int:
             if indent > 0:
-                indent = ' ' * indent
+                indent_str = '\n' + ' ' * indent * level
+                end_str += '\n' + ' ' * indent * (level - 1)
             else:
-                indent = ''
+                indent_str = '\n'
+                end_str += '\n'
+        else:
+            indent_str = '\n' + indent * level
+            end_str += '\n' + indent * (level - 1)
     else:
-        indent = ''
-        level = 0
-        nl = ''
+        indent_str = ''
+        end_str = ''
 
     item_sep, kv_sep = separators
-    indent_str = nl + indent * level
-    if nl and kwargs.get('trailing_commas', True):
-        end_str = ',' + nl + indent * (level - 1)
-    else:
-        end_str = nl + indent * (level - 1)
-
     item_sep += indent_str
-    kwargs['level'] = level + 1
+    level += 1
 
-    # In Python3, we'd check if this was an abc.Mapping.
-    # For now, just check for the attrs we need to iterate over the object.
-    if hasattr(t, 'keys') and hasattr(t, '__getitem__'):
-        return _dump_dict(obj, seen, item_sep, kv_sep, indent_str, end_str,
-                          **kwargs)
+    if seen is not None:
+        i = id(obj)
+        if i in seen:
+            raise ValueError('Circular reference detected.')
+        else:
+            seen.add(i)
 
-    # In Python3, we'd check if this was an abc.Sequence.
+    # In Python3, we'd check if this was an abc.Mapping or an abc.Sequence.
     # For now, just check for the attrs we need to iterate over the object.
-    if hasattr(t, '__getitem__') and hasattr(t, '__iter__'):
-        if not obj:
-            return u'[]'
-        return (u'[' + indent_str +
-                item_sep.join([_dumps(el, seen, **kwargs) for el in obj]) +
-                end_str + u']')
+    if hasattr(t, 'keys') and hasattr(t, '__getitem__'):
+        s = _dump_dict(obj, skipkeys, ensure_ascii,
+                       check_circular, allow_nan, indent,
+                       separators, default, sort_keys,
+                       quote_keys, trailing_commas,
+                       allow_duplicate_keys, seen, level,
+                       item_sep, kv_sep, indent_str, end_str)
+    elif hasattr(t, '__getitem__') and hasattr(t, '__iter__'):
+        s = _dump_array(obj, skipkeys, ensure_ascii,
+                        check_circular, allow_nan, indent,
+                        separators, default, sort_keys,
+                        quote_keys, trailing_commas,
+                        allow_duplicate_keys, seen, level,
+                        item_sep, indent_str, end_str)
+    else:
+        s = default(obj)
 
-    return kwargs.get('default', _raise_type_error)(obj)
+    if seen is not None:
+        seen.remove(i)
+    return False, s
 
 
-def _dump_dict(obj, seen, item_sep, kv_sep, indent_str, end_str, **kwargs):
+def _dump_dict(obj, skipkeys, ensure_ascii, check_circular, allow_nan,
+               indent, separators, default, sort_keys,
+               quote_keys, trailing_commas, allow_duplicate_keys,
+               seen, level, item_sep, kv_sep, indent_str, end_str):
     if not obj:
         return u'{}'
 
-    if kwargs.get('sort_keys', False):
+    if sort_keys:
         keys = sorted(obj.keys())
     else:
         keys = obj.keys()
 
     s = u'{' + indent_str
 
-    skipkeys = kwargs.get('skipkeys', False)
-    ensure_ascii = kwargs.get('ensure_ascii', True)
-    quote_keys = kwargs.get('quote_keys', False)
-    first_item = True
+    num_items_added = 0
+    new_keys = set()
     for key in keys:
-        valid_key, key_str = _dumpkey(key, ensure_ascii, quote_keys)
+        valid_key, key_str = _dumps(key, skipkeys, ensure_ascii, 
check_circular,
+                                    allow_nan, indent, separators, default,
+                                    sort_keys,
+                                    quote_keys, trailing_commas,
+                                    allow_duplicate_keys,
+                                    seen, level, is_key=True)
         if valid_key:
-            if not first_item:
+            if not allow_duplicate_keys:
+                if key_str in new_keys:
+                    raise ValueError('duplicate key %s' % repr(key))
+                else:
+                    new_keys.add(key_str)
+            if num_items_added:
                 s += item_sep
-            s += key_str + kv_sep + _dumps(obj[key], seen, **kwargs)
-            first_item = False
-        elif skipkeys:
-            continue
-        else:
+            s += key_str + kv_sep + _dumps(obj[key], skipkeys, ensure_ascii,
+                                           check_circular, allow_nan, indent,
+                                           separators, default, sort_keys,
+                                           quote_keys, trailing_commas,
+                                           allow_duplicate_keys,
+                                           seen, level, is_key=False)[1]
+            num_items_added += 1
+        elif not skipkeys:
             raise TypeError('invalid key %s' % repr(key))
+
     s += end_str + u'}'
     return s
 
 
+def _dump_array(obj, skipkeys, ensure_ascii, check_circular, allow_nan,
+                indent, separators, default, sort_keys,
+                quote_keys, trailing_commas, allow_duplicate_keys,
+                seen, level, item_sep, indent_str, end_str):
+    if not obj:
+        return u'[]'
+    return (u'[' + indent_str +
+            item_sep.join([_dumps(el, skipkeys, ensure_ascii, check_circular,
+                                  allow_nan, indent, separators, default,
+                                  sort_keys, quote_keys, trailing_commas,
+                                  allow_duplicate_keys,
+                                  seen, level, False)[1] for el in obj]) +
+            end_str + u']')
+
+
 def _dump_float(obj, allow_nan):
     if allow_nan:
         if math.isnan(obj):
@@ -304,14 +396,6 @@
     return str(obj)
 
 
-def _dumpkey(k, ensure_ascii, quote_keys):
-    if type(k) in (int, float, type(''), long, type(u'')) or k is None:
-        if not quote_keys and _is_ident(k) and not _is_reserved_word(k):
-            return True, k
-        return True, _dump_str(k, ensure_ascii)
-    return False, ''
-
-
 def _dump_str(obj, ensure_ascii):
     ret = ['"']
     for ch in obj:
@@ -355,13 +439,14 @@
 
 def _is_ident(k):
     k = str(k)
-    if not _is_id_start(k[0]) and k[0] not in (u'$', u'_'):
+    if not k or not _is_id_start(k[0]) and k[0] not in (u'$', u'_'):
         return False
     for ch in k[1:]:
         if not _is_id_continue(ch) and ch not in (u'$', u'_'):
             return False
     return True
 
+
 def _is_id_start(ch):
     return unicodedata.category(ch) in (
         'Lu', 'Ll', 'Li', 'Lt', 'Lm', 'Lo', 'Nl')
@@ -379,7 +464,7 @@
 
     if _reserved_word_re is None:
         # List taken from section 7.6.1 of ECMA-262.
-        _reserved_word_re = re.compile('|'.join([
+        _reserved_word_re = re.compile('(' + '|'.join([
             'break',
             'case',
             'catch',
@@ -416,7 +501,7 @@
             'void',
             'while',
             'with',
-        ]))
+        ]) + ')$')
     return _reserved_word_re.match(k) is not None
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyjson5-0.8.5/json5/version.py 
new/pyjson5-0.9.4/json5/version.py
--- old/pyjson5-0.8.5/json5/version.py  2019-07-05 04:18:45.000000000 +0200
+++ new/pyjson5-0.9.4/json5/version.py  2020-03-27 00:12:33.000000000 +0100
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-VERSION = '0.8.5'
+VERSION = '0.9.4'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyjson5-0.8.5/setup.py new/pyjson5-0.9.4/setup.py
--- old/pyjson5-0.8.5/setup.py  2019-07-05 04:18:45.000000000 +0200
+++ new/pyjson5-0.9.4/setup.py  2020-03-27 00:12:33.000000000 +0100
@@ -29,8 +29,7 @@
 
 setup(
     name='json5',
-    packages=find_packages(),
-    package_data={'': ['../README.md']},
+    packages=find_packages(exclude=['tests']),
     entry_points={
         'console_scripts': [
             'pyjson5=json5.tool:main',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyjson5-0.8.5/tests/lib_test.py 
new/pyjson5-0.9.4/tests/lib_test.py
--- old/pyjson5-0.8.5/tests/lib_test.py 2019-07-05 04:18:45.000000000 +0200
+++ new/pyjson5-0.9.4/tests/lib_test.py 2020-03-27 00:12:33.000000000 +0100
@@ -245,24 +245,56 @@
     def check(self, obj, s):
         self.assertEqual(json5.dumps(obj), s)
 
+    def test_allow_duplicate_keys(self):
+        self.assertIn(json5.dumps({1: "foo", "1": "bar"}),
+                      {'{"1": "foo", "1": "bar"}',
+                       '{"1": "bar", "1": "foo"}'})
+
+        self.assertRaises(ValueError, json5.dumps,
+                          {1: "foo", "1": "bar"},
+                           allow_duplicate_keys=False)
+
     def test_arrays(self):
         self.check([], '[]')
         self.check([1, 2, 3], '[1, 2, 3]')
+        self.check([{'foo': 'bar'}, {'baz': 'quux'}],
+                    '[{foo: "bar"}, {baz: "quux"}]')
 
     def test_bools(self):
         self.check(True, 'true')
         self.check(False, 'false')
 
     def test_check_circular(self):
+        # This tests a trivial cycle.
         l = [1, 2, 3]
         l[2] = l
         self.assertRaises(ValueError, json5.dumps, l)
+
+        # This checks that json5 doesn't raise an error. However,
+        # the underlying Python implementation likely will.
         try:
             json5.dumps(l, check_circular=False)
             self.fail()  # pragma: no cover
         except Exception as e:
             self.assertNotIn(str(e), 'Circular reference detected')
 
+        # This checks that repeated but non-circular references
+        # are okay.
+        x = [1, 2]
+        y = {"foo": x, "bar": x}
+        self.check(y,
+                   '{foo: [1, 2], bar: [1, 2]}')
+
+        # This tests a more complicated cycle.
+        x = {}
+        y = {}
+        z = {}
+        z['x'] = x
+        z['y'] = y
+        z['x']['y'] = y
+        z['y']['x'] = x
+        self.assertRaises(ValueError, json5.dumps, z)
+
     def test_default(self):
 
         def _custom_serializer(obj):
@@ -293,6 +325,8 @@
                          u'[\n 1,\n 2,\n 3,\n]')
         self.assertEqual(json5.dumps([1, 2, 3], indent='++'),
                          u'[\n++1,\n++2,\n++3,\n]')
+        self.assertEqual(json5.dumps([[1, 2, 3]], indent=2),
+                         u'[\n  [\n    1,\n    2,\n    3,\n  ],\n]')
 
         self.assertEqual(json5.dumps({}, indent=2),
                          u'{}')
@@ -320,6 +354,13 @@
     def test_reserved_words_in_object_keys_are_quoted(self):
         self.check({'new': 1}, '{"new": 1}')
 
+    def 
test_identifiers_only_starting_with_reserved_words_are_not_quoted(self):
+        self.check({'newbie': 1}, '{newbie: 1}')
+
+    def test_non_string_keys(self):
+        self.assertEqual(json5.dumps({False: 'a', 1: 'b', 2.0: 'c', None: 
'd'}),
+                         '{"false": "a", "1": "b", "2.0": "c", "null": "d"}')
+
     def test_quote_keys(self):
         self.assertEqual(json5.dumps({"foo": 1}, quote_keys=True),
                          '{"foo": 1}')
@@ -335,9 +376,21 @@
                    '"\\u2028\\u2029\\b\\t\\f\\n\\r\\v\\\\\\0"')
 
     def test_skip_keys(self):
-        self.assertRaises(TypeError, json5.dumps, {"foo": 1, (1, 2): 2})
-        self.assertEqual(json5.dumps({"foo": 1, (1, 2): 2}, skipkeys=True),
-                         '{foo: 1}')
+        od = OrderedDict()
+        od[(1, 2)] = 2
+        self.assertRaises(TypeError, json5.dumps, od)
+        self.assertEqual(json5.dumps(od, skipkeys=True), '{}')
+
+        od['foo'] = 1
+        self.assertEqual(json5.dumps(od, skipkeys=True), '{foo: 1}')
+
+        # Also test that having an invalid key as the last element
+        # doesn't incorrectly add a trailing comma (see
+        # https://github.com/dpranke/pyjson5/issues/33).
+        od = OrderedDict()
+        od['foo'] = 1
+        od[(1, 2)] = 2
+        self.assertEqual(json5.dumps(od, skipkeys=True), '{foo: 1}')
 
     def test_sort_keys(self):
         od = OrderedDict()
@@ -369,6 +422,9 @@
             # we can't test this there.
             pass
 
+    def test_empty_key(self):
+        self.assertEqual(json5.dumps({'': 'value'}), '{"": "value"}')
+
 
 if __name__ == '__main__':  # pragma: no cover
     unittest.main()


Reply via email to