Hello community, here is the log from the commit of package python-simplejson for openSUSE:Factory checked in at 2016-12-02 16:38:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-simplejson (Old) and /work/SRC/openSUSE:Factory/.python-simplejson.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-simplejson" Changes: -------- --- /work/SRC/openSUSE:Factory/python-simplejson/python-simplejson.changes 2015-05-18 22:59:36.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-simplejson.new/python-simplejson.changes 2016-12-02 16:38:57.000000000 +0100 @@ -1,0 +2,23 @@ +Fri Nov 18 22:41:28 UTC 2016 - dmueller@suse.com + +- update to 3.8.2: +* Fix implicit cast compiler warning in _speedups.c +* simplejson is now available as wheels for OS X and Windows thanks to Travis-CI + and AppVeyor respectively! Many thanks to @aebrahim for getting this party + started. +* Fix issue with iterable_as_array and indent option +* Fix typo in keyword argument name introduced in 3.8.0 +* New iterable_as_array encoder option to perform lazy serialization of + any iterable objects, without having to convert to tuple or list. +* Fix typo introduced in 3.7.0 (behavior should be indistinguishable) + https://github.com/simplejson/simplejson/commit/e18cc09b688ea1f3305c27616fd3... +* Do not cache Decimal class in encoder, only reference the decimal module. + This may make reload work in more common scenarios. +* Fix compilation with MSVC + https://github.com/simplejson/simplejson/pull/119 +* simplejson no longer trusts custom str/repr methods for int, long, float + subclasses. These instances are now formatted as if they were exact + instances of those types. + https://github.com/simplejson/simplejson/issues/118 + +------------------------------------------------------------------- Old: ---- simplejson-3.6.5.tar.gz New: ---- simplejson-3.8.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-simplejson.spec ++++++ --- /var/tmp/diff_new_pack.EeH7zj/_old 2016-12-02 16:38:58.000000000 +0100 +++ /var/tmp/diff_new_pack.EeH7zj/_new 2016-12-02 16:38:58.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-simplejson # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python-simplejson -Version: 3.6.5 +Version: 3.8.2 Release: 0 Url: http://github.com/simplejson/simplejson Summary: Simple, fast, extensible JSON encoder/decoder for Python ++++++ simplejson-3.6.5.tar.gz -> simplejson-3.8.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/CHANGES.txt new/simplejson-3.8.2/CHANGES.txt --- old/simplejson-3.6.5/CHANGES.txt 2014-10-24 17:13:39.000000000 +0200 +++ new/simplejson-3.8.2/CHANGES.txt 2016-02-15 19:02:14.000000000 +0100 @@ -1,3 +1,46 @@ +Version 3.8.2 released 2016-02-14 + +* Fix implicit cast compiler warning in _speedups.c +* simplejson is now available as wheels for OS X and Windows thanks to Travis-CI + and AppVeyor respectively! Many thanks to @aebrahim for getting this party + started. + https://github.com/simplejson/simplejson/pull/130 + https://github.com/simplejson/simplejson/issues/122 + +Version 3.8.1 released 2015-10-27 + +* Fix issue with iterable_as_array and indent option + https://github.com/simplejson/simplejson/issues/128 +* Fix typo in keyword argument name introduced in 3.8.0 + https://github.com/simplejson/simplejson/pull/123 + +Version 3.8.0 released 2015-07-18 + +* New iterable_as_array encoder option to perform lazy serialization of + any iterable objects, without having to convert to tuple or list. + +Version 3.7.3 released 2015-05-31 + +* Fix typo introduced in 3.7.0 (behavior should be indistinguishable) + https://github.com/simplejson/simplejson/commit/e18cc09b688ea1f3305c27616fd3... + +Version 3.7.2 released 2015-05-22 + +* Do not cache Decimal class in encoder, only reference the decimal module. + This may make reload work in more common scenarios. + +Version 3.7.1 released 2015-05-18 + +* Fix compilation with MSVC + https://github.com/simplejson/simplejson/pull/119 + +Version 3.7.0 released 2015-05-18 + +* simplejson no longer trusts custom str/repr methods for int, long, float + subclasses. These instances are now formatted as if they were exact + instances of those types. + https://github.com/simplejson/simplejson/issues/118 + Version 3.6.5 released 2014-10-24 * Importing bug fix for reference leak when an error occurs during diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/PKG-INFO new/simplejson-3.8.2/PKG-INFO --- old/simplejson-3.6.5/PKG-INFO 2014-10-24 17:18:17.000000000 +0200 +++ new/simplejson-3.8.2/PKG-INFO 2016-02-15 21:18:55.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: simplejson -Version: 3.6.5 +Version: 3.8.2 Summary: Simple, fast, extensible JSON encoder/decoder for Python Home-page: http://github.com/simplejson/simplejson Author: Bob Ippolito diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/conf.py new/simplejson-3.8.2/conf.py --- old/simplejson-3.6.5/conf.py 2014-10-24 17:14:03.000000000 +0200 +++ new/simplejson-3.8.2/conf.py 2016-02-15 19:02:14.000000000 +0100 @@ -36,15 +36,15 @@ # General substitutions. project = 'simplejson' -copyright = '2014, Bob Ippolito' +copyright = '2015, Bob Ippolito' # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. # # The short X.Y version. -version = '3.6' +version = '3.8' # The full version, including alpha/beta/rc tags. -release = '3.6.5' +release = '3.8.2' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/index.rst new/simplejson-3.8.2/index.rst --- old/simplejson-3.6.5/index.rst 2014-08-18 21:53:31.000000000 +0200 +++ new/simplejson-3.8.2/index.rst 2015-07-18 23:46:40.000000000 +0200 @@ -101,7 +101,7 @@ >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] - ... raise TypeError(repr(o) + " is not JSON serializable") + ... raise TypeError(repr(obj) + " is not JSON serializable") ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' @@ -142,7 +142,7 @@ namedtuple_as_object=True, tuple_as_array=True, \ bigint_as_string=False, sort_keys=False, \ item_sort_key=None, for_json=None, ignore_nan=False, \ - int_as_string_bitcount=None, **kw) + int_as_string_bitcount=None, iterable_as_array=False, **kw) Serialize *obj* as a JSON formatted stream to *fp* (a ``.write()``-supporting file-like object) using this :ref:`conversion table <py-to-json-table>`. @@ -230,6 +230,13 @@ If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. + If *iterable_as_array* is true (default: ``False``), + any object not in the above table that implements ``__iter__()`` + will be encoded as a JSON array. + + .. versionchanged:: 3.8.0 + *iterable_as_array* is new in 3.8.0. + .. versionchanged:: 2.2.0 *tuple_as_array* is new in 2.2.0. @@ -302,7 +309,7 @@ namedtuple_as_object=True, tuple_as_array=True, \ bigint_as_string=False, sort_keys=False, \ item_sort_key=None, for_json=None, ignore_nan=False, \ - int_as_string_bitcount=None, **kw) + int_as_string_bitcount=None, iterable_as_array=False, **kw) Serialize *obj* to a JSON formatted :class:`str`. @@ -374,6 +381,14 @@ .. versionchanged:: 2.1.0 *use_decimal* is new in 2.1.0. + If *iterable_as_array* is true (default: ``False``), + any object not in the above table that implements ``__iter__()`` + will be encoded as a JSON array. + + .. versionchanged:: 3.8.0 + *iterable_as_array* is new in 3.8.0. + + To use a custom :class:`JSONDecoder` subclass, specify it with the ``cls`` kwarg. Additional keyword arguments will be passed to the constructor of the class. You probably shouldn't do this. @@ -527,7 +542,7 @@ namedtuple_as_object=True, tuple_as_array=True, \ bigint_as_string=False, item_sort_key=None, \ for_json=True, ignore_nan=False, \ - int_as_string_bitcount=None) + int_as_string_bitcount=None, iterable_as_array=False) Extensible JSON encoder for Python data structures. @@ -662,6 +677,13 @@ .. versionchanged:: 2.2.0 *tuple_as_array* is new in 2.2.0. + If *iterable_as_array* is true (default: ``False``), + any object not in the above table that implements ``__iter__()`` + will be encoded as a JSON array. + + .. versionchanged:: 3.8.0 + *iterable_as_array* is new in 3.8.0. + If *bigint_as_string* is true (default: ``False``), :class:`int`` ``2**53`` and higher or lower than ``-2**53`` will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. Note that this diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/scripts/artifacts.py new/simplejson-3.8.2/scripts/artifacts.py --- old/simplejson-3.6.5/scripts/artifacts.py 1970-01-01 01:00:00.000000000 +0100 +++ new/simplejson-3.8.2/scripts/artifacts.py 2016-02-15 21:17:38.000000000 +0100 @@ -0,0 +1,48 @@ +try: + from urllib.request import urlopen +except ImportError: + from urllib import urlopen + +import io +import json +import subprocess + + +def get_json(url): + return json.loads(urlopen(url).read().decode('utf-8')) + + +def download_file(src_url, dest_path): + print(dest_path) + subprocess.call( + ['curl', '-L', '-#', '-o', dest_path, src_url]) + + +def download_appveyor_artifacts(): + api_url = 'https://ci.appveyor.com/api' + builds = get_json( + '{}/projects/etrepum/simplejson'.format(api_url)) + + for job in builds['build']['jobs']: + url = '{api_url}/buildjobs/{jobId}/artifacts'.format( + api_url=api_url, **job) + for artifact in get_json(url): + download_file( + '{url}/{fileName}'.format(url=url, **artifact), + artifact['fileName']) + + +def download_github_artifacts(): + release = get_json( + 'https://api.github.com/repos/simplejson/simplejson/releases/latest') + for asset in release['assets']: + download_file(asset['url'], 'dist/{name}'.format(**asset)) + + +def main(): + download_appveyor_artifacts() + download_github_artifacts() + + +if __name__ == '__main__': + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/setup.py new/simplejson-3.8.2/setup.py --- old/simplejson-3.6.5/setup.py 2014-10-24 17:14:06.000000000 +0200 +++ new/simplejson-3.8.2/setup.py 2016-02-15 19:02:14.000000000 +0100 @@ -11,7 +11,7 @@ DistutilsPlatformError IS_PYPY = hasattr(sys, 'pypy_translation_info') -VERSION = '3.6.5' +VERSION = '3.8.2' DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python" with open('README.rst', 'r') as f: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson/__init__.py new/simplejson-3.8.2/simplejson/__init__.py --- old/simplejson-3.6.5/simplejson/__init__.py 2014-10-24 17:14:00.000000000 +0200 +++ new/simplejson-3.8.2/simplejson/__init__.py 2016-02-15 19:02:14.000000000 +0100 @@ -5,9 +5,8 @@ :mod:`simplejson` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is the externally maintained version of the :mod:`json` library contained in Python 2.6, but maintains -compatibility with Python 2.4 and Python 2.5 and (currently) has -significant performance advantages, even without using the optional C -extension for speedups. +compatibility back to Python 2.5 and (currently) has significant performance +advantages, even without using the optional C extension for speedups. Encoding basic Python object hierarchies:: @@ -98,7 +97,7 @@ Expecting property name: line 1 column 3 (char 2) """ from __future__ import absolute_import -__version__ = '3.6.5' +__version__ = '3.8.2' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', @@ -140,6 +139,7 @@ use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, + iterable_as_array=False, bigint_as_string=False, item_sort_key=None, for_json=False, @@ -152,7 +152,8 @@ encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, - for_json=False, ignore_nan=False, int_as_string_bitcount=None, **kw): + for_json=False, ignore_nan=False, int_as_string_bitcount=None, + iterable_as_array=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). @@ -204,6 +205,10 @@ If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. + If *iterable_as_array* is true (default: ``False``), + any object not in the above table that implements ``__iter__()`` + will be encoded as a JSON array. + If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. Note that this is still a @@ -242,7 +247,7 @@ check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and use_decimal - and namedtuple_as_object and tuple_as_array + and namedtuple_as_object and tuple_as_array and not iterable_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and not ignore_nan and int_as_string_bitcount is None @@ -258,6 +263,7 @@ default=default, use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, + iterable_as_array=iterable_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, @@ -276,7 +282,8 @@ encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, - for_json=False, ignore_nan=False, int_as_string_bitcount=None, **kw): + for_json=False, ignore_nan=False, int_as_string_bitcount=None, + iterable_as_array=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is false then ``dict`` keys that are not basic types @@ -324,6 +331,10 @@ If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. + If *iterable_as_array* is true (default: ``False``), + any object not in the above table that implements ``__iter__()`` + will be encoded as a JSON array. + If *bigint_as_string* is true (not the default), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. @@ -356,12 +367,11 @@ """ # cached encoder - if ( - not skipkeys and ensure_ascii and + if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and use_decimal - and namedtuple_as_object and tuple_as_array + and namedtuple_as_object and tuple_as_array and not iterable_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and not ignore_nan and int_as_string_bitcount is None @@ -377,6 +387,7 @@ use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, + iterable_as_array=iterable_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson/_speedups.c new/simplejson-3.8.2/simplejson/_speedups.c --- old/simplejson-3.6.5/simplejson/_speedups.c 2014-10-24 17:12:40.000000000 +0200 +++ new/simplejson-3.8.2/simplejson/_speedups.c 2016-02-15 19:02:14.000000000 +0100 @@ -10,6 +10,7 @@ #define PyString_AS_STRING PyBytes_AS_STRING #define PyString_FromStringAndSize PyBytes_FromStringAndSize #define PyInt_Check(obj) 0 +#define PyInt_CheckExact(obj) 0 #define JSON_UNICHR Py_UCS4 #define JSON_InternFromString PyUnicode_InternFromString #define JSON_Intern_GET_SIZE PyUnicode_GET_SIZE @@ -168,6 +169,7 @@ int use_decimal; int namedtuple_as_object; int tuple_as_array; + int iterable_as_array; PyObject *max_long_size; PyObject *min_long_size; PyObject *item_sort_key; @@ -660,7 +662,20 @@ return _encoded_const(key); } else if (PyInt_Check(key) || PyLong_Check(key)) { - return PyObject_Str(key); + if (!(PyInt_CheckExact(key) || PyLong_CheckExact(key))) { + /* See #118, do not trust custom str/repr */ + PyObject *res; + PyObject *tmp = PyObject_CallFunctionObjArgs((PyObject *)&PyLong_Type, key, NULL); + if (tmp == NULL) { + return NULL; + } + res = PyObject_Str(tmp); + Py_DECREF(tmp); + return res; + } + else { + return PyObject_Str(key); + } } else if (s->use_decimal && PyObject_TypeCheck(key, (PyTypeObject *)s->Decimal)) { return PyObject_Str(key); @@ -2567,7 +2582,6 @@ static int encoder_init(PyObject *self, PyObject *args, PyObject *kwds) { - /* initialize Encoder object */ static char *kwlist[] = { "markers", "default", @@ -2588,24 +2602,25 @@ "for_json", "ignore_nan", "Decimal", + "iterable_as_array", NULL}; PyEncoderObject *s; PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan, *key_memo; - PyObject *use_decimal, *namedtuple_as_object, *tuple_as_array; + PyObject *use_decimal, *namedtuple_as_object, *tuple_as_array, *iterable_as_array; PyObject *int_as_string_bitcount, *item_sort_key, *encoding, *for_json; PyObject *ignore_nan, *Decimal; assert(PyEncoder_Check(self)); s = (PyEncoderObject *)self; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOOOOOOOOOOOO:make_encoder", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOOOOOOOOOOOOO:make_encoder", kwlist, &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, &sort_keys, &skipkeys, &allow_nan, &key_memo, &use_decimal, &namedtuple_as_object, &tuple_as_array, &int_as_string_bitcount, &item_sort_key, &encoding, &for_json, - &ignore_nan, &Decimal)) + &ignore_nan, &Decimal, &iterable_as_array)) return -1; Py_INCREF(markers); @@ -2635,10 +2650,11 @@ s->use_decimal = PyObject_IsTrue(use_decimal); s->namedtuple_as_object = PyObject_IsTrue(namedtuple_as_object); s->tuple_as_array = PyObject_IsTrue(tuple_as_array); + s->iterable_as_array = PyObject_IsTrue(iterable_as_array); if (PyInt_Check(int_as_string_bitcount) || PyLong_Check(int_as_string_bitcount)) { static const unsigned int long_long_bitsize = SIZEOF_LONG_LONG * 8; - int int_as_string_bitcount_val = PyLong_AsLong(int_as_string_bitcount); - if (int_as_string_bitcount_val > 0 && int_as_string_bitcount_val < long_long_bitsize) { + int int_as_string_bitcount_val = (int)PyLong_AsLong(int_as_string_bitcount); + if (int_as_string_bitcount_val > 0 && int_as_string_bitcount_val < (int)long_long_bitsize) { s->max_long_size = PyLong_FromUnsignedLongLong(1ULL << int_as_string_bitcount_val); s->min_long_size = PyLong_FromLongLong(-1LL << int_as_string_bitcount_val); if (s->min_long_size == NULL || s->max_long_size == NULL) { @@ -2800,7 +2816,20 @@ } } /* Use a better float format here? */ - return PyObject_Repr(obj); + if (PyFloat_CheckExact(obj)) { + return PyObject_Repr(obj); + } + else { + /* See #118, do not trust custom str/repr */ + PyObject *res; + PyObject *tmp = PyObject_CallFunctionObjArgs((PyObject *)&PyFloat_Type, obj, NULL); + if (tmp == NULL) { + return NULL; + } + res = PyObject_Repr(tmp); + Py_DECREF(tmp); + return res; + } } static PyObject * @@ -2840,7 +2869,21 @@ rv = _steal_accumulate(rval, encoded); } else if (PyInt_Check(obj) || PyLong_Check(obj)) { - PyObject *encoded = PyObject_Str(obj); + PyObject *encoded; + if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj)) { + encoded = PyObject_Str(obj); + } + else { + /* See #118, do not trust custom str/repr */ + PyObject *tmp = PyObject_CallFunctionObjArgs((PyObject *)&PyLong_Type, obj, NULL); + if (tmp == NULL) { + encoded = NULL; + } + else { + encoded = PyObject_Str(tmp); + Py_DECREF(tmp); + } + } if (encoded != NULL) { encoded = maybe_quote_bigint(s, encoded, obj); if (encoded == NULL) @@ -2895,6 +2938,16 @@ else { PyObject *ident = NULL; PyObject *newobj; + if (s->iterable_as_array) { + newobj = PyObject_GetIter(obj); + if (newobj == NULL) + PyErr_Clear(); + else { + rv = encoder_listencode_list(s, rval, newobj, indent_level); + Py_DECREF(newobj); + break; + } + } if (s->markers != Py_None) { int has_key; ident = PyLong_FromVoidPtr(obj); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson/encoder.py new/simplejson-3.8.2/simplejson/encoder.py --- old/simplejson-3.6.5/simplejson/encoder.py 2014-07-22 22:30:14.000000000 +0200 +++ new/simplejson-3.8.2/simplejson/encoder.py 2015-10-27 16:19:00.000000000 +0100 @@ -3,7 +3,8 @@ from __future__ import absolute_import import re from operator import itemgetter -from decimal import Decimal +# Do not import Decimal directly to avoid reload issues +import decimal from .compat import u, unichr, binary_type, string_types, integer_types, PY3 def _import_speedups(): try: @@ -123,7 +124,7 @@ use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, item_sort_key=None, for_json=False, ignore_nan=False, - int_as_string_bitcount=None): + int_as_string_bitcount=None, iterable_as_array=False): """Constructor for JSONEncoder, with sensible defaults. If skipkeys is false, then it is a TypeError to attempt @@ -178,6 +179,10 @@ If tuple_as_array is true (the default), tuple (and subclasses) will be encoded as JSON arrays. + If *iterable_as_array* is true (default: ``False``), + any object not in the above table that implements ``__iter__()`` + will be encoded as a JSON array. + If bigint_as_string is true (not the default), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. @@ -209,6 +214,7 @@ self.use_decimal = use_decimal self.namedtuple_as_object = namedtuple_as_object self.tuple_as_array = tuple_as_array + self.iterable_as_array = iterable_as_array self.bigint_as_string = bigint_as_string self.item_sort_key = item_sort_key self.for_json = for_json @@ -311,6 +317,9 @@ elif o == _neginf: text = '-Infinity' else: + if type(o) != float: + # See #118, do not trust custom str/repr + o = float(o) return _repr(o) if ignore_nan: @@ -334,7 +343,7 @@ self.namedtuple_as_object, self.tuple_as_array, int_as_string_bitcount, self.item_sort_key, self.encoding, self.for_json, - self.ignore_nan, Decimal) + self.ignore_nan, decimal.Decimal, self.iterable_as_array) else: _iterencode = _make_iterencode( markers, self.default, _encoder, self.indent, floatstr, @@ -343,7 +352,7 @@ self.namedtuple_as_object, self.tuple_as_array, int_as_string_bitcount, self.item_sort_key, self.encoding, self.for_json, - Decimal=Decimal) + self.iterable_as_array, Decimal=decimal.Decimal) try: return _iterencode(o, 0) finally: @@ -382,11 +391,12 @@ _use_decimal, _namedtuple_as_object, _tuple_as_array, _int_as_string_bitcount, _item_sort_key, _encoding,_for_json, + _iterable_as_array, ## HACK: hand-optimized bytecode; turn globals into locals _PY3=PY3, ValueError=ValueError, string_types=string_types, - Decimal=Decimal, + Decimal=None, dict=dict, float=float, id=id, @@ -395,7 +405,10 @@ list=list, str=str, tuple=tuple, + iter=iter, ): + if _use_decimal and Decimal is None: + Decimal = decimal.Decimal if _item_sort_key and not callable(_item_sort_key): raise TypeError("item_sort_key must be None or callable") elif _sort_keys and not _item_sort_key: @@ -412,6 +425,9 @@ or _int_as_string_bitcount < 1 ) + if type(value) not in integer_types: + # See #118, do not trust custom str/repr + value = int(value) if ( skip_quoting or (-1 << _int_as_string_bitcount) @@ -480,10 +496,14 @@ chunks = _iterencode(value, _current_indent_level) for chunk in chunks: yield chunk - if newline_indent is not None: - _current_indent_level -= 1 - yield '\n' + (_indent * _current_indent_level) - yield ']' + if first: + # iterable_as_array misses the fast path at the top + yield '[]' + else: + if newline_indent is not None: + _current_indent_level -= 1 + yield '\n' + (_indent * _current_indent_level) + yield ']' if markers is not None: del markers[markerid] @@ -501,6 +521,9 @@ elif key is None: key = 'null' elif isinstance(key, integer_types): + if type(key) not in integer_types: + # See #118, do not trust custom str/repr + key = int(key) key = str(key) elif _use_decimal and isinstance(key, Decimal): key = str(key) @@ -634,6 +657,16 @@ elif _use_decimal and isinstance(o, Decimal): yield str(o) else: + while _iterable_as_array: + # Markers are not checked here because it is valid for + # an iterable to return self. + try: + o = iter(o) + except TypeError: + break + for chunk in _iterencode_list(o, _current_indent_level): + yield chunk + return if markers is not None: markerid = id(o) if markerid in markers: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson/tests/__init__.py new/simplejson-3.8.2/simplejson/tests/__init__.py --- old/simplejson-3.6.5/simplejson/tests/__init__.py 2014-07-22 22:30:14.000000000 +0200 +++ new/simplejson-3.8.2/simplejson/tests/__init__.py 2015-10-27 16:11:46.000000000 +0100 @@ -49,6 +49,7 @@ 'simplejson.tests.test_fail', 'simplejson.tests.test_float', 'simplejson.tests.test_indent', + 'simplejson.tests.test_iterable', 'simplejson.tests.test_pass1', 'simplejson.tests.test_pass2', 'simplejson.tests.test_pass3', @@ -62,6 +63,7 @@ 'simplejson.tests.test_namedtuple', 'simplejson.tests.test_tool', 'simplejson.tests.test_for_json', + 'simplejson.tests.test_subclass', ])) suite = get_suite() import simplejson diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson/tests/test_iterable.py new/simplejson-3.8.2/simplejson/tests/test_iterable.py --- old/simplejson-3.6.5/simplejson/tests/test_iterable.py 1970-01-01 01:00:00.000000000 +0100 +++ new/simplejson-3.8.2/simplejson/tests/test_iterable.py 2015-10-27 16:29:44.000000000 +0100 @@ -0,0 +1,31 @@ +import unittest +from simplejson.compat import StringIO + +import simplejson as json + +def iter_dumps(obj, **kw): + return ''.join(json.JSONEncoder(**kw).iterencode(obj)) + +def sio_dump(obj, **kw): + sio = StringIO() + json.dumps(obj, **kw) + return sio.getvalue() + +class TestIterable(unittest.TestCase): + def test_iterable(self): + for l in ([], [1], [1, 2], [1, 2, 3]): + for opts in [{}, {'indent': 2}]: + for dumps in (json.dumps, iter_dumps, sio_dump): + expect = dumps(l, **opts) + default_expect = dumps(sum(l), **opts) + # Default is False + self.assertRaises(TypeError, dumps, iter(l), **opts) + self.assertRaises(TypeError, dumps, iter(l), iterable_as_array=False, **opts) + self.assertEqual(expect, dumps(iter(l), iterable_as_array=True, **opts)) + # Ensure that the "default" gets called + self.assertEqual(default_expect, dumps(iter(l), default=sum, **opts)) + self.assertEqual(default_expect, dumps(iter(l), iterable_as_array=False, default=sum, **opts)) + # Ensure that the "default" does not get called + self.assertEqual( + expect, + dumps(iter(l), iterable_as_array=True, default=sum, **opts)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson/tests/test_subclass.py new/simplejson-3.8.2/simplejson/tests/test_subclass.py --- old/simplejson-3.6.5/simplejson/tests/test_subclass.py 1970-01-01 01:00:00.000000000 +0100 +++ new/simplejson-3.8.2/simplejson/tests/test_subclass.py 2015-05-18 20:36:17.000000000 +0200 @@ -0,0 +1,37 @@ +from unittest import TestCase +import simplejson as json + +from decimal import Decimal + +class AlternateInt(int): + def __repr__(self): + return 'invalid json' + __str__ = __repr__ + + +class AlternateFloat(float): + def __repr__(self): + return 'invalid json' + __str__ = __repr__ + + +# class AlternateDecimal(Decimal): +# def __repr__(self): +# return 'invalid json' + + +class TestSubclass(TestCase): + def test_int(self): + self.assertEqual(json.dumps(AlternateInt(1)), '1') + self.assertEqual(json.dumps(AlternateInt(-1)), '-1') + self.assertEqual(json.loads(json.dumps({AlternateInt(1): 1})), {'1': 1}) + + def test_float(self): + self.assertEqual(json.dumps(AlternateFloat(1.0)), '1.0') + self.assertEqual(json.dumps(AlternateFloat(-1.0)), '-1.0') + self.assertEqual(json.loads(json.dumps({AlternateFloat(1.0): 1})), {'1.0': 1}) + + # NOTE: Decimal subclasses are not supported as-is + # def test_decimal(self): + # self.assertEqual(json.dumps(AlternateDecimal('1.0')), '1.0') + # self.assertEqual(json.dumps(AlternateDecimal('-1.0')), '-1.0') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson/tests/test_tuple.py new/simplejson-3.8.2/simplejson/tests/test_tuple.py --- old/simplejson-3.6.5/simplejson/tests/test_tuple.py 2014-07-22 22:30:14.000000000 +0200 +++ new/simplejson-3.8.2/simplejson/tests/test_tuple.py 2015-07-18 23:46:40.000000000 +0200 @@ -45,7 +45,3 @@ self.assertEqual( json.dumps(repr(t)), sio.getvalue()) - -class TestNamedTuple(unittest.TestCase): - def test_namedtuple_dump(self): - pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson.egg-info/PKG-INFO new/simplejson-3.8.2/simplejson.egg-info/PKG-INFO --- old/simplejson-3.6.5/simplejson.egg-info/PKG-INFO 2014-10-24 17:18:12.000000000 +0200 +++ new/simplejson-3.8.2/simplejson.egg-info/PKG-INFO 2016-02-15 21:18:55.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: simplejson -Version: 3.6.5 +Version: 3.8.2 Summary: Simple, fast, extensible JSON encoder/decoder for Python Home-page: http://github.com/simplejson/simplejson Author: Bob Ippolito diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simplejson-3.6.5/simplejson.egg-info/SOURCES.txt new/simplejson-3.8.2/simplejson.egg-info/SOURCES.txt --- old/simplejson-3.6.5/simplejson.egg-info/SOURCES.txt 2014-10-24 17:18:13.000000000 +0200 +++ new/simplejson-3.8.2/simplejson.egg-info/SOURCES.txt 2016-02-15 21:18:55.000000000 +0100 @@ -5,6 +5,7 @@ conf.py index.rst setup.py +scripts/artifacts.py scripts/make_docs.py simplejson/__init__.py simplejson/_speedups.c @@ -34,6 +35,7 @@ simplejson/tests/test_for_json.py simplejson/tests/test_indent.py simplejson/tests/test_item_sort_key.py +simplejson/tests/test_iterable.py simplejson/tests/test_namedtuple.py simplejson/tests/test_pass1.py simplejson/tests/test_pass2.py @@ -42,6 +44,7 @@ simplejson/tests/test_scanstring.py simplejson/tests/test_separators.py simplejson/tests/test_speedups.py +simplejson/tests/test_subclass.py simplejson/tests/test_tool.py simplejson/tests/test_tuple.py simplejson/tests/test_unicode.py \ No newline at end of file