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
|
from __future__ import absolute_import
|
||||||
__version__ = '3.17.0'
|
__version__ = '3.17.5'
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'dump', 'dumps', 'load', 'loads',
|
'dump', 'dumps', 'load', 'loads',
|
||||||
'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
|
'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
|
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
|
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*.
|
*sort_keys*.
|
||||||
|
|
||||||
If *sort_keys* is true (default: ``False``), the output of dictionaries
|
If *sort_keys* is true (default: ``False``), the output of dictionaries
|
||||||
|
|
|
@ -386,6 +386,8 @@ static int
|
||||||
_is_namedtuple(PyObject *obj)
|
_is_namedtuple(PyObject *obj)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
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");
|
PyObject *_asdict = PyObject_GetAttrString(obj, "_asdict");
|
||||||
if (_asdict == NULL) {
|
if (_asdict == NULL) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
@ -2853,6 +2855,15 @@ encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ss
|
||||||
return rv;
|
return rv;
|
||||||
newobj = PyObject_CallMethod(obj, "_asdict", NULL);
|
newobj = PyObject_CallMethod(obj, "_asdict", NULL);
|
||||||
if (newobj != 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);
|
rv = encoder_listencode_dict(s, rval, newobj, indent_level);
|
||||||
Py_DECREF(newobj);
|
Py_DECREF(newobj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,7 +520,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
||||||
else:
|
else:
|
||||||
_asdict = _namedtuple_as_object and getattr(value, '_asdict', None)
|
_asdict = _namedtuple_as_object and getattr(value, '_asdict', None)
|
||||||
if _asdict and callable(_asdict):
|
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)
|
_current_indent_level)
|
||||||
elif _tuple_as_array and isinstance(value, tuple):
|
elif _tuple_as_array and isinstance(value, tuple):
|
||||||
chunks = _iterencode_list(value, _current_indent_level)
|
chunks = _iterencode_list(value, _current_indent_level)
|
||||||
|
@ -641,7 +644,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
||||||
else:
|
else:
|
||||||
_asdict = _namedtuple_as_object and getattr(value, '_asdict', None)
|
_asdict = _namedtuple_as_object and getattr(value, '_asdict', None)
|
||||||
if _asdict and callable(_asdict):
|
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)
|
_current_indent_level)
|
||||||
elif _tuple_as_array and isinstance(value, tuple):
|
elif _tuple_as_array and isinstance(value, tuple):
|
||||||
chunks = _iterencode_list(value, _current_indent_level)
|
chunks = _iterencode_list(value, _current_indent_level)
|
||||||
|
@ -686,8 +692,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
||||||
else:
|
else:
|
||||||
_asdict = _namedtuple_as_object and getattr(o, '_asdict', None)
|
_asdict = _namedtuple_as_object and getattr(o, '_asdict', None)
|
||||||
if _asdict and callable(_asdict):
|
if _asdict and callable(_asdict):
|
||||||
for chunk in _iterencode_dict(_asdict(),
|
dct = _asdict()
|
||||||
_current_indent_level):
|
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
|
yield chunk
|
||||||
elif (_tuple_as_array and isinstance(o, tuple)):
|
elif (_tuple_as_array and isinstance(o, tuple)):
|
||||||
for chunk in _iterencode_list(o, _current_indent_level):
|
for chunk in _iterencode_list(o, _current_indent_level):
|
||||||
|
|
|
@ -7,6 +7,7 @@ import os
|
||||||
class NoExtensionTestSuite(unittest.TestSuite):
|
class NoExtensionTestSuite(unittest.TestSuite):
|
||||||
def run(self, result):
|
def run(self, result):
|
||||||
import simplejson
|
import simplejson
|
||||||
|
|
||||||
simplejson._toggle_speedups(False)
|
simplejson._toggle_speedups(False)
|
||||||
result = unittest.TestSuite.run(self, result)
|
result = unittest.TestSuite.run(self, result)
|
||||||
simplejson._toggle_speedups(True)
|
simplejson._toggle_speedups(True)
|
||||||
|
@ -15,16 +16,17 @@ class NoExtensionTestSuite(unittest.TestSuite):
|
||||||
|
|
||||||
class TestMissingSpeedups(unittest.TestCase):
|
class TestMissingSpeedups(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
if hasattr(sys, 'pypy_translation_info'):
|
if hasattr(sys, "pypy_translation_info"):
|
||||||
"PyPy doesn't need speedups! :)"
|
"PyPy doesn't need speedups! :)"
|
||||||
elif hasattr(self, 'skipTest'):
|
elif hasattr(self, "skipTest"):
|
||||||
self.skipTest('_speedups.so is missing!')
|
self.skipTest("_speedups.so is missing!")
|
||||||
|
|
||||||
|
|
||||||
def additional_tests(suite=None):
|
def additional_tests(suite=None, project_dir=None):
|
||||||
import simplejson
|
import simplejson
|
||||||
import simplejson.encoder
|
import simplejson.encoder
|
||||||
import simplejson.decoder
|
import simplejson.decoder
|
||||||
|
|
||||||
if suite is None:
|
if suite is None:
|
||||||
suite = unittest.TestSuite()
|
suite = unittest.TestSuite()
|
||||||
try:
|
try:
|
||||||
|
@ -36,39 +38,54 @@ def additional_tests(suite=None):
|
||||||
raise
|
raise
|
||||||
for mod in (simplejson, simplejson.encoder, simplejson.decoder):
|
for mod in (simplejson, simplejson.encoder, simplejson.decoder):
|
||||||
suite.addTest(doctest.DocTestSuite(mod))
|
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
|
return suite
|
||||||
|
|
||||||
|
|
||||||
def all_tests_suite():
|
def all_tests_suite(project_dir=None):
|
||||||
def get_suite():
|
def get_suite():
|
||||||
suite_names = [
|
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__))
|
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(
|
return additional_tests(
|
||||||
unittest.TestLoader().loadTestsFromNames(suite_names))
|
suite=unittest.TestLoader().loadTestsFromNames(suite_names),
|
||||||
|
project_dir=project_dir,
|
||||||
|
)
|
||||||
|
|
||||||
suite = get_suite()
|
suite = get_suite()
|
||||||
import simplejson
|
import simplejson
|
||||||
|
|
||||||
if simplejson._import_c_make_encoder() is None:
|
if simplejson._import_c_make_encoder() is None:
|
||||||
suite.addTest(TestMissingSpeedups())
|
suite.addTest(TestMissingSpeedups())
|
||||||
else:
|
else:
|
||||||
suite = unittest.TestSuite([
|
suite = unittest.TestSuite(
|
||||||
suite,
|
[
|
||||||
NoExtensionTestSuite([get_suite()]),
|
suite,
|
||||||
])
|
NoExtensionTestSuite([get_suite()]),
|
||||||
|
]
|
||||||
|
)
|
||||||
return suite
|
return suite
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main(project_dir=None):
|
||||||
runner = unittest.TextTestRunner(verbosity=1 + sys.argv.count('-v'))
|
runner = unittest.TextTestRunner(verbosity=1 + sys.argv.count("-v"))
|
||||||
suite = all_tests_suite()
|
suite = all_tests_suite(project_dir=project_dir)
|
||||||
raise SystemExit(not runner.run(suite).wasSuccessful())
|
raise SystemExit(not runner.run(suite).wasSuccessful())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
import os
|
import os
|
||||||
import sys
|
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
|
import simplejson as json
|
||||||
from simplejson.compat import StringIO
|
from simplejson.compat import StringIO
|
||||||
|
|
||||||
|
try:
|
||||||
|
from unittest import mock
|
||||||
|
except ImportError:
|
||||||
|
mock = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -120,3 +125,25 @@ class TestNamedTuple(unittest.TestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
json.dumps(f({})),
|
json.dumps(f({})),
|
||||||
json.dumps(f(DeadDict()), namedtuple_as_object=True))
|
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