Hello community,

here is the log from the commit of package python-python-rapidjson for 
openSUSE:Factory checked in at 2020-03-10 11:55:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-rapidjson (Old)
 and      /work/SRC/openSUSE:Factory/.python-python-rapidjson.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-python-rapidjson"

Tue Mar 10 11:55:28 2020 rev:6 rq:783263 version:0.9.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-python-rapidjson/python-python-rapidjson.changes
  2019-10-07 14:14:29.626827608 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-python-rapidjson.new.26092/python-python-rapidjson.changes
       2020-03-10 11:55:33.891732318 +0100
@@ -1,0 +2,7 @@
+Tue Mar 10 10:08:12 UTC 2020 - Tomáš Chvátal <[email protected]>
+
+- Update to 0.9.1:
+  * Compatibility fix for Python 3.8 (issue #125)
+  * Fix memory leak in case of failed validation (issue 126)
+
+-------------------------------------------------------------------

Old:
----
  python-rapidjson-0.8.0.tar.gz

New:
----
  python-rapidjson-0.9.1.tar.gz

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

Other differences:
------------------
++++++ python-python-rapidjson.spec ++++++
--- /var/tmp/diff_new_pack.nYz2rF/_old  2020-03-10 11:55:35.947733362 +0100
+++ /var/tmp/diff_new_pack.nYz2rF/_new  2020-03-10 11:55:35.951733365 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-python-rapidjson
 #
-# 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
@@ -19,11 +19,10 @@
 %define skip_python2 1
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-python-rapidjson
-Version:        0.8.0
+Version:        0.9.1
 Release:        0
 Summary:        Python wrapper around rapidjson
 License:        MIT
-Group:          Development/Languages/Python
 URL:            https://github.com/python-rapidjson/python-rapidjson
 Source:         
https://github.com/python-rapidjson/python-rapidjson/archive/v%{version}.tar.gz#/python-rapidjson-%{version}.tar.gz
 Patch0:         rapidjson-system.patch

++++++ python-rapidjson-0.8.0.tar.gz -> python-rapidjson-0.9.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/.appveyor.yml 
new/python-rapidjson-0.9.1/.appveyor.yml
--- old/python-rapidjson-0.8.0/.appveyor.yml    2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/.appveyor.yml    2019-11-13 14:20:44.000000000 
+0100
@@ -17,7 +17,7 @@
 install: "git submodule update --init --recursive"
 
 build_script:
-  - "%PYTHON% -m pip install cibuildwheel==0.10.1"
+  - "%PYTHON% -m pip install cibuildwheel==1.0.0"
   - "%PYTHON% -m cibuildwheel --output-dir wheelhouse"
   - ps: >-
       if ($env:APPVEYOR_REPO_TAG -eq "true") {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/.gitlab-ci.yml 
new/python-rapidjson-0.9.1/.gitlab-ci.yml
--- old/python-rapidjson-0.8.0/.gitlab-ci.yml   2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/.gitlab-ci.yml   2019-11-13 14:20:44.000000000 
+0100
@@ -29,6 +29,6 @@
   script:
     - git submodule update --init --recursive
     - python3 -m venv env
-    - env/bin/pip install cibuildwheel==0.10.1 twine
+    - env/bin/pip install cibuildwheel==1.0.0 twine
     - env/bin/cibuildwheel
     - env/bin/twine upload wheelhouse/*.whl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/.travis.yml 
new/python-rapidjson-0.9.1/.travis.yml
--- old/python-rapidjson-0.8.0/.travis.yml      2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/.travis.yml      2019-11-13 14:20:44.000000000 
+0100
@@ -55,7 +55,7 @@
   # so we remove bytecode files before running it.
   - find . -name __pycache__ -exec rm -rf {} +
   - |
-    pip3 install cibuildwheel==0.10.2
+    pip3 install cibuildwheel==1.0.0
     cibuildwheel --output-dir wheelhouse
     if [[ -n "$TRAVIS_TAG" && -z "$RUN_DEBUG_PYTHON" ]]; then
       pip3 install twine
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/CHANGES.rst 
new/python-rapidjson-0.9.1/CHANGES.rst
--- old/python-rapidjson-0.8.0/CHANGES.rst      2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/CHANGES.rst      2019-11-13 14:20:44.000000000 
+0100
@@ -1,6 +1,30 @@
 Changes
 -------
 
+0.9.1 (2019-11-13)
+~~~~~~~~~~~~~~~~~~
+
+* Fix memory leak in case of failed validation (`issue 126`__)
+
+  __ https://github.com/python-rapidjson/python-rapidjson/issues/126
+
+
+0.9.0 (2019-11-13)
+~~~~~~~~~~~~~~~~~~
+
+* Produce Python 3.8 wheels
+
+* Compatibility fix for Python 3.8 (`issue #125`__)
+
+  __ https://github.com/python-rapidjson/python-rapidjson/issues/125
+
+* New dump option ``write_mode``, supporting RapidJSON's 
``kFormatSingleLineArray`` option
+  (`issue #123`__), thanks to Nguyễn Hồng Quân for the initial implementation 
(`PR #124`__)
+
+  __ https://github.com/python-rapidjson/python-rapidjson/issues/123
+  __ https://github.com/python-rapidjson/python-rapidjson/pull/124
+
+
 0.8.0 (2019-08-09)
 ~~~~~~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/docs/api.rst 
new/python-rapidjson-0.9.1/docs/api.rst
--- old/python-rapidjson-0.8.0/docs/api.rst     2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/docs/api.rst     2019-11-13 14:20:44.000000000 
+0100
@@ -176,6 +176,24 @@
    error location in the (invalid) document.
 
 
+.. rubric:: `write_mode` related constants
+
+.. data:: WM_COMPACT
+
+   The default dump mode, without any extra whitespace.
+
+.. data:: WM_PRETTY
+
+   This selects the RapidJSON ``PrettyWriter``, to produce more readable 
``JSON``: each
+   array's item and object's key will be preceded by a newline, and nested 
structures will
+   be indented.
+
+.. data:: WM_SINGLE_LINE_ARRAY
+
+   This tells the ``PrettyWriter`` to emit arrays on a single line, instead of 
separating
+   items with a newline.
+
+
 .. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601
 .. _RapidJSON: http://rapidjson.org/
 .. _UTC: https://en.wikipedia.org/wiki/Coordinated_Universal_Time
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/docs/dump.rst 
new/python-rapidjson-0.9.1/docs/dump.rst
--- old/python-rapidjson-0.8.0/docs/dump.rst    2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/docs/dump.rst    2019-11-13 14:20:44.000000000 
+0100
@@ -16,9 +16,10 @@
    import io
    from rapidjson import dump, dumps
 
-.. function:: dump(obj, stream, *, skipkeys=False, ensure_ascii=True, 
indent=None, \
-                   default=None, sort_keys=False, number_mode=None, 
datetime_mode=None, \
-                   uuid_mode=None, bytes_mode=BM_UTF8, chunk_size=65536, 
allow_nan=True)
+.. function:: dump(obj, stream, *, skipkeys=False, ensure_ascii=True, \
+                   write_mode=WM_COMPACT, indent=4, default=None, 
sort_keys=False, \
+                   number_mode=None, datetime_mode=None, uuid_mode=None, \
+                   bytes_mode=BM_UTF8, chunk_size=65536, allow_nan=True)
 
    Encode given Python `obj` instance into a ``JSON`` stream.
 
@@ -27,6 +28,7 @@
    :param bool skipkeys: whether skip invalid :class:`dict` keys
    :param bool ensure_ascii: whether the output should contain only ASCII
                              characters
+   :param int write_mode: enable particular pretty print behaviors
    :param int indent: indentation width to produce pretty printed JSON
    :param callable default: a function that gets called for objects that can't
                             otherwise be serialized
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/docs/dumps.rst 
new/python-rapidjson-0.9.1/docs/dumps.rst
--- old/python-rapidjson-0.8.0/docs/dumps.rst   2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/docs/dumps.rst   2019-11-13 14:20:44.000000000 
+0100
@@ -16,11 +16,13 @@
    from rapidjson import (dumps, loads, BM_NONE, BM_UTF8, DM_NONE, DM_ISO8601,
                           DM_UNIX_TIME, DM_ONLY_SECONDS, DM_IGNORE_TZ, 
DM_NAIVE_IS_UTC,
                           DM_SHIFT_TO_UTC, UM_NONE, UM_CANONICAL, UM_HEX, 
NM_NATIVE,
-                          NM_DECIMAL, NM_NAN, PM_NONE, PM_COMMENTS, 
PM_TRAILING_COMMAS)
+                          NM_DECIMAL, NM_NAN, PM_NONE, PM_COMMENTS, 
PM_TRAILING_COMMAS,
+                          WM_COMPACT, WM_PRETTY, WM_SINGLE_LINE_ARRAY)
 
-.. function:: dumps(obj, *, skipkeys=False, ensure_ascii=True, indent=None, \
-                    default=None, sort_keys=False, number_mode=None, 
datetime_mode=None, \
-                    uuid_mode=None, bytes_mode=BM_UTF8, allow_nan=True)
+.. function:: dumps(obj, *, skipkeys=False, ensure_ascii=True, 
write_mode=WM_COMPACT, \
+                    indent=4, default=None, sort_keys=False, number_mode=None, 
\
+                    datetime_mode=None, uuid_mode=None, bytes_mode=BM_UTF8, \
+                    allow_nan=True)
 
    Encode given Python `obj` instance into a ``JSON`` string.
 
@@ -28,6 +30,7 @@
    :param bool skipkeys: whether invalid :class:`dict` keys will be skipped
    :param bool ensure_ascii: whether the output should contain only ASCII
                              characters
+   :param int write_mode: enable particular pretty print behaviors
    :param int indent: indentation width to produce pretty printed JSON
    :param callable default: a function that gets called for objects that can't
                             otherwise be serialized
@@ -75,18 +78,57 @@
       '"The symbol for the Euro currency is €"'
 
 
-   .. _pretty-print:
-   .. rubric:: `indent`
+   .. _write-mode:
+   .. rubric:: `write_mode`
 
-   When `indent` is ``None`` (the default), ``python-rapidjson`` produces the 
most compact
-   JSON representation. By setting `indent` to 0 each array item and each 
dictionary value
-   will be followed by a newline. A positive integer means that each *level* 
will be
-   indented by that many spaces:
+   The `write_mode` controls how ``python-rapidjson`` emits JSON: by default 
it is
+   :data:`WM_COMPACT`, that produces the most compact JSON representation:
 
    .. code-block:: pycon
 
       >>> dumps([1, 2, {'three': 3, 'four': 4}])
       '[1,2,{"four":4,"three":3}]'
+
+   With :data:`WM_PRETTY` it will use ``RapidJSON``\ 's ``PrettyWriter``, with 
a default
+   `indent` (see below) of four spaces:
+
+   .. code-block:: pycon
+
+      >>> print(dumps([1, 2, {'three': 3, 'four': 4}], write_mode=WM_PRETTY))
+      [
+          1,
+          2,
+          {
+              "four": 4,
+              "three": 3
+          }
+      ]
+
+   With :data:`WM_SINGLE_LINE_ARRAY` arrays will be kept on a single line:
+
+   .. code-block:: pycon
+
+      >>> print(dumps([1, 2, 'three', [4, 5]], 
write_mode=WM_SINGLE_LINE_ARRAY))
+      [1, 2, 'three', [4, 5]]
+      >>> print(dumps([1, 2, {'three': 3, 'four': 4}], 
write_mode=WM_SINGLE_LINE_ARRAY))
+      [1, 2, {
+              "three": 3,
+              "four": 4
+          }]
+
+   .. rubric:: `indent`
+
+   The `indent` parameter specifies how many spaces will be used to indent 
nested
+   structures, when the `write_mode` above is not :data:`WM_COMPACT`, and it 
defaults
+   to 4. Specifying a value different from ``None`` automatically sets 
`write_mode` to
+   :data:`WM_PRETTY`, if not explicited.
+
+   By setting `indent` to 0 each array item (when `write_mode` is not
+   :data:`WM_SINGLE_LINE_MODE`) and each dictionary value will be followed by 
a newline. A
+   positive integer means that each *level* will be indented by that many 
spaces:
+
+   .. code-block:: pycon
+
       >>> print(dumps([1, 2, {'three': 3, 'four': 4}], indent=0))
       [
       1,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/docs/encoder.rst 
new/python-rapidjson-0.9.1/docs/encoder.rst
--- old/python-rapidjson-0.8.0/docs/encoder.rst 2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/docs/encoder.rst 2019-11-13 14:20:44.000000000 
+0100
@@ -16,10 +16,11 @@
    from rapidjson import (Decoder, Encoder, BM_NONE, BM_UTF8, DM_NONE, 
DM_ISO8601,
                           DM_UNIX_TIME, DM_ONLY_SECONDS, DM_IGNORE_TZ, 
DM_NAIVE_IS_UTC,
                           DM_SHIFT_TO_UTC, UM_NONE, UM_CANONICAL, UM_HEX, 
NM_NATIVE,
-                          NM_DECIMAL, NM_NAN, PM_NONE, PM_COMMENTS, 
PM_TRAILING_COMMAS)
+                          NM_DECIMAL, NM_NAN, PM_NONE, PM_COMMENTS, 
PM_TRAILING_COMMAS,
+                          WM_COMPACT, WM_PRETTY, WM_SINGLE_LINE_ARRAY)
 
-.. class:: Encoder(skip_invalid_keys=False, ensure_ascii=True, indent=None, \
-                   sort_keys=False, number_mode=None, datetime_mode=None, \
+.. class:: Encoder(skip_invalid_keys=False, ensure_ascii=True, 
write_mode=WM_COMPACT, \
+                   indent=4, sort_keys=False, number_mode=None, 
datetime_mode=None, \
                    uuid_mode=None, bytes_mode=BM_UTF8)
 
    Class-based :func:`dumps`\ -like functionality.
@@ -28,8 +29,8 @@
                                   <skip-invalid-keys>`
    :param bool ensure_ascii: whether the output should contain :ref:`only ASCII
                              characters <ensure-ascii>`
-   :param int indent: indentation width to produce :ref:`pretty printed JSON
-                      <pretty-print>`
+   :param int write_mode: enable particular :ref:`pretty print <write-mode>` 
behaviors
+   :param int indent: indentation width when `write_mode` is not 
:data:`WM_COMPACT`
    :param bool sort_keys: whether dictionary keys should be :ref:`sorted
                           alphabetically <sort-keys>`
    :param int number_mode: enable particular :ref:`behaviors in handling 
numbers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/rapidjson.cpp 
new/python-rapidjson-0.9.1/rapidjson.cpp
--- old/python-rapidjson-0.8.0/rapidjson.cpp    2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/rapidjson.cpp    2019-11-13 14:20:44.000000000 
+0100
@@ -171,6 +171,11 @@
     PM_TRAILING_COMMAS = 1<<1 // allow trailing commas at the end of objects 
and arrays
 };
 
+enum WriteMode {
+    WM_COMPACT = 0,
+    WM_PRETTY = 1<<0,            // Use PrettyWriter
+    WM_SINGLE_LINE_ARRAY = 1<<1  // Format arrays on a single line
+};
 
 //////////////////////////
 // Forward declarations //
@@ -188,13 +193,13 @@
 
 
 static PyObject* do_encode(PyObject* value, bool skipInvalidKeys, PyObject* 
defaultFn,
-                           bool sortKeys, bool ensureAscii, bool prettyPrint,
+                           bool sortKeys, bool ensureAscii, WriteMode 
writeMode,
                            unsigned indent, NumberMode numberMode,
                            DatetimeMode datetimeMode, UuidMode uuidMode,
                            BytesMode bytesMode);
 static PyObject* do_stream_encode(PyObject* value, PyObject* stream, size_t 
chunkSize,
                                   bool skipInvalidKeys, PyObject* defaultFn,
-                                  bool sortKeys, bool ensureAscii, bool 
prettyPrint,
+                                  bool sortKeys, bool ensureAscii, WriteMode 
writeMode,
                                   unsigned indent, NumberMode numberMode,
                                   DatetimeMode datetimeMode, UuidMode uuidMode,
                                   BytesMode bytesMode);
@@ -2267,11 +2272,11 @@
                 writer->Uint64(ui);
             }
         } else {
-            // Mimic stdlib json: subclasses of int may override __str__, but 
we still
+            // Mimic stdlib json: subclasses of int may override __repr__, but 
we still
             // want to encode them as integers in JSON; one example within the 
standard
             // library is IntEnum
 
-            PyObject* intStrObj = PyLong_Type.tp_str(object);
+            PyObject* intStrObj = PyLong_Type.tp_repr(object);
             if (intStrObj == NULL)
                 return false;
 
@@ -2813,7 +2818,7 @@
     PyObject_HEAD
     bool skipInvalidKeys;
     bool ensureAscii;
-    bool prettyPrint;
+    WriteMode writeMode;
     unsigned indent;
     bool sortKeys;
     DatetimeMode datetimeMode;
@@ -2824,9 +2829,9 @@
 
 
 PyDoc_STRVAR(dumps_docstring,
-             "dumps(obj, *, skipkeys=False, ensure_ascii=True, indent=None, 
default=None,"
-             " sort_keys=False, number_mode=None, datetime_mode=None, 
uuid_mode=None,"
-             " bytes_mode=BM_UTF8, allow_nan=True)\n"
+             "dumps(obj, *, skipkeys=False, ensure_ascii=True, 
write_mode=WM_COMPACT,"
+             " indent=4, default=None, sort_keys=False, number_mode=None,"
+             " datetime_mode=None, uuid_mode=None, bytes_mode=BM_UTF8, 
allow_nan=True)\n"
              "\n"
              "Encode a Python object into a JSON string.");
 
@@ -2850,7 +2855,8 @@
     UuidMode uuidMode = UM_NONE;
     PyObject* bytesModeObj = NULL;
     BytesMode bytesMode = BM_UTF8;
-    bool prettyPrint = false;
+    PyObject* writeModeObj = NULL;
+    WriteMode writeMode = WM_COMPACT;
     unsigned indentCharCount = 4;
     int allowNan = -1;
     static char const* kwlist[] = {
@@ -2864,6 +2870,7 @@
         "datetime_mode",
         "uuid_mode",
         "bytes_mode",
+        "write_mode",
 
         /* compatibility with stdlib json */
         "allow_nan",
@@ -2871,7 +2878,7 @@
         NULL
     };
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
"O|$ppOOpOOOOp:rapidjson.dumps",
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
"O|$ppOOpOOOOOp:rapidjson.dumps",
                                      (char**) kwlist,
                                      &value,
                                      &skipKeys,
@@ -2883,6 +2890,7 @@
                                      &datetimeModeObj,
                                      &uuidModeObj,
                                      &bytesModeObj,
+                                     &writeModeObj,
                                      &allowNan))
         return NULL;
 
