mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-16 02:02:58 -07:00
Update simplejson-3.17.5
This commit is contained in:
parent
f165d2d080
commit
cdeff390d9
6 changed files with 95 additions and 25 deletions
|
@ -118,7 +118,7 @@ Serializing multiple objects to JSON lines (newline-delimited JSON)::
|
|||
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
__version__ = '3.17.0'
|
||||
__version__ = '3.17.5'
|
||||
__all__ = [
|
||||
'dump', 'dumps', 'load', 'loads',
|
||||
'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
|
||||
|
@ -360,7 +360,7 @@ def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
|
|||
|
||||
If specified, *item_sort_key* is a callable used to sort the items in
|
||||
each dictionary. This is useful if you want to sort items other than
|
||||
in alphabetical order by key. This option takes precendence over
|
||||
in alphabetical order by key. This option takes precedence over
|
||||
*sort_keys*.
|
||||
|
||||
If *sort_keys* is true (default: ``False``), the output of dictionaries
|
||||
|
|
|
@ -386,6 +386,8 @@ static int
|
|||
_is_namedtuple(PyObject *obj)
|
||||
{
|
||||
int rval = 0;
|
||||
/* We intentionally accept anything with a duck typed _asdict method rather
|
||||
* than requiring it to pass PyTuple_Check(obj). */
|
||||
PyObject *_asdict = PyObject_GetAttrString(obj, "_asdict");
|
||||
if (_asdict == NULL) {
|
||||
PyErr_Clear();
|
||||
|
@ -2853,6 +2855,15 @@ encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ss
|
|||
return rv;
|
||||
newobj = PyObject_CallMethod(obj, "_asdict", NULL);
|
||||
if (newobj != NULL) {
|
||||
if (!PyDict_Check(newobj)) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"_asdict() must return a dict, not %.80s",
|
||||
Py_TYPE(newobj)->tp_name
|
||||
);
|
||||
Py_DECREF(newobj);
|
||||
return -1;
|
||||
}
|
||||
rv = encoder_listencode_dict(s, rval, newobj, indent_level);
|
||||
Py_DECREF(newobj);
|
||||
}
|
||||
|
|
|
@ -520,7 +520,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
|||
else:
|
||||
_asdict = _namedtuple_as_object and getattr(value, '_asdict', None)
|
||||
if _asdict and callable(_asdict):
|
||||
chunks = _iterencode_dict(_asdict(),
|
||||
dct = _asdict()
|
||||
if not isinstance(dct, dict):
|
||||
raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,))
|
||||
chunks = _iterencode_dict(dct,
|
||||
_current_indent_level)
|
||||
elif _tuple_as_array and isinstance(value, tuple):
|
||||
chunks = _iterencode_list(value, _current_indent_level)
|
||||
|
@ -641,7 +644,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
|||
else:
|
||||
_asdict = _namedtuple_as_object and getattr(value, '_asdict', None)
|
||||
if _asdict and callable(_asdict):
|
||||
chunks = _iterencode_dict(_asdict(),
|
||||
dct = _asdict()
|
||||
if not isinstance(dct, dict):
|
||||
raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,))
|
||||
chunks = _iterencode_dict(dct,
|
||||
_current_indent_level)
|
||||
elif _tuple_as_array and isinstance(value, tuple):
|
||||
chunks = _iterencode_list(value, _current_indent_level)
|
||||
|
@ -686,8 +692,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
|||
else:
|
||||
_asdict = _namedtuple_as_object and getattr(o, '_asdict', None)
|
||||
if _asdict and callable(_asdict):
|
||||
for chunk in _iterencode_dict(_asdict(),
|
||||
_current_indent_level):
|
||||
dct = _asdict()
|
||||
if not isinstance(dct, dict):
|
||||
raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,))
|
||||
for chunk in _iterencode_dict(dct, _current_indent_level):
|
||||
yield chunk
|
||||
elif (_tuple_as_array and isinstance(o, tuple)):
|
||||
for chunk in _iterencode_list(o, _current_indent_level):
|
||||
|
|
|
@ -7,6 +7,7 @@ import os
|
|||
class NoExtensionTestSuite(unittest.TestSuite):
|
||||
def run(self, result):
|
||||
import simplejson
|
||||
|
||||
simplejson._toggle_speedups(False)
|
||||
result = unittest.TestSuite.run(self, result)
|
||||
simplejson._toggle_speedups(True)
|
||||
|
@ -15,16 +16,17 @@ class NoExtensionTestSuite(unittest.TestSuite):
|
|||
|
||||
class TestMissingSpeedups(unittest.TestCase):
|
||||
def runTest(self):
|
||||
if hasattr(sys, 'pypy_translation_info'):
|
||||
if hasattr(sys, "pypy_translation_info"):
|
||||
"PyPy doesn't need speedups! :)"
|
||||
elif hasattr(self, 'skipTest'):
|
||||
self.skipTest('_speedups.so is missing!')
|
||||
elif hasattr(self, "skipTest"):
|
||||
self.skipTest("_speedups.so is missing!")
|
||||
|
||||
|
||||
def additional_tests(suite=None):
|
||||
def additional_tests(suite=None, project_dir=None):
|
||||
import simplejson
|
||||
import simplejson.encoder
|
||||
import simplejson.decoder
|
||||
|
||||
if suite is None:
|
||||
suite = unittest.TestSuite()
|
||||
try:
|
||||
|
@ -36,39 +38,54 @@ def additional_tests(suite=None):
|
|||
raise
|
||||
for mod in (simplejson, simplejson.encoder, simplejson.decoder):
|
||||
suite.addTest(doctest.DocTestSuite(mod))
|
||||
suite.addTest(doctest.DocFileSuite('../../index.rst'))
|
||||
if project_dir is not None:
|
||||
suite.addTest(
|
||||
doctest.DocFileSuite(
|
||||
os.path.join(project_dir, "index.rst"), module_relative=False
|
||||
)
|
||||
)
|
||||
return suite
|
||||
|
||||
|
||||
def all_tests_suite():
|
||||
def all_tests_suite(project_dir=None):
|
||||
def get_suite():
|
||||
suite_names = [
|
||||
'simplejson.tests.%s' % (os.path.splitext(f)[0],)
|
||||
"simplejson.tests.%s" % (os.path.splitext(f)[0],)
|
||||
for f in os.listdir(os.path.dirname(__file__))
|
||||
if f.startswith('test_') and f.endswith('.py')
|
||||
if f.startswith("test_") and f.endswith(".py")
|
||||
]
|
||||
return additional_tests(
|
||||
unittest.TestLoader().loadTestsFromNames(suite_names))
|
||||
suite=unittest.TestLoader().loadTestsFromNames(suite_names),
|
||||
project_dir=project_dir,
|
||||
)
|
||||
|
||||
suite = get_suite()
|
||||
import simplejson
|
||||
|
||||
if simplejson._import_c_make_encoder() is None:
|
||||
suite.addTest(TestMissingSpeedups())
|
||||
else:
|
||||
suite = unittest.TestSuite([
|
||||
suite,
|
||||
NoExtensionTestSuite([get_suite()]),
|
||||
])
|
||||
suite = unittest.TestSuite(
|
||||
[
|
||||
suite,
|
||||
NoExtensionTestSuite([get_suite()]),
|
||||
]
|
||||
)
|
||||
return suite
|
||||
|
||||
|
||||
def main():
|
||||
runner = unittest.TextTestRunner(verbosity=1 + sys.argv.count('-v'))
|
||||
suite = all_tests_suite()
|
||||
def main(project_dir=None):
|
||||
runner = unittest.TextTestRunner(verbosity=1 + sys.argv.count("-v"))
|
||||
suite = all_tests_suite(project_dir=project_dir)
|
||||
raise SystemExit(not runner.run(suite).wasSuccessful())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
||||
main()
|
||||
|
||||
project_dir = os.path.dirname(
|
||||
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
)
|
||||
sys.path.insert(0, project_dir)
|
||||
main(project_dir=project_dir)
|
||||
|
|
7
lib/simplejson/tests/_cibw_runner.py
Normal file
7
lib/simplejson/tests/_cibw_runner.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
"""Internal module for running tests from cibuildwheel"""
|
||||
|
||||
import sys
|
||||
import simplejson.tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
simplejson.tests.main(project_dir=sys.argv[1])
|
|
@ -3,6 +3,11 @@ import unittest
|
|||
import simplejson as json
|
||||
from simplejson.compat import StringIO
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
mock = None
|
||||
|
||||
try:
|
||||
from collections import namedtuple
|
||||
except ImportError:
|
||||
|
@ -120,3 +125,25 @@ class TestNamedTuple(unittest.TestCase):
|
|||
self.assertEqual(
|
||||
json.dumps(f({})),
|
||||
json.dumps(f(DeadDict()), namedtuple_as_object=True))
|
||||
|
||||
def test_asdict_does_not_return_dict(self):
|
||||
if not mock:
|
||||
if hasattr(unittest, "SkipTest"):
|
||||
raise unittest.SkipTest("unittest.mock required")
|
||||
else:
|
||||
print("unittest.mock not available")
|
||||
return
|
||||
fake = mock.Mock()
|
||||
self.assertTrue(hasattr(fake, '_asdict'))
|
||||
self.assertTrue(callable(fake._asdict))
|
||||
self.assertFalse(isinstance(fake._asdict(), dict))
|
||||
# https://github.com/simplejson/simplejson/pull/284
|
||||
# when running under a debug build of CPython (COPTS=-UNDEBUG)
|
||||
# a C assertion could fire due to an unchecked error of an PyDict
|
||||
# API call on a non-dict internally in _speedups.c. Without a debug
|
||||
# build of CPython this test likely passes either way despite the
|
||||
# potential for internal data corruption. Getting it to crash in
|
||||
# a debug build is not always easy either as it requires an
|
||||
# assert(!PyErr_Occurred()) that could fire later on.
|
||||
with self.assertRaises(TypeError):
|
||||
json.dumps({23: fake}, namedtuple_as_object=True, for_json=False)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue