[Python-modules-commits] [simplejson] 01/04: Import simplejson_3.13.2.orig.tar.gz

Piotr Ożarowski piotr at moszumanska.debian.org
Thu Nov 30 12:53:51 UTC 2017


This is an automated email from the git hooks/post-receive script.

piotr pushed a commit to branch master
in repository simplejson.

commit 26d9b037c2eb05aae73b116df8bfb1938167f071
Author: Piotr Ożarowski <piotr at debian.org>
Date:   Thu Nov 30 13:45:23 2017 +0100

    Import simplejson_3.13.2.orig.tar.gz
---
 CHANGES.txt                       | 28 +++++++++++++++++++
 PKG-INFO                          | 20 ++------------
 conf.py                           |  4 +--
 scripts/artifacts.py              | 57 ++++++++++++++++++++++++++++-----------
 setup.cfg                         |  1 -
 setup.py                          |  5 +++-
 simplejson.egg-info/PKG-INFO      |  3 ++-
 simplejson/__init__.py            |  5 ++--
 simplejson/_speedups.c            | 41 +++++++++++++++++++++-------
 simplejson/encoder.py             | 20 +++++++++-----
 simplejson/tests/test_dump.py     | 14 +++++++++-
 simplejson/tests/test_errors.py   | 19 ++++++++++++-
 simplejson/tests/test_speedups.py | 24 +++++++++++++++++
 simplejson/tests/test_tool.py     | 34 ++++++++++++++---------
 14 files changed, 205 insertions(+), 70 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 9c66080..49faccf 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,31 @@
+Version 3.13.2 released 2017-11-24
+
+* Fix additional Python 2.x compilation issue on Windows
+
+Version 3.13.1 released 2017-11-24
+
+* Improve CI to catch speedups build regressions
+* Fix speedups build regression in Python 2.x
+  https://github.com/simplejson/simplejson/issues/193
+
+Version 3.13.0 released 2017-11-23
+
+* Workarounds for NamedTemporaryFile issues with Windows for tool tests
+* Make TypeError messages contain type name instead of a repr.
+  https://github.com/simplejson/simplejson/pull/191
+* Ensure that encoding of text subtypes is consistent with or without speedups
+  https://github.com/simplejson/simplejson/issues/185
+
+Version 3.12.1 released 2017-11-23
+
+* Misc updates to build infrastructure
+* Fix an assertion failure when make_encoder receives a bad encoder argument
+  https://github.com/simplejson/simplejson/pull/188
+* Fix potential crash during GC
+  https://github.com/simplejson/simplejson/pull/187
+* Fix a reference leak when sorting keys
+  https://github.com/simplejson/simplejson/pull/186
+
 Version 3.12.0 released 2017-11-05
 
 * Fix threaded import race condition
diff --git a/PKG-INFO b/PKG-INFO
index b0c1b4a..65e0c91 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: simplejson
-Version: 3.12.0
+Version: 3.13.2
 Summary: Simple, fast, extensible JSON encoder/decoder for Python
 Home-page: http://github.com/simplejson/simplejson
 Author: Bob Ippolito
 Author-email: bob at redivi.com
 License: MIT License
+Description-Content-Type: UNKNOWN
 Description: simplejson
         ----------
         
@@ -43,20 +44,3 @@ Description: simplejson
         .. _python2.2: https://github.com/simplejson/simplejson/tree/python2.2
         
 Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: License :: OSI Approved :: Academic Free License (AFL)
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/conf.py b/conf.py
index 374da34..00524e9 100644
--- a/conf.py
+++ b/conf.py
@@ -42,9 +42,9 @@ copyright = '2017, Bob Ippolito'
 # other places throughout the built documents.
 #
 # The short X.Y version.
-version = '3.12'
+version = '3.13'
 # The full version, including alpha/beta/rc tags.
-release = '3.12.0'
+release = '3.13.2'
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
diff --git a/scripts/artifacts.py b/scripts/artifacts.py
index 8d220af..a8e41c4 100644
--- a/scripts/artifacts.py
+++ b/scripts/artifacts.py
@@ -1,13 +1,11 @@
-try:
-    from urllib.request import urlopen
-except ImportError:
-    from urllib import urlopen
+#!/usr/bin/env python3
+from urllib.request import urlopen
 
 import json
 import os
-import re
 import subprocess
 import sys
+import getpass
 
 
 def get_json(url):
@@ -40,34 +38,63 @@ def download_github_artifacts():
     for asset in release['assets']:
         download_file(asset['browser_download_url'], 'dist/{name}'.format(**asset))
 
+
 def get_version():
-    return subprocess.check_output([sys.executable, 'setup.py', '--version']).strip()
+    return subprocess.check_output(
+        [sys.executable, 'setup.py', '--version'],
+        encoding='utf8'
+    ).strip()
+
 
 def artifact_matcher(version):
-    return re.compile('^simplejson-{}.*\\.(exe|whl)$'.format(re.escape(version)))
+    prefix = 'simplejson-{}'.format(version)
+    def matches(fn):
+        return (
+            fn.startswith(prefix) and
+            os.path.splitext(fn)[1] in ('.exe', '.whl') and
+            not fn.endswith('-none-any.whl')
+        ) or fn == '{}.tar.gz'.format(prefix)
+    return matches
+
 
 def sign_artifacts(version):
     artifacts = set(os.listdir('dist'))
-    pattern = artifact_matcher(version)
+    matches = artifact_matcher(version)
+    passphrase = getpass.getpass('\nGPG Passphrase:')
     for fn in artifacts:
-        if pattern.search(fn) and '{}.asc'.format(fn) not in artifacts:
-            sign_artifact(os.path.join('dist', fn))
+        if matches(fn) and '{}.asc'.format(fn) not in artifacts:
+            sign_artifact(os.path.join('dist', fn), passphrase)
+
+
+def sign_artifact(path, passphrase):
+    cmd = [
+        'gpg',
+        '--detach-sign',
+        '--batch',
+        '--passphrase-fd', '0',
+        '--armor',
+        path
+    ]
+    print(' '.join(cmd))
+    subprocess.run(cmd, check=True, input=passphrase, encoding='utf8')
 
-def sign_artifact(path):
-    print(' '.join(['gpg', '--detach-sign', '-a', path]))
-    subprocess.check_call(['gpg', '--detach-sign', '-a', path])
 
 def upload_artifacts(version):
     artifacts = set(os.listdir('dist'))
-    pattern = artifact_matcher(version)
+    matches = artifact_matcher(version)
     args = ['twine', 'upload']
     for fn in artifacts:
-        if pattern.search(fn):
+        if matches(fn):
             filename = os.path.join('dist', fn)
             args.extend([filename, filename + '.asc'])
     subprocess.check_call(args)
 
+
 def main():
+    try:
+        os.makedirs('dist')
+    except OSError:
+        pass
     download_appveyor_artifacts()
     download_github_artifacts()
     version = get_version()
diff --git a/setup.cfg b/setup.cfg
index 861a9f5..8bfd5a1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff --git a/setup.py b/setup.py
index 70e2391..754acfc 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 from __future__ import with_statement
 
+import os
 import sys
 try:
     from setuptools import setup, Extension, Command
@@ -11,7 +12,7 @@ from distutils.errors import CCompilerError, DistutilsExecError, \
     DistutilsPlatformError
 
 IS_PYPY = hasattr(sys, 'pypy_translation_info')
-VERSION = '3.12.0'
+VERSION = '3.13.2'
 DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python"
 
 with open('README.rst', 'r') as f:
@@ -112,6 +113,8 @@ def run_setup(with_binary):
 try:
     run_setup(not IS_PYPY)
 except BuildFailed:
+    if os.environ.get('REQUIRE_SPEEDUPS'):
+        raise
     BUILD_EXT_WARNING = ("WARNING: The C extension could not be compiled, "
                          "speedups are not enabled.")
     print('*' * 75)
diff --git a/simplejson.egg-info/PKG-INFO b/simplejson.egg-info/PKG-INFO
index b0c1b4a..ef341c8 100644
--- a/simplejson.egg-info/PKG-INFO
+++ b/simplejson.egg-info/PKG-INFO
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: simplejson
-Version: 3.12.0
+Version: 3.13.2
 Summary: Simple, fast, extensible JSON encoder/decoder for Python
 Home-page: http://github.com/simplejson/simplejson
 Author: Bob Ippolito
 Author-email: bob at redivi.com
 License: MIT License
+Description-Content-Type: UNKNOWN
 Description: simplejson
         ----------
         
diff --git a/simplejson/__init__.py b/simplejson/__init__.py
index 2f14262..adca453 100644
--- a/simplejson/__init__.py
+++ b/simplejson/__init__.py
@@ -77,7 +77,8 @@ Specializing JSON object encoding::
     >>> def encode_complex(obj):
     ...     if isinstance(obj, complex):
     ...         return [obj.real, obj.imag]
-    ...     raise TypeError(repr(o) + " is not JSON serializable")
+    ...     raise TypeError('Object of type %s is not JSON serializable' %
+    ...                     obj.__class__.__name__)
     ...
     >>> json.dumps(2 + 1j, default=encode_complex)
     '[2.0, 1.0]'
@@ -97,7 +98,7 @@ Using simplejson.tool from the shell to validate and pretty-print::
     Expecting property name: line 1 column 3 (char 2)
 """
 from __future__ import absolute_import
-__version__ = '3.12.0'
+__version__ = '3.13.2'
 __all__ = [
     'dump', 'dumps', 'load', 'loads',
     'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c
index 7b46d8a..f352443 100644
--- a/simplejson/_speedups.c
+++ b/simplejson/_speedups.c
@@ -680,7 +680,9 @@ encoder_stringify_key(PyEncoderObject *s, PyObject *key)
         Py_INCREF(Py_None);
         return Py_None;
     }
-    PyErr_SetString(PyExc_TypeError, "keys must be a string");
+    PyErr_Format(PyExc_TypeError,
+                 "keys must be str, int, float, bool or None, "
+                 "not %.100s", key->ob_type->tp_name);
     return NULL;
 }
 
@@ -692,7 +694,8 @@ encoder_dict_iteritems(PyEncoderObject *s, PyObject *dct)
     PyObject *lst = NULL;
     PyObject *item = NULL;
     PyObject *kstr = NULL;
-    static PyObject *sortfun = NULL;
+    PyObject *sortfun = NULL;
+    PyObject *sortres;
     static PyObject *sortargs = NULL;
 
     if (sortargs == NULL) {
@@ -763,8 +766,10 @@ encoder_dict_iteritems(PyEncoderObject *s, PyObject *dct)
     sortfun = PyObject_GetAttrString(lst, "sort");
     if (sortfun == NULL)
         goto bail;
-    if (!PyObject_Call(sortfun, sortargs, s->item_sort_kw))
+    sortres = PyObject_Call(sortfun, sortargs, s->item_sort_kw);
+    if (!sortres)
         goto bail;
+    Py_DECREF(sortres);
     Py_CLEAR(sortfun);
     iter = PyObject_GetIter(lst);
     Py_CLEAR(lst);
@@ -1355,7 +1360,8 @@ py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr)
 static void
 scanner_dealloc(PyObject *self)
 {
-    /* Deallocate scanner object */
+    /* bpo-31095: UnTrack is needed before calling any callbacks */
+    PyObject_GC_UnTrack(self);
     scanner_clear(self);
     Py_TYPE(self)->tp_free(self);
 }
@@ -2807,10 +2813,25 @@ static PyObject *
 encoder_encode_string(PyEncoderObject *s, PyObject *obj)
 {
     /* Return the JSON representation of a string */
-    if (s->fast_encode)
+    PyObject *encoded;
+
+    if (s->fast_encode) {
         return py_encode_basestring_ascii(NULL, obj);
-    else
-        return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
+    }
+    encoded = PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
+    if (encoded != NULL &&
+#if PY_MAJOR_VERSION < 3
+        !JSON_ASCII_Check(encoded) &&
+#endif /* PY_MAJOR_VERSION < 3 */
+        !PyUnicode_Check(encoded))
+    {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder() must return a string, not %.80s",
+                     Py_TYPE(encoded)->tp_name);
+        Py_DECREF(encoded);
+        return NULL;
+    }
+    return encoded;
 }
 
 static int
@@ -3205,7 +3226,8 @@ bail:
 static void
 encoder_dealloc(PyObject *self)
 {
-    /* Deallocate Encoder */
+    /* bpo-31095: UnTrack is needed before calling any callbacks */
+    PyObject_GC_UnTrack(self);
     encoder_clear(self);
     Py_TYPE(self)->tp_free(self);
 }
@@ -3335,10 +3357,11 @@ static struct PyModuleDef moduledef = {
 PyObject *
 import_dependency(char *module_name, char *attr_name)
 {
+    PyObject *rval;
     PyObject *module = PyImport_ImportModule(module_name);
     if (module == NULL)
         return NULL;
-    PyObject *rval = PyObject_GetAttrString(module, attr_name);
+    rval = PyObject_GetAttrString(module, attr_name);
     Py_DECREF(module);
     return rval;
 }
diff --git a/simplejson/encoder.py b/simplejson/encoder.py
index c87468a..831527b 100644
--- a/simplejson/encoder.py
+++ b/simplejson/encoder.py
@@ -48,12 +48,15 @@ def encode_basestring(s, _PY3=PY3, _q=u('"')):
         if isinstance(s, binary_type):
             s = s.decode('utf-8')
         if type(s) is not text_type:
-            s = text_type(s)
+            s = text_type.__str__(s)
     else:
         if isinstance(s, str) and HAS_UTF8.search(s) is not None:
             s = s.decode('utf-8')
         if type(s) not in string_types:
-            s = text_type(s)
+            if isinstance(s, str):
+                s = str.__str__(s)
+            else:
+                s = unicode.__getnewargs__(s)[0]
     def replace(match):
         return ESCAPE_DCT[match.group(0)]
     return _q + ESCAPE.sub(replace, s) + _q
@@ -67,12 +70,15 @@ def py_encode_basestring_ascii(s, _PY3=PY3):
         if isinstance(s, binary_type):
             s = s.decode('utf-8')
         if type(s) is not text_type:
-            s = text_type(s)
+            s = text_type.__str__(s)
     else:
         if isinstance(s, str) and HAS_UTF8.search(s) is not None:
             s = s.decode('utf-8')
         if type(s) not in string_types:
-            s = text_type(s)
+            if isinstance(s, str):
+                s = str.__str__(s)
+            else:
+                s = unicode.__getnewargs__(s)[0]
     def replace(match):
         s = match.group(0)
         try:
@@ -258,7 +264,8 @@ class JSONEncoder(object):
                 return JSONEncoder.default(self, o)
 
         """
