diff options
-rw-r--r-- | CHANGES.txt | 6 | ||||
-rw-r--r-- | conf.py | 4 | ||||
-rw-r--r-- | index.rst | 14 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | simplejson/__init__.py | 2 | ||||
-rw-r--r-- | simplejson/_speedups.c | 2 | ||||
-rw-r--r-- | simplejson/encoder.py | 11 | ||||
-rw-r--r-- | simplejson/tests/test_namedtuple.py | 28 |
8 files changed, 50 insertions, 19 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 55d748f..eea200a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,9 @@ +Version 2.3.0 released 2011-12-05 + +* Any objects with _asdict() methods are now considered for + namedtuple_as_object. + https://github.com/simplejson/simplejson/pull/22 + Version 2.2.1 released 2011-09-06 * Fix MANIFEST.in issue when building a sdist from a sdist. @@ -42,9 +42,9 @@ copyright = '2011, Bob Ippolito' # other places throughout the built documents. # # The short X.Y version. -version = '2.2' +version = '2.3' # The full version, including alpha/beta/rc tags. -release = '2.2.1' +release = '2.3.0' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -190,12 +190,16 @@ Basic Usage The default of *use_decimal* changed to ``True`` in 2.2.0. If *namedtuple_as_object* is true (default: ``True``), - :class:`tuple` subclasses with ``_asdict()`` methods will be encoded + objects with ``_asdict()`` methods will be encoded as JSON objects. - + .. versionchanged:: 2.2.0 *namedtuple_as_object* is new in 2.2.0. + .. versionchanged:: 2.3.0 + *namedtuple_as_object* no longer requires that these objects be + subclasses of :class:`tuple`. + If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. @@ -484,12 +488,16 @@ Encoders and decoders ``'utf-8'``. If *namedtuple_as_object* is true (default: ``True``), - :class:`tuple` subclasses with ``_asdict()`` methods will be encoded + objects with ``_asdict()`` methods will be encoded as JSON objects. .. versionchanged:: 2.2.0 *namedtuple_as_object* is new in 2.2.0. + .. versionchanged:: 2.3.0 + *namedtuple_as_object* no longer requires that these objects be + subclasses of :class:`tuple`. + If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. @@ -7,7 +7,7 @@ from distutils.errors import CCompilerError, DistutilsExecError, \ DistutilsPlatformError IS_PYPY = hasattr(sys, 'pypy_translation_info') -VERSION = '2.2.1' +VERSION = '2.3.0' DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python" LONG_DESCRIPTION = open('README.rst', 'r').read() diff --git a/simplejson/__init__.py b/simplejson/__init__.py index ef5c0db..50886f6 100644 --- a/simplejson/__init__.py +++ b/simplejson/__init__.py @@ -97,7 +97,7 @@ Using simplejson.tool from the shell to validate and pretty-print:: $ echo '{ 1.2:3.4}' | python -m simplejson.tool Expecting property name: line 1 column 2 (char 2) """ -__version__ = '2.2.1' +__version__ = '2.3.0' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c index f8b0565..5169923 100644 --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -169,7 +169,7 @@ _is_namedtuple(PyObject *obj); static int _is_namedtuple(PyObject *obj) { - return PyTuple_Check(obj) && PyObject_HasAttrString(obj, "_asdict"); + return PyObject_HasAttrString(obj, "_asdict"); } static int diff --git a/simplejson/encoder.py b/simplejson/encoder.py index 5ec7440..383d834 100644 --- a/simplejson/encoder.py +++ b/simplejson/encoder.py @@ -155,7 +155,7 @@ class JSONEncoder(object): be supported directly by the encoder. For the inverse, decode JSON with ``parse_float=decimal.Decimal``. - If namedtuple_as_object is true (the default), tuple subclasses with + If namedtuple_as_object is true (the default), objects with ``_asdict()`` methods will be encoded as JSON objects. If tuple_as_array is true (the default), tuple (and subclasses) will @@ -387,8 +387,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, yield buf if isinstance(value, list): chunks = _iterencode_list(value, _current_indent_level) - elif (_namedtuple_as_object and isinstance(value, tuple) and - hasattr(value, '_asdict')): + elif (_namedtuple_as_object and hasattr(value, '_asdict')): chunks = _iterencode_dict(value._asdict(), _current_indent_level) elif _tuple_as_array and isinstance(value, tuple): @@ -472,8 +471,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, else: if isinstance(value, list): chunks = _iterencode_list(value, _current_indent_level) - elif (_namedtuple_as_object and isinstance(value, tuple) and - hasattr(value, '_asdict')): + elif (_namedtuple_as_object and hasattr(value, '_asdict')): chunks = _iterencode_dict(value._asdict(), _current_indent_level) elif _tuple_as_array and isinstance(value, tuple): @@ -507,8 +505,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, elif isinstance(o, list): for chunk in _iterencode_list(o, _current_indent_level): yield chunk - elif (_namedtuple_as_object and isinstance(o, tuple) and - hasattr(o, '_asdict')): + elif (_namedtuple_as_object and hasattr(o, '_asdict')): for chunk in _iterencode_dict(o._asdict(), _current_indent_level): yield chunk elif (_tuple_as_array and isinstance(o, tuple)): diff --git a/simplejson/tests/test_namedtuple.py b/simplejson/tests/test_namedtuple.py index 18da218..f4cdbe6 100644 --- a/simplejson/tests/test_namedtuple.py +++ b/simplejson/tests/test_namedtuple.py @@ -21,11 +21,24 @@ else: 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 TestNamedTuple(unittest.TestCase): def test_namedtuple_dumps(self): - for v in [Value(1), Point(1, 2)]: + for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]: d = v._asdict() - l = list(v) self.assertEqual(d, json.loads(json.dumps(v))) self.assertEqual( d, @@ -35,6 +48,10 @@ class TestNamedTuple(unittest.TestCase): 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))) @@ -42,9 +59,8 @@ class TestNamedTuple(unittest.TestCase): tuple_as_array=False, namedtuple_as_object=False) def test_namedtuple_dump(self): - for v in [Value(1), Point(1, 2)]: + for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]: d = v._asdict() - l = list(v) sio = StringIO() json.dump(v, sio) self.assertEqual(d, json.loads(sio.getvalue())) @@ -62,6 +78,10 @@ class TestNamedTuple(unittest.TestCase): 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( |