diff --git a/oslo_serialization/jsonutils.py b/oslo_serialization/jsonutils.py index 0e310b1..a2a700b 100644 --- a/oslo_serialization/jsonutils.py +++ b/oslo_serialization/jsonutils.py @@ -33,6 +33,7 @@ import codecs import datetime import functools import inspect +import io import itertools import json import uuid @@ -161,7 +162,7 @@ def to_primitive(value, convert_instances=False, convert_datetime=True, # Python 3 does not have iteritems elif hasattr(value, 'items'): return recursive(dict(value.items()), level=level + 1) - elif hasattr(value, '__iter__'): + elif hasattr(value, '__iter__') and not isinstance(value, io.IOBase): return list(map(recursive, value)) elif convert_instances and hasattr(value, '__dict__'): # Likely an instance of something. Watch for cycles. diff --git a/oslo_serialization/tests/test_jsonutils.py b/oslo_serialization/tests/test_jsonutils.py index e04b9dc..f076822 100644 --- a/oslo_serialization/tests/test_jsonutils.py +++ b/oslo_serialization/tests/test_jsonutils.py @@ -401,6 +401,16 @@ class ToPrimitiveTestCase(test_base.BaseTestCase): ret = jsonutils.to_primitive(obj, fallback=lambda _: 'fallback') self.assertEqual('fallback', ret) + def test_fallback_typeerror_IO_object(self): + # IO Objects are not callable, cause a TypeError in to_primitive() + obj = io.IOBase + + ret = jsonutils.to_primitive(obj) + self.assertEqual(str(obj), ret) + + ret = jsonutils.to_primitive(obj, fallback=lambda _: 'fallback') + self.assertEqual('fallback', ret) + def test_exception(self): self.assertIn(jsonutils.to_primitive(ValueError("an exception")), ["ValueError('an exception',)", diff --git a/releasenotes/notes/bug-1908607-fix-json-to_primitive-IO-OBjects-04faff4a1b5cf48f.yaml b/releasenotes/notes/bug-1908607-fix-json-to_primitive-IO-OBjects-04faff4a1b5cf48f.yaml new file mode 100644 index 0000000..0246ef7 --- /dev/null +++ b/releasenotes/notes/bug-1908607-fix-json-to_primitive-IO-OBjects-04faff4a1b5cf48f.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + `Bug #1908607 `_: Fix + json to_primitive when using IO OBjects.