Unverified Kaydet (Commit) cfa797c0 authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka Kaydeden (comit) GitHub

bpo-24641: Improved error message for JSON unserializible keys. (#4364)

Also updated an example for default() in the module docstring.
Removed quotes around type name in other error messages.
üst 5b48dc63
...@@ -76,7 +76,8 @@ Specializing JSON object encoding:: ...@@ -76,7 +76,8 @@ Specializing JSON object encoding::
>>> def encode_complex(obj): >>> def encode_complex(obj):
... if isinstance(obj, complex): ... if isinstance(obj, complex):
... return [obj.real, obj.imag] ... return [obj.real, obj.imag]
... raise TypeError(repr(obj) + " is not JSON serializable") ... raise TypeError(f'Object of type {obj.__class__.__name__} '
... f'is not JSON serializable')
... ...
>>> json.dumps(2 + 1j, default=encode_complex) >>> json.dumps(2 + 1j, default=encode_complex)
'[2.0, 1.0]' '[2.0, 1.0]'
...@@ -344,8 +345,8 @@ def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, ...@@ -344,8 +345,8 @@ def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None,
s, 0) s, 0)
else: else:
if not isinstance(s, (bytes, bytearray)): if not isinstance(s, (bytes, bytearray)):
raise TypeError('the JSON object must be str, bytes or bytearray, ' raise TypeError(f'the JSON object must be str, bytes or bytearray, '
'not {!r}'.format(s.__class__.__name__)) f'not {s.__class__.__name__}')
s = s.decode(detect_encoding(s), 'surrogatepass') s = s.decode(detect_encoding(s), 'surrogatepass')
if (cls is None and object_hook is None and if (cls is None and object_hook is None and
......
...@@ -176,8 +176,8 @@ class JSONEncoder(object): ...@@ -176,8 +176,8 @@ class JSONEncoder(object):
return JSONEncoder.default(self, o) return JSONEncoder.default(self, o)
""" """
raise TypeError("Object of type '%s' is not JSON serializable" % raise TypeError(f'Object of type {o.__class__.__name__} '
o.__class__.__name__) f'is not JSON serializable')
def encode(self, o): def encode(self, o):
"""Return a JSON string representation of a Python data structure. """Return a JSON string representation of a Python data structure.
...@@ -373,7 +373,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, ...@@ -373,7 +373,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
elif _skipkeys: elif _skipkeys:
continue continue
else: else:
raise TypeError("key " + repr(key) + " is not a string") raise TypeError(f'keys must be str, int, float, bool or None, '
f'not {key.__class__.__name__}')
if first: if first:
first = False first = False
else: else:
......
...@@ -93,12 +93,15 @@ class TestFail: ...@@ -93,12 +93,15 @@ class TestFail:
def test_non_string_keys_dict(self): def test_non_string_keys_dict(self):
data = {'a' : 1, (1, 2) : 2} data = {'a' : 1, (1, 2) : 2}
with self.assertRaisesRegex(TypeError,
'keys must be str, int, float, bool or None, not tuple'):
self.dumps(data)
#This is for c encoder def test_not_serializable(self):
self.assertRaises(TypeError, self.dumps, data) import sys
with self.assertRaisesRegex(TypeError,
#This is for python encoder 'Object of type module is not JSON serializable'):
self.assertRaises(TypeError, self.dumps, data, indent=True) self.dumps(sys)
def test_truncated_input(self): def test_truncated_input(self):
test_cases = [ test_cases = [
......
...@@ -1650,8 +1650,9 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, ...@@ -1650,8 +1650,9 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
continue; continue;
} }
else { else {
/* TODO: include repr of key */ PyErr_Format(PyExc_TypeError,
PyErr_SetString(PyExc_TypeError, "keys must be a string"); "keys must be str, int, float, bool or None, "
"not %.100s", key->ob_type->tp_name);
goto bail; goto bail;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment