Files
MoFin/venv/lib/python3.12/site-packages/simplejson/tests/test_namedtuple.py
T
知微 fa45d8aa5f fix: 小果地址统一node122(兼容LAN+EasyTier)
- health_checklist.json: 192.168.1.122→node122
- ocr_client.py: docstring IP→node122
- docs/market-data-requirements.md: IP→node122
- 所有API调用通过ProxyHandler({})绕过系统代理
  Privoxy对node122:18003返回500,直连正常
2026-06-30 02:56:35 +08:00

207 lines
7.2 KiB
Python

from __future__ import absolute_import
import unittest
import simplejson as json
from simplejson.compat import StringIO
try:
from unittest import mock
except ImportError:
mock = None
from collections import namedtuple
Value = namedtuple('Value', ['value'])
Point = namedtuple('Point', ['x', 'y'])
class DuckValue(object):
def __init__(self, *args):
self.value = Value(*args)
def _asdict(self):
return self.value._asdict()
class DuckPoint(object):
def __init__(self, *args):
self.point = Point(*args)
def _asdict(self):
return self.point._asdict()
class DeadDuck(object):
_asdict = None
class DeadDict(dict):
_asdict = None
CONSTRUCTORS = [
lambda v: v,
lambda v: [v],
lambda v: [{'key': v}],
]
class TestNamedTuple(unittest.TestCase):
def test_namedtuple_dumps(self):
for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]:
d = v._asdict()
self.assertEqual(d, json.loads(json.dumps(v)))
self.assertEqual(
d,
json.loads(json.dumps(v, namedtuple_as_object=True)))
self.assertEqual(d, json.loads(json.dumps(v, tuple_as_array=False)))
self.assertEqual(
d,
json.loads(json.dumps(v, namedtuple_as_object=True,
tuple_as_array=False)))
def test_namedtuple_dumps_false(self):
for v in [Value(1), Point(1, 2)]:
l = list(v)
self.assertEqual(
l,
json.loads(json.dumps(v, namedtuple_as_object=False)))
self.assertRaises(TypeError, json.dumps, v,
tuple_as_array=False, namedtuple_as_object=False)
def test_namedtuple_dump(self):
for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]:
d = v._asdict()
sio = StringIO()
json.dump(v, sio)
self.assertEqual(d, json.loads(sio.getvalue()))
sio = StringIO()
json.dump(v, sio, namedtuple_as_object=True)
self.assertEqual(
d,
json.loads(sio.getvalue()))
sio = StringIO()
json.dump(v, sio, tuple_as_array=False)
self.assertEqual(d, json.loads(sio.getvalue()))
sio = StringIO()
json.dump(v, sio, namedtuple_as_object=True,
tuple_as_array=False)
self.assertEqual(
d,
json.loads(sio.getvalue()))
def test_namedtuple_dump_false(self):
for v in [Value(1), Point(1, 2)]:
l = list(v)
sio = StringIO()
json.dump(v, sio, namedtuple_as_object=False)
self.assertEqual(
l,
json.loads(sio.getvalue()))
self.assertRaises(TypeError, json.dump, v, StringIO(),
tuple_as_array=False, namedtuple_as_object=False)
def test_asdict_not_callable_dump(self):
for f in CONSTRUCTORS:
self.assertRaises(
TypeError,
json.dump,
f(DeadDuck()),
StringIO(),
namedtuple_as_object=True
)
sio = StringIO()
json.dump(f(DeadDict()), sio, namedtuple_as_object=True)
self.assertEqual(
json.dumps(f({})),
sio.getvalue())
self.assertRaises(
TypeError,
json.dump,
f(Value),
StringIO(),
namedtuple_as_object=True
)
def test_asdict_not_callable_dumps(self):
for f in CONSTRUCTORS:
self.assertRaises(TypeError,
json.dumps, f(DeadDuck()), namedtuple_as_object=True)
self.assertRaises(
TypeError,
json.dumps,
f(Value),
namedtuple_as_object=True
)
self.assertEqual(
json.dumps(f({})),
json.dumps(f(DeadDict()), namedtuple_as_object=True))
def test_asdict_unbound_method_dumps(self):
for f in CONSTRUCTORS:
self.assertEqual(
json.dumps(f(Value), default=lambda v: v.__name__),
json.dumps(f(Value.__name__))
)
def test_asdict_does_not_return_dict(self):
if not mock:
raise unittest.SkipTest("unittest.mock required")
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)
def test_asdict_dispatch_order(self):
# Regression: the Python encoder used to check isinstance(o, list)
# BEFORE _asdict(), so a list subclass that defines _asdict()
# encoded as a plain list under Py and as an object under C.
# Consolidated on C's order: _asdict() takes precedence over
# list/tuple/dict container checks. for_json still wins over
# _asdict in both backends.
#
# The _cibw_runner harness runs the whole test suite once with
# the C speedups active and once with them disabled, so a single
# assertion here covers both backends.
class ListAsdict(list):
def _asdict(self):
return {'from_asdict': list(self)}
class TupleAsdict(tuple):
def _asdict(self):
return {'from_asdict': list(self)}
class DictAsdict(dict):
def _asdict(self):
return {'from_asdict': dict(self)}
class ListBoth(list):
def _asdict(self):
return {'from_asdict': True}
def for_json(self):
return {'from_for_json': True}
self.assertEqual(
{'from_asdict': [10, 20]},
json.loads(json.dumps(ListAsdict([10, 20]))))
self.assertEqual(
{'from_asdict': [1, 2]},
json.loads(json.dumps(TupleAsdict((1, 2)))))
self.assertEqual(
{'from_asdict': {'x': 1}},
json.loads(json.dumps(DictAsdict(x=1))))
# Nested inside a plain list.
self.assertEqual(
[{'from_asdict': [10]}],
json.loads(json.dumps([ListAsdict([10])])))
# Nested inside a plain dict.
self.assertEqual(
{'k': {'from_asdict': [10]}},
json.loads(json.dumps({'k': ListAsdict([10])})))
# for_json must still outrank _asdict.
self.assertEqual(
{'from_for_json': True},
json.loads(json.dumps(ListBoth([1]), for_json=True)))