@@ -2896,7 +2904,7 @@
     }
 
     if (indent && indent != Py_None) {
-        prettyPrint = true;
+        writeMode = WM_PRETTY;
 
         if (PyLong_Check(indent) && PyLong_AsLong(indent) >= 0) {
             indentCharCount = PyLong_AsUnsignedLong(indent);
@@ -2906,6 +2914,21 @@
             return NULL;
         }
     }
+    if (writeModeObj) {
+        if (writeModeObj == Py_None)
+            writeMode = WM_COMPACT;
+        else if (PyLong_Check(writeModeObj)) {
+            int mode = PyLong_AsLong(writeModeObj);
+            if (mode < 0 || mode >= 1<<2) {
+                PyErr_SetString(PyExc_ValueError, "Invalid write_mode");
+                return NULL;
+            }
+            if (mode == WM_COMPACT)
+                writeMode = WM_COMPACT;
+            else if (mode & WM_SINGLE_LINE_ARRAY)
+                writeMode = (WriteMode) (writeMode | WM_SINGLE_LINE_ARRAY);
+        }
+    }
 
     if (numberModeObj) {
         if (numberModeObj == Py_None)
@@ -2977,15 +3000,16 @@
     }
 
     return do_encode(value, skipKeys ? true : false, defaultFn, sortKeys ? 
true : false,
-                     ensureAscii ? true : false, prettyPrint ? true : false,
-                     indentCharCount, numberMode, datetimeMode, uuidMode, 
bytesMode);
+                     ensureAscii ? true : false, writeMode, indentCharCount,
+                     numberMode, datetimeMode, uuidMode, bytesMode);
 }
 
 
 PyDoc_STRVAR(dump_docstring,
-             "dump(obj, stream, *, skipkeys=False, ensure_ascii=True, 
indent=None,"
-             " default=None, sort_keys=False, number_mode=None, 
datetime_mode=None,"
-             " uuid_mode=None, bytes_mode=BM_UTF8, chunk_size=65536, 
allow_nan=True)\n"
+             "dump(obj, stream, *, skipkeys=False, ensure_ascii=True,"
+             " write_mode=WM_COMPACT, indent=4, default=None, sort_keys=False,"
+             " number_mode=None, datetime_mode=None, uuid_mode=None, 
bytes_mode=BM_UTF8,"
+             " chunk_size=65536, allow_nan=True)\n"
              "\n"
              "Encode a Python object into a JSON stream.");
 
@@ -3010,7 +3034,8 @@
     UuidMode uuidMode = UM_NONE;
     PyObject* bytesModeObj = NULL;
     BytesMode bytesMode = BM_UTF8;
-    bool prettyPrint = false;
+    PyObject* writeModeObj = NULL;
+    WriteMode writeMode = WM_COMPACT;
     unsigned indentCharCount = 4;
     PyObject* chunkSizeObj = NULL;
     size_t chunkSize = 65536;
@@ -3028,6 +3053,7 @@
         "uuid_mode",
         "bytes_mode",
         "chunk_size",
+        "write_mode",
 
         /* compatibility with stdlib json */
         "allow_nan",
@@ -3035,7 +3061,7 @@
         NULL
     };
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
"OO|$ppOOpOOOOOp:rapidjson.dump",
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
"OO|$ppOOpOOOOOOp:rapidjson.dump",
                                      (char**) kwlist,
                                      &value,
                                      &stream,
@@ -3049,6 +3075,7 @@
                                      &uuidModeObj,
                                      &bytesModeObj,
                                      &chunkSizeObj,
+                                     &writeModeObj,
                                      &allowNan))
         return NULL;
 
@@ -3062,7 +3089,7 @@
     }
 
     if (indent && indent != Py_None) {
-        prettyPrint = true;
+        writeMode = WM_PRETTY;
 
         if (PyLong_Check(indent) && PyLong_AsLong(indent) >= 0) {
             indentCharCount = PyLong_AsUnsignedLong(indent);
@@ -3072,6 +3099,21 @@
             return NULL;
         }
     }
