summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Ippolito <bob@redivi.com>2011-12-05 13:17:44 -0800
committerBob Ippolito <bob@redivi.com>2011-12-05 13:17:44 -0800
commit8e96135943aab24f1f009f257711073e5edcd1f5 (patch)
tree98ce0881a5d45e58ba8193f0b7f7687a18eeb627
parent52d00503192973f36e629c8869652df1b65eb8be (diff)
parent0f17131614f6af0d4e9bbf065aa5c42cf1a25508 (diff)
downloadsimplejson-8e96135943aab24f1f009f257711073e5edcd1f5.tar.gz
Merge branch 'namedtuple_duck-gh22'v2.3.0
-rw-r--r--CHANGES.txt6
-rw-r--r--conf.py4
-rw-r--r--index.rst14
-rw-r--r--setup.py2
-rw-r--r--simplejson/__init__.py2
-rw-r--r--simplejson/_speedups.c2
-rw-r--r--simplejson/encoder.py11
-rw-r--r--simplejson/tests/test_namedtuple.py28
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.
diff --git a/conf.py b/conf.py
index e9cabf5..4b4537a 100644
--- a/conf.py
+++ b/conf.py
@@ -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:
diff --git a/index.rst b/index.rst
index 11f076e..fd92f4d 100644
--- a/index.rst
+++ b/index.rst
@@ -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.
diff --git a/setup.py b/setup.py
index c54f39c..534c333 100644
--- a/setup.py
+++ b/setup.py
@@ -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(