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