-        raise TypeError(repr(o) + " is not JSON serializable")
+        raise TypeError('Object of type %s is not JSON serializable' %
+                        o.__class__.__name__)
 
     def encode(self, o):
         """Return a JSON string representation of a Python data structure.
@@ -541,7 +548,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
         elif _skipkeys:
             key = None
         else:
-            raise TypeError("key " + repr(key) + " is not a string")
+            raise TypeError('keys must be str, int, float, bool or None, '
+                            'not %s' % key.__class__.__name__)
         return key
 
     def _iterencode_dict(dct, _current_indent_level):
diff --git a/simplejson/tests/test_dump.py b/simplejson/tests/test_dump.py
index 3661de0..f5f4c1f 100644
--- a/simplejson/tests/test_dump.py
+++ b/simplejson/tests/test_dump.py
@@ -1,7 +1,11 @@
 from unittest import TestCase
-from simplejson.compat import StringIO, long_type, b, binary_type, PY3
+from simplejson.compat import StringIO, long_type, b, binary_type, text_type, PY3
 import simplejson as json
 
+class MisbehavingTextSubtype(text_type):
+    def __str__(self):
+        return "FAIL!"
+
 def as_text_type(s):
     if PY3 and isinstance(s, binary_type):
         return s.decode('ascii')
@@ -128,3 +132,11 @@ class TestDump(TestCase):
             json.dump(p, sio, sort_keys=True)
             self.assertEqual(sio.getvalue(), json.dumps(p, sort_keys=True))
             self.assertEqual(json.loads(sio.getvalue()), p)
+
+    def test_misbehaving_text_subtype(self):
+        # https://github.com/simplejson/simplejson/issues/185
+        text = "this is some text"
+        self.assertEqual(
+            json.dumps(MisbehavingTextSubtype(text)),
+            json.dumps(text)
+        )
diff --git a/simplejson/tests/test_errors.py b/simplejson/tests/test_errors.py
index 8dede38..78f25a5 100644
--- a/simplejson/tests/test_errors.py
+++ b/simplejson/tests/test_errors.py
@@ -7,7 +7,24 @@ from simplejson.compat import u, b
 class TestErrors(TestCase):
     def test_string_keys_error(self):
         data = [{'a': 'A', 'b': (2, 4), 'c': 3.0, ('d',): 'D tuple'}]
-        self.assertRaises(TypeError, json.dumps, data)
+        try:
+            json.dumps(data)
+        except TypeError:
+            err = sys.exc_info()[1]
+        else:
+            self.fail('Expected TypeError')
+        self.assertEqual(str(err),
+                'keys must be str, int, float, bool or None, not tuple')
+
+    def test_not_serializable(self):
+        try:
+            json.dumps(json)
+        except TypeError:
+            err = sys.exc_info()[1]
+        else:
+            self.fail('Expected TypeError')
+        self.assertEqual(str(err),
+                'Object of type module is not JSON serializable')
 
     def test_decode_error(self):
         err = None
diff --git a/simplejson/tests/test_speedups.py b/simplejson/tests/test_speedups.py
index b59eeca..8b146df 100644
--- a/simplejson/tests/test_speedups.py
+++ b/simplejson/tests/test_speedups.py
@@ -60,6 +60,30 @@ class TestEncode(TestCase):
         )
 
     @skip_if_speedups_missing
+    def test_bad_str_encoder(self):
+        # Issue #31505: There shouldn't be an assertion failure in case
+        # c_make_encoder() receives a bad encoder() argument.
+        import decimal
+        def bad_encoder1(*args):
+            return None
+        enc = encoder.c_make_encoder(
+                None, lambda obj: str(obj),
+                bad_encoder1, None, ': ', ', ',
+                False, False, False, {}, False, False, False,
+                None, None, 'utf-8', False, False, decimal.Decimal, False)
+        self.assertRaises(TypeError, enc, 'spam', 4)
+        self.assertRaises(TypeError, enc, {'spam': 42}, 4)
+
+        def bad_encoder2(*args):
+            1/0
+        enc = encoder.c_make_encoder(
+                None, lambda obj: str(obj),
+                bad_encoder2, None, ': ', ', ',
+                False, False, False, {}, False, False, False,
+                None, None, 'utf-8', False, False, decimal.Decimal, False)
+        self.assertRaises(ZeroDivisionError, enc, 'spam', 4)
+
+    @skip_if_speedups_missing
     def test_bad_bool_args(self):
         def test(name):
             encoder.JSONEncoder(**{name: BadBool()}).encode({})
diff --git a/simplejson/tests/test_tool.py b/simplejson/tests/test_tool.py
index ac2a14c..ebb295b 100644
--- a/simplejson/tests/test_tool.py
+++ b/simplejson/tests/test_tool.py
@@ -63,35 +63,43 @@ class TestTool(unittest.TestCase):
         out, err = proc.communicate(data)
         self.assertEqual(strip_python_stderr(err), ''.encode())
         self.assertEqual(proc.returncode, 0)
-        return out
+        return out.decode('utf8').splitlines()
 
     def test_stdin_stdout(self):
         self.assertEqual(
             self.runTool(data=self.data.encode()),
-            self.expect.encode())
+            self.expect.splitlines())
 
     def test_infile_stdout(self):
-        with tempfile.NamedTemporaryFile() as infile:
+        infile = tempfile.NamedTemporaryFile(delete=False)
+        try:
             infile.write(self.data.encode())
-            infile.flush()
+            infile.close()
             self.assertEqual(
                 self.runTool(args=[infile.name]),
-                self.expect.encode())
+                self.expect.splitlines())
+        finally:
+            os.unlink(infile.name)
 
     def test_infile_outfile(self):
-        with tempfile.NamedTemporaryFile() as infile:
+        infile = tempfile.NamedTemporaryFile(delete=False)
+        try:
             infile.write(self.data.encode())
-            infile.flush()
+            infile.close()
             # outfile will get overwritten by tool, so the delete
             # may not work on some platforms. Do it manually.
-            outfile = tempfile.NamedTemporaryFile()
+            outfile = tempfile.NamedTemporaryFile(delete=False)
             try:
+                outfile.close()
                 self.assertEqual(
                     self.runTool(args=[infile.name, outfile.name]),
-                    ''.encode())
+                    [])
                 with open(outfile.name, 'rb') as f:
-                    self.assertEqual(f.read(), self.expect.encode())
+                    self.assertEqual(
+                        f.read().decode('utf8').splitlines(),
+                        self.expect.splitlines()
+                    )
             finally:
-                outfile.close()
-                if os.path.exists(outfile.name):
-                    os.unlink(outfile.name)
+                os.unlink(outfile.name)
+        finally:
+            os.unlink(infile.name)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/simplejson.git



More information about the Python-modules-commits mailing list