-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Labels
Description
Description
The packages doesn't pass its tests.
Steps to Reproduce
$ git clone https://github.com/domdfcoding/singledispatch-json && cd singledispatch-jsonpython3 -m venv .venv && source .venv/bin/activatepip install -r requirements.txt -r tests/requirements.txtpip install .pytest -vra
Actual result:
Expected result:
Reproduces how often:
==================================================================== FAILURES =====================================================================
_________________________________________________________________ test_protocols __________________________________________________________________
def test_protocols() -> None:
class Integer:
def __int__(self) -> int:
return 42
class Float:
def __float__(self) -> float:
return 42.0
class Bytes:
def __bytes__(self) -> bytes:
return b"42"
with pytest.raises(TypeError, match="Object of type '?Integer'? is not JSON serializable"):
sdjson.dumps(Integer())
with pytest.raises(TypeError, match="Object of type '?Float'? is not JSON serializable"):
sdjson.dumps(Float())
with pytest.raises(TypeError, match="Object of type '?Bytes'? is not JSON serializable"):
sdjson.dumps(Bytes())
@sdjson.encoders.register(SupportsInt)
def supports_int_encoder(obj):
return int(obj)
@sdjson.encoders.register(SupportsFloat)
def supports_float_encoder(obj):
return float(obj)
@sdjson.encoders.register(SupportsBytes)
def supports_bytes_encoder(obj):
return bytes(obj)
assert sdjson.dumps(Integer()) == "42"
assert sdjson.dumps(Float()) == "42.0"
# To prove the protocols don't take precedence
assert sdjson.dumps(123) == "123"
with pytest.raises(TypeError, match="Object of type '?bytes'? is not JSON serializable"):
> sdjson.dumps(Bytes())
tests/test_protocols.py:100:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sdjson/__init__.py:326: in dumps
return _default_encoder.encode(obj)
sdjson/__init__.py:385: in encode
return super().encode(o)
/usr/lib64/python3.11/json/encoder.py:200: in encode
chunks = self.iterencode(o, _one_shot=True)
sdjson/__init__.py:394: in iterencode
return super().iterencode(o, _one_shot)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <sdjson._CustomEncoder object at 0x7fc4922fef90>, o = <tests.test_protocols.test_protocols.<locals>.Bytes object at 0x7fc492b637d0>
_one_shot = True
def iterencode(self, o, _one_shot=False):
"""Encode the given object and yield each string
representation as available.
For example::
for chunk in JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)
"""
if self.check_circular:
markers = {}
else:
markers = None
if self.ensure_ascii:
_encoder = encode_basestring_ascii
else:
_encoder = encode_basestring
def floatstr(o, allow_nan=self.allow_nan,
_repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY):
# Check for specials. Note that this type of test is processor
# and/or platform-specific, so do tests which don't depend on the
# internals.
if o != o:
text = 'NaN'
elif o == _inf:
text = 'Infinity'
elif o == _neginf:
text = '-Infinity'
else:
return _repr(o)
if not allow_nan:
raise ValueError(
"Out of range float values are not JSON compliant: " +
repr(o))
return text
if (_one_shot and c_make_encoder is not None
and self.indent is None):
_iterencode = c_make_encoder(
markers, self.default, _encoder, self.indent,
self.key_separator, self.item_separator, self.sort_keys,
self.skipkeys, self.allow_nan)
else:
_iterencode = _make_iterencode(
markers, self.default, _encoder, self.indent, floatstr,
self.key_separator, self.item_separator, self.sort_keys,
self.skipkeys, _one_shot)
> return _iterencode(o, 0)
E ValueError: Circular reference detected
/usr/lib64/python3.11/json/encoder.py:258: ValueError
_________________________________________________________________ test_unregister _________________________________________________________________
def test_unregister() -> None:
# Create and register a custom encoder for Decimal that turns it into a string
@sdjson.encoders.register(Decimal)
def encode_str(obj):
return str(obj)
# Test that we get the expected output from the first encoder
assert sdjson.dumps(Decimal(1)) == '"1"'
# Unregister that encoder
sdjson.unregister_encoder(Decimal)
# We should now get an error
> with pytest.raises(TypeError, match="Object of type [']*Decimal[']* is not JSON serializable") as e:
E Failed: DID NOT RAISE <class 'TypeError'>
tests/test_unregister.py:24: Failed
________________________________________________________________ test_bytes_encode ________________________________________________________________
def test_bytes_encode() -> None:
with pytest.raises(TypeError):
> sdjson.dumps(b"hi")
tests/stdlib_tests/test_unicode.py:66:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sdjson/__init__.py:326: in dumps
return _default_encoder.encode(obj)
sdjson/__init__.py:385: in encode
return super().encode(o)
/usr/lib64/python3.11/json/encoder.py:200: in encode
chunks = self.iterencode(o, _one_shot=True)
sdjson/__init__.py:394: in iterencode
return super().iterencode(o, _one_shot)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <sdjson._CustomEncoder object at 0x7fc4922fef90>, o = b'hi', _one_shot = True
def iterencode(self, o, _one_shot=False):
"""Encode the given object and yield each string
representation as available.
For example::
for chunk in JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)
"""
if self.check_circular:
markers = {}
else:
markers = None
if self.ensure_ascii:
_encoder = encode_basestring_ascii
else:
_encoder = encode_basestring
def floatstr(o, allow_nan=self.allow_nan,
_repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY):
# Check for specials. Note that this type of test is processor
# and/or platform-specific, so do tests which don't depend on the
# internals.
if o != o:
text = 'NaN'
elif o == _inf:
text = 'Infinity'
elif o == _neginf:
text = '-Infinity'
else:
return _repr(o)
if not allow_nan:
raise ValueError(
"Out of range float values are not JSON compliant: " +
repr(o))
return text
if (_one_shot and c_make_encoder is not None
and self.indent is None):
_iterencode = c_make_encoder(
markers, self.default, _encoder, self.indent,
self.key_separator, self.item_separator, self.sort_keys,
self.skipkeys, self.allow_nan)
else:
_iterencode = _make_iterencode(
markers, self.default, _encoder, self.indent, floatstr,
self.key_separator, self.item_separator, self.sort_keys,
self.skipkeys, _one_shot)
> return _iterencode(o, 0)
E ValueError: Circular reference detected
/usr/lib64/python3.11/json/encoder.py:258: ValueError
============================================================== slowest 25 durations ===============================================================
0.10s call tests/stdlib_tests/test_unicode.py::test_unicode_decode
0.09s call tests/stdlib_tests/test_recursion.py::test_highly_nested_objects_encoding
(23 durations < 0.005s hidden. Use -vv to show these durations.)
Version
- Operating System:
ALT Starterkit 10 (Hypericum)(updated to Sisyphus branch). - Python:
3.11.4 - sdjson:
v0.4.0
Installation source
$ git clone https://github.com/domdfcoding/singledispatch-json
Other Additional Information:
The error doesn't occur for Python 3.10.