+    if (writeModeObj) {
+        if (writeModeObj == Py_None)
+            writeMode = WM_COMPACT;
+        else if (PyLong_Check(writeModeObj)) {
+            int mode = PyLong_AsLong(writeModeObj);
+            if (mode < 0 || mode >= 1<<2) {
+                PyErr_SetString(PyExc_ValueError, "Invalid write_mode");
+                return NULL;
+            }
+            if (mode == WM_COMPACT)
+                writeMode = WM_COMPACT;
+            else if (mode & WM_SINGLE_LINE_ARRAY)
+                writeMode = (WriteMode) (writeMode | WM_SINGLE_LINE_ARRAY);
+        }
+    }
 
     if (numberModeObj) {
         if (numberModeObj == Py_None)
@@ -3162,16 +3204,15 @@
 
     return do_stream_encode(value, stream, chunkSize, skipKeys ? true : false,
                             defaultFn, sortKeys ? true : false,
-                            ensureAscii ? true : false, prettyPrint ? true : 
false,
-                            indentCharCount, numberMode, datetimeMode, 
uuidMode,
-                            bytesMode);
+                            ensureAscii ? true : false, writeMode, 
indentCharCount,
+                            numberMode, datetimeMode, uuidMode, bytesMode);
 }
 
 
 PyDoc_STRVAR(encoder_doc,
-             "Encoder(skip_invalid_keys=False, ensure_ascii=True, indent=None,"
-             " sort_keys=False, number_mode=None, datetime_mode=None, 
uuid_mode=None,"
-             " bytes_mode=None)\n\n"
+             "Encoder(skip_invalid_keys=False, ensure_ascii=True, 
write_mode=WM_COMPACT,"
+             " indent=4, sort_keys=False, number_mode=None, 
datetime_mode=None,"
+             " uuid_mode=None, bytes_mode=None)\n\n"
              "Create and return a new Encoder instance.");
 
 
@@ -3258,11 +3299,11 @@
 
 static PyObject*
 do_encode(PyObject* value, bool skipInvalidKeys, PyObject* defaultFn, bool 
sortKeys,
-          bool ensureAscii, bool prettyPrint, unsigned indent,
+          bool ensureAscii, WriteMode writeMode, unsigned indent,
           NumberMode numberMode, DatetimeMode datetimeMode, UuidMode uuidMode,
           BytesMode bytesMode)
 {
-    if (!prettyPrint) {
+    if (writeMode == WM_COMPACT) {
         if (ensureAscii) {
             GenericStringBuffer<ASCII<> > buf;
             Writer<GenericStringBuffer<ASCII<> >, UTF8<>, ASCII<> > 
writer(buf);
@@ -3278,12 +3319,18 @@
         GenericStringBuffer<ASCII<> > buf;
         PrettyWriter<GenericStringBuffer<ASCII<> >, UTF8<>, ASCII<> > 
writer(buf);
         writer.SetIndent(' ', indent);
+        if (writeMode & WM_SINGLE_LINE_ARRAY) {
+            writer.SetFormatOptions(kFormatSingleLineArray);
+        }
         return DUMPS_INTERNAL_CALL;
     }
     else {
         StringBuffer buf;
         PrettyWriter<StringBuffer> writer(buf);
         writer.SetIndent(' ', indent);
+        if (writeMode & WM_SINGLE_LINE_ARRAY) {
+            writer.SetFormatOptions(kFormatSingleLineArray);
+        }
         return DUMPS_INTERNAL_CALL;
     }
 }
@@ -3305,13 +3352,13 @@
 static PyObject*
 do_stream_encode(PyObject* value, PyObject* stream, size_t chunkSize,
                  bool skipInvalidKeys, PyObject* defaultFn, bool sortKeys,
-                 bool ensureAscii, bool prettyPrint, unsigned indent,
+                 bool ensureAscii, WriteMode writeMode, unsigned indent,
                  NumberMode numberMode, DatetimeMode datetimeMode, UuidMode 
uuidMode,
                  BytesMode bytesMode)
 {
     PyWriteStreamWrapper os(stream, chunkSize);
 
-    if (!prettyPrint) {
+    if (writeMode == WM_COMPACT) {
         if (ensureAscii) {
             Writer<PyWriteStreamWrapper, UTF8<>, ASCII<> > writer(os);
             return DUMP_INTERNAL_CALL;
@@ -3324,11 +3371,17 @@
     else if (ensureAscii) {
         PrettyWriter<PyWriteStreamWrapper, UTF8<>, ASCII<> > writer(os);
         writer.SetIndent(' ', indent);
+        if (writeMode & WM_SINGLE_LINE_ARRAY) {
+            writer.SetFormatOptions(kFormatSingleLineArray);
+        }
         return DUMP_INTERNAL_CALL;
     }
     else {
         PrettyWriter<PyWriteStreamWrapper> writer(os);
         writer.SetIndent(' ', indent);
+        if (writeMode & WM_SINGLE_LINE_ARRAY) {
+            writer.SetFormatOptions(kFormatSingleLineArray);
+        }
         return DUMP_INTERNAL_CALL;
     }
 }
@@ -3386,13 +3439,13 @@
             }
         }
         result = do_stream_encode(value, stream, chunkSize, 
e->skipInvalidKeys, defaultFn,
-                                  e->sortKeys, e->ensureAscii, e->prettyPrint, 
e->indent,
+                                  e->sortKeys, e->ensureAscii, e->writeMode, 
e->indent,
                                   e->numberMode, e->datetimeMode, e->uuidMode,
                                   e->bytesMode);
     }
     else {
         result = do_encode(value, e->skipInvalidKeys, defaultFn, e->sortKeys,
-                           e->ensureAscii, e->prettyPrint, e->indent,
+                           e->ensureAscii, e->writeMode, e->indent,
                            e->numberMode, e->datetimeMode, e->uuidMode, 
e->bytesMode);
     }
 
@@ -3419,8 +3472,9 @@
     UuidMode uuidMode = UM_NONE;
     PyObject* bytesModeObj = NULL;
     BytesMode bytesMode = BM_UTF8;
+    PyObject* writeModeObj = NULL;
+    WriteMode writeMode = WM_COMPACT;
     unsigned indentCharCount = 4;
-    bool prettyPrint = false;
 
     static char const* kwlist[] = {
         "skip_invalid_keys",
@@ -3431,10 +3485,11 @@
         "datetime_mode",
         "uuid_mode",
         "bytes_mode",
+        "write_mode",
         NULL
     };
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ppOpOOOO:Encoder",
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ppOpOOOOO:Encoder",
                                      (char**) kwlist,
                                      &skipInvalidKeys,
                                      &ensureAscii,
@@ -3443,11 +3498,12 @@
                                      &numberModeObj,
                                      &datetimeModeObj,
                                      &uuidModeObj,
-                                     &bytesModeObj))
+                                     &bytesModeObj,
+                                     &writeModeObj))
         return NULL;
 
     if (indent && indent != Py_None) {
-        prettyPrint = true;
+        writeMode = WM_PRETTY;
 
         if (PyLong_Check(indent) && PyLong_AsLong(indent) >= 0) {
             indentCharCount = PyLong_AsUnsignedLong(indent);
@@ -3457,6 +3513,21 @@
             return NULL;
         }
     }
+    if (writeModeObj) {
+        if (writeModeObj == Py_None)
+            writeMode = WM_COMPACT;
+        else if (PyLong_Check(writeModeObj)) {
+            int mode = PyLong_AsLong(writeModeObj);
+            if (mode < 0 || mode >= 1<<2) {
+                PyErr_SetString(PyExc_ValueError, "Invalid write_mode");
+                return NULL;
+            }
+            if (mode == WM_COMPACT)
+                writeMode = WM_COMPACT;
+            else if (mode & WM_SINGLE_LINE_ARRAY)
+                writeMode = (WriteMode) (writeMode | WM_SINGLE_LINE_ARRAY);
+        }
+    }
 
     if (numberModeObj) {
         if (numberModeObj == Py_None)
@@ -3527,7 +3598,7 @@
 
     e->skipInvalidKeys = skipInvalidKeys ? true : false;
     e->ensureAscii = ensureAscii ? true : false;
-    e->prettyPrint = prettyPrint;
+    e->writeMode = writeMode;
     e->indent = indentCharCount;
     e->sortKeys = sortKeys ? true : false;
     e->datetimeMode = datetimeMode;
@@ -3652,9 +3723,11 @@
         validator.GetInvalidDocumentPointer().StringifyUriFragment(dptr);
         Py_END_ALLOW_THREADS
 
-        PyErr_SetObject(validation_error,
-                        Py_BuildValue("sss", 
validator.GetInvalidSchemaKeyword(),
-                                      sptr.GetString(), dptr.GetString()));
+        PyObject* error = Py_BuildValue("sss", 
validator.GetInvalidSchemaKeyword(),
+                                        sptr.GetString(), dptr.GetString());
+        PyErr_SetObject(validation_error, error);
+
+        Py_XDECREF(error);
         sptr.Clear();
         dptr.Clear();
 
@@ -3922,6 +3995,10 @@
         || PyModule_AddIntConstant(m, "BM_NONE", BM_NONE)
         || PyModule_AddIntConstant(m, "BM_UTF8", BM_UTF8)
 
+        || PyModule_AddIntConstant(m, "WM_COMPACT", WM_COMPACT)
+        || PyModule_AddIntConstant(m, "WM_PRETTY", WM_PRETTY)
+        || PyModule_AddIntConstant(m, "WM_SINGLE_LINE_ARRAY", 
WM_SINGLE_LINE_ARRAY)
+
         || PyModule_AddStringConstant(m, "__version__", 
STRINGIFY(PYTHON_RAPIDJSON_VERSION))
         || PyModule_AddStringConstant(m, "__author__", "Ken Robbins 
<[email protected]>")
         || PyModule_AddStringConstant(m, "__rapidjson_version__", 
RAPIDJSON_VERSION_STRING))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/tests/test_memory_leaks.py 
new/python-rapidjson-0.9.1/tests/test_memory_leaks.py
--- old/python-rapidjson-0.8.0/tests/test_memory_leaks.py       2019-08-09 
12:57:38.000000000 +0200
+++ new/python-rapidjson-0.9.1/tests/test_memory_leaks.py       2019-11-13 
14:20:44.000000000 +0100
@@ -78,3 +78,46 @@
 
     for stat in top_stats[:10]:
         assert stat.count_diff < 3
+
+
+def test_failed_validation():
+    tracemalloc.start()
+
+    schema = """{
+        "$schema": "http://json-schema.org/draft-04/schema#";,
+        "required": ["id", "name"],
+        "type": "object",
+        "properties": {
+            "id": {"type": "integer"},
+            "name": {"type": "string"}
+        }
+    }""".encode("utf-8")
+
+    obj = """{
+        "id": 50
+    }""".encode("utf-8")
+
+    validate = rj.Validator(schema)
+
+    snapshot1 = tracemalloc.take_snapshot().filter_traces((
+        tracemalloc.Filter(True, __file__),))
+
+    # start the test
+    for j in range(1000):
+        try:
+            validate(obj)
+        except rj.ValidationError:
+            pass
+
+    del j
+
+    gc.collect()
+
+    snapshot2 = tracemalloc.take_snapshot().filter_traces((
+        tracemalloc.Filter(True, __file__),))
+
+    top_stats = snapshot2.compare_to(snapshot1, 'lineno')
+    tracemalloc.stop()
+
+    for stat in top_stats[:10]:
+        assert stat.count_diff < 3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/tests/test_params.py 
new/python-rapidjson-0.9.1/tests/test_params.py
--- old/python-rapidjson-0.8.0/tests/test_params.py     2019-08-09 
12:57:38.000000000 +0200
+++ new/python-rapidjson-0.9.1/tests/test_params.py     2019-11-13 
14:20:44.000000000 +0100
@@ -3,7 +3,7 @@
 # :Author:    Ken Robbins <[email protected]>
 # :License:   MIT License
 # :Copyright: © 2015 Ken Robbins
-# :Copyright: © 2015, 2016, 2017, 2018 Lele Gaifax
+# :Copyright: © 2015, 2016, 2017, 2018, 2019 Lele Gaifax
 #
 
 from calendar import timegm
@@ -180,6 +180,22 @@
 
 
 @pytest.mark.unit
+def test_write_mode(dumps):
+    o = {"a": 1, "b": [2, 3, 4]}
+    expected_compact = ('{"a":1,"b":[2,3,4]}', '{"b":[2,3,4],"a":1}')
+    expected_pretty = ('{\n    "a": 1,\n    "b": [2, 3, 4]\n}',
+                       '{\n    "b": [2, 3, 4],\n    "a": 1\n}')
+
+    assert dumps(o, write_mode=rj.WM_COMPACT) in expected_compact
+    assert dumps(o, indent=0, write_mode=rj.WM_COMPACT) in expected_compact
+    assert dumps(o, write_mode=rj.WM_SINGLE_LINE_ARRAY) in expected_pretty
+    assert dumps(o, write_mode=rj.WM_PRETTY|rj.WM_SINGLE_LINE_ARRAY) in 
expected_pretty
+
+    with pytest.raises(ValueError):
+        dumps(o, write_mode=4)
+
+
[email protected]
 def test_sort_keys(dumps):
     o = {"a": 1, "z": 2, "b": 3}
     expected0 = '{\n"a": 1,\n"b": 3,\n"z": 2\n}'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-rapidjson-0.8.0/version.txt 
new/python-rapidjson-0.9.1/version.txt
--- old/python-rapidjson-0.8.0/version.txt      2019-08-09 12:57:38.000000000 
+0200
+++ new/python-rapidjson-0.9.1/version.txt      2019-11-13 14:20:44.000000000 
+0100
@@ -1 +1 @@
-0.8.0
\ No newline at end of file
+0.9.1
\ No newline at end of file


Reply via email to