Hello community,

here is the log from the commit of package python-simplejson for 
openSUSE:Factory checked in at 2013-05-13 15:26:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-simplejson (Old)
 and      /work/SRC/openSUSE:Factory/.python-simplejson.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-simplejson"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-simplejson/python-simplejson.changes      
2013-04-14 10:39:13.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-simplejson.new/python-simplejson.changes 
2013-05-13 15:27:00.000000000 +0200
@@ -1,0 +2,8 @@
+Wed May  8 09:51:19 UTC 2013 - benny.gaech...@gmail.com
+
+- Update to version 3.3.0
+    * Unpaired surrogates once again pass through the decoder, to match older
+      behavior and the RFC-4627 spec.
+      https://github.com/simplejson/simplejson/issues/62 
+
+-------------------------------------------------------------------
--- /work/SRC/openSUSE:Factory/python-simplejson/python3-simplejson.changes     
2013-04-14 10:39:13.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-simplejson.new/python3-simplejson.changes    
    2013-05-13 15:27:00.000000000 +0200
@@ -1,0 +2,8 @@
+Wed May  8 09:51:08 UTC 2013 - benny.gaech...@gmail.com
+
+- Update to version 3.3.0
+    * Unpaired surrogates once again pass through the decoder, to match older
+      behavior and the RFC-4627 spec.
+      https://github.com/simplejson/simplejson/issues/62 
+
+-------------------------------------------------------------------

Old:
----
  simplejson-3.1.3.tar.gz

New:
----
  simplejson-3.3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-simplejson.spec ++++++
--- /var/tmp/diff_new_pack.C9w7xa/_old  2013-05-13 15:27:01.000000000 +0200
+++ /var/tmp/diff_new_pack.C9w7xa/_new  2013-05-13 15:27:01.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-simplejson
-Version:        3.1.3
+Version:        3.3.0
 Release:        0
 Url:            http://github.com/simplejson/simplejson
 Summary:        Simple, fast, extensible JSON encoder/decoder for Python

python3-simplejson.spec: same change
++++++ simplejson-3.1.3.tar.gz -> simplejson-3.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/CHANGES.txt 
new/simplejson-3.3.0/CHANGES.txt
--- old/simplejson-3.1.3/CHANGES.txt    2013-04-06 23:19:13.000000000 +0200
+++ new/simplejson-3.3.0/CHANGES.txt    2013-05-08 08:04:12.000000000 +0200
@@ -1,3 +1,19 @@
+Version 3.3.0 released 2013-05-07
+
+* Unpaired surrogates once again pass through the decoder, to match older
+  behavior and the RFC-4627 spec.
+  https://github.com/simplejson/simplejson/issues/62
+
+Version 3.2.0 released 2013-05-01
+
+* New ignore_nan kwarg in encoder that serializes out
+  of range floats (Infinity, -Infinity, NaN) as null for ECMA-262
+  compliance.
+  https://github.com/simplejson/simplejson/pull/63
+* New for_json kwarg in encoder to make it possible to for
+  subclasses of dict and list to be specialized.
+  https://github.com/simplejson/simplejson/pull/69
+
 Version 3.1.3 released 2013-04-06
 
 * Updated documentation to discourage subclassing whenever possible.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/PKG-INFO 
new/simplejson-3.3.0/PKG-INFO
--- old/simplejson-3.1.3/PKG-INFO       2013-04-06 23:19:44.000000000 +0200
+++ new/simplejson-3.3.0/PKG-INFO       2013-05-08 11:30:45.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: simplejson
-Version: 3.1.3
+Version: 3.3.0
 Summary: Simple, fast, extensible JSON encoder/decoder for Python
 Home-page: http://github.com/simplejson/simplejson
 Author: Bob Ippolito
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/conf.py new/simplejson-3.3.0/conf.py
--- old/simplejson-3.1.3/conf.py        2013-04-05 21:22:25.000000000 +0200
+++ new/simplejson-3.3.0/conf.py        2013-05-08 08:04:12.000000000 +0200
@@ -42,9 +42,9 @@
 # other places throughout the built documents.
 #
 # The short X.Y version.
-version = '3.1'
+version = '3.3'
 # The full version, including alpha/beta/rc tags.
-release = '3.1.3'
+release = '3.3.0'
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/index.rst 
new/simplejson-3.3.0/index.rst
--- old/simplejson-3.1.3/index.rst      2013-04-05 21:16:34.000000000 +0200
+++ new/simplejson-3.3.0/index.rst      2013-05-01 22:01:12.000000000 +0200
@@ -129,7 +129,7 @@
 Basic Usage
 -----------
 
-.. function:: dump(obj, fp[, skipkeys[, ensure_ascii[, check_circular[, 
allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, 
namedtuple_as_object[, tuple_as_array[, bigint_as_string[, sort_keys[, 
item_sort_key[, **kw]]]]]]]]]]]]]]]])
+.. function:: dump(obj, fp[, skipkeys[, ensure_ascii[, check_circular[, 
allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, 
namedtuple_as_object[, tuple_as_array[, bigint_as_string[, sort_keys[, 
item_sort_key[, [for_json[, ignore_nan[, **kw]]]]]]]]]]]]]]]]]]])
 
    Serialize *obj* as a JSON formatted stream to *fp* (a 
``.write()``-supporting
    file-like object).
@@ -152,9 +152,10 @@
 
    If *allow_nan* is false (default: ``True``), then it will be a
    :exc:`ValueError` to serialize out of range :class:`float` values (``nan``,
-   ``inf``, ``-inf``) in strict compliance of the JSON specification.
+   ``inf``, ``-inf``) in strict compliance of the original JSON specification.
    If *allow_nan* is true, their JavaScript equivalents will be used
-   (``NaN``, ``Infinity``, ``-Infinity``).
+   (``NaN``, ``Infinity``, ``-Infinity``). See also *ignore_nan* for ECMA-262
+   compliant behavior.
 
    If *indent* is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
@@ -187,7 +188,7 @@
    .. note::
 
         Subclassing is not recommended. Use the *default* kwarg
-        instead. This is faster and more portable.
+        or *for_json* instead. This is faster and more portable.
 
    If *use_decimal* is true (default: ``True``) then :class:`decimal.Decimal`
    will be natively serialized to JSON with full precision.
@@ -245,14 +246,29 @@
       strings, to avoid comparison of heterogeneously typed objects
       (since this does not work in Python 3.3+)
 
-    .. note::
+   If *for_json* is true (not the default), objects with a ``for_json()``
+   method will use the return value of that method for encoding as JSON instead
+   of the object.
+
+   .. versionchanged:: 3.2.0
+      *for_json* is new in 3.2.0.
+
+   If *ignore_nan* is true (default: ``False``), then out of range
+   :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
+   ``null`` in compliance with the ECMA-262 specification. If true, this will
+   override *allow_nan*.
+
+   .. versionchanged:: 3.2.0
+      *ignore_nan* is new in 3.2.0.
+
+  .. note::
 
         JSON is not a framed protocol so unlike :mod:`pickle` or 
:mod:`marshal` it
         does not make sense to serialize more than one JSON document without 
some
         container protocol to delimit them.
 
 
-.. function:: dumps(obj[, skipkeys[, ensure_ascii[, check_circular[, 
allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, 
namedtuple_as_object[, tuple_as_array[, bigint_as_string[, sort_keys[, 
item_sort_key[, **kw]]]]]]]]]]]]]]]])
+.. function:: dumps(obj[, skipkeys[, ensure_ascii[, check_circular[, 
allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, 
namedtuple_as_object[, tuple_as_array[, bigint_as_string[, sort_keys[, 
item_sort_key[, for_json[, ignore_nan[, **kw]]]]]]]]]]]]]]]]]])
 
    Serialize *obj* to a JSON formatted :class:`str`.
 
@@ -261,6 +277,8 @@
    :func:`dump`. Note that the default *ensure_ascii* setting has much
    better performance.
 
+   The other options have the same meaning as in :func:`dump`.
+
 
 .. function:: load(fp[, encoding[, cls[, object_hook[, parse_float[, 
parse_int[, parse_constant[, object_pairs_hook[, use_decimal[, **kw]]]]]]]]])
 
@@ -456,7 +474,7 @@
       :exc:`JSONDecodeError` will be raised if the given JSON
       document is not valid.
 
-.. class:: JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, 
sort_keys[, indent[, separators[, encoding[, default[, use_decimal[, 
namedtuple_as_object[, tuple_as_array[, bigint_as_string[, 
item_sort_key]]]]]]]]]]]]])
+.. class:: JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, 
sort_keys[, indent[, separators[, encoding[, default[, use_decimal[, 
namedtuple_as_object[, tuple_as_array[, bigint_as_string[, item_sort_key[, 
for_json[, ignore_nan]]]]]]]]]]]]]]]])
 
    Extensible JSON encoder for Python data structures.
 
@@ -491,7 +509,7 @@
     .. note::
 
         Subclassing is not recommended. You should use the *default*
-        kwarg. This is faster and more portable than subclassing.
+        or *for_json* kwarg. This is faster and more portable than subclassing.
 
    If *skipkeys* is false (the default), then it is a :exc:`TypeError` to
    attempt encoding of keys that are not str, int, long, float or None.  If
@@ -507,10 +525,10 @@
    Otherwise, no such check takes place.
 
    If *allow_nan* is true (the default), then ``NaN``, ``Infinity``, and
-   ``-Infinity`` will be encoded as such.  This behavior is not JSON
+   ``-Infinity`` will be encoded as such. This behavior is not JSON
    specification compliant, but is consistent with most JavaScript based
    encoders and decoders.  Otherwise, it will be a :exc:`ValueError` to encode
-   such floats.
+   such floats. See also *ignore_nan* for ECMA-262 compliant behavior.
 
    If *sort_keys* is true (not the default), then the output of dictionaries
    will be sorted by key; this is useful for regression tests to ensure that
@@ -587,6 +605,20 @@
    .. versionchanged:: 2.4.0
      *bigint_as_string* is new in 2.4.0.
 
+   If *for_json* is true (default: ``False``), objects with a ``for_json()``
+   method will use the return value of that method for encoding as JSON instead
+   of the object.
+
+   .. versionchanged:: 3.2.0
+     *for_json* is new in 3.2.0.
+
+   If *ignore_nan* is true (default: ``False``), then out of range
+   :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
+   ``null`` in compliance with the ECMA-262 specification. If true, this will
+   override *allow_nan*.
+
+   .. versionchanged:: 3.2.0
+      *ignore_nan* is new in 3.2.0.
 
    .. method:: default(o)
 
@@ -635,7 +667,7 @@
       Note that :meth:`encode` has much better performance than
       :meth:`iterencode`.
 
-.. class:: JSONEncoderForHTML([skipkeys[, ensure_ascii[, check_circular[, 
allow_nan[, sort_keys[, indent[, separators[, encoding[, default[, 
use_decimal[, namedtuple_as_object[, tuple_as_array[, bigint_as_string[, 
item_sort_key]]]]]]]]]]]]])
+.. class:: JSONEncoderForHTML([skipkeys[, ensure_ascii[, check_circular[, 
allow_nan[, sort_keys[, indent[, separators[, encoding[, default[, 
use_decimal[, namedtuple_as_object[, tuple_as_array[, bigint_as_string[, 
item_sort_key[, for_json[, ignore_nan]]]]]]]]]]]]]]]])
 
    Subclass of :class:`JSONEncoder` that escapes &, <, and > for embedding in 
HTML.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/setup.py 
new/simplejson-3.3.0/setup.py
--- old/simplejson-3.1.3/setup.py       2013-04-05 21:22:05.000000000 +0200
+++ new/simplejson-3.3.0/setup.py       2013-05-08 08:04:12.000000000 +0200
@@ -8,7 +8,7 @@
     DistutilsPlatformError
 
 IS_PYPY = hasattr(sys, 'pypy_translation_info')
-VERSION = '3.1.3'
+VERSION = '3.3.0'
 DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python"
 
 with open('README.rst', 'r') as f:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/__init__.py 
new/simplejson-3.3.0/simplejson/__init__.py
--- old/simplejson-3.1.3/simplejson/__init__.py 2013-04-05 21:22:15.000000000 
+0200
+++ new/simplejson-3.3.0/simplejson/__init__.py 2013-05-08 08:04:12.000000000 
+0200
@@ -98,7 +98,7 @@
     Expecting property name: line 1 column 3 (char 2)
 """
 from __future__ import absolute_import
-__version__ = '3.1.3'
+__version__ = '3.3.0'
 __all__ = [
     'dump', 'dumps', 'load', 'loads',
     'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
@@ -142,6 +142,8 @@
     tuple_as_array=True,
     bigint_as_string=False,
     item_sort_key=None,
+    for_json=False,
+    ignore_nan=False,
 )
 
 def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
@@ -149,28 +151,29 @@
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
         bigint_as_string=False, sort_keys=False, item_sort_key=None,
-        **kw):
+        for_json=False, ignore_nan=False, **kw):
     """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
     ``.write()``-supporting file-like object).
 
-    If ``skipkeys`` is true then ``dict`` keys that are not basic types
+    If *skipkeys* is true then ``dict`` keys that are not basic types
     (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
     will be skipped instead of raising a ``TypeError``.
 
-    If ``ensure_ascii`` is false, then the some chunks written to ``fp``
+    If *ensure_ascii* is false, then the some chunks written to ``fp``
     may be ``unicode`` instances, subject to normal Python ``str`` to
     ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
     understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
     to cause an error.
 
-    If ``check_circular`` is false, then the circular reference check
+    If *check_circular* is false, then the circular reference check
     for container types will be skipped and a circular reference will
     result in an ``OverflowError`` (or worse).
 
-    If ``allow_nan`` is false, then it will be a ``ValueError`` to
+    If *allow_nan* is false, then it will be a ``ValueError`` to
     serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
-    in strict compliance of the JSON specification, instead of using the
-    JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
+    in strict compliance of the original JSON specification, instead of using
+    the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). See
+    *ignore_nan* for ECMA-262 compliant behavior.
 
     If *indent* is a string, then JSON array elements and object members
     will be pretty-printed with a newline followed by that string repeated
@@ -179,16 +182,16 @@
     versions of simplejson earlier than 2.1.0, an integer is also accepted
     and is converted to a string with that many spaces.
 
-    If specified, ``separators`` should be an
+    If specified, *separators* should be an
     ``(item_separator, key_separator)`` tuple.  The default is ``(', ', ': ')``
     if *indent* is ``None`` and ``(',', ': ')`` otherwise.  To get the most
     compact JSON representation, you should specify ``(',', ':')`` to eliminate
     whitespace.
 
-    ``encoding`` is the character encoding for str instances, default is UTF-8.
+    *encoding* is the character encoding for str instances, default is UTF-8.
 
-    ``default(obj)`` is a function that should return a serializable version
-    of obj or raise TypeError. The default simply raises TypeError.
+    *default(obj)* is a function that should return a serializable version
+    of obj or raise ``TypeError``. The default simply raises ``TypeError``.
 
     If *use_decimal* is true (default: ``True``) then decimal.Decimal
     will be natively serialized to JSON with full precision.
@@ -214,10 +217,19 @@
     If *sort_keys* is true (default: ``False``), the output of dictionaries
     will be sorted by item.
 
+    If *for_json* is true (default: ``False``), objects with a ``for_json()``
+    method will use the return value of that method for encoding as JSON
+    instead of the object.
+
+    If *ignore_nan* is true (default: ``False``), then out of range
+    :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
+    ``null`` in compliance with the ECMA-262 specification. If true, this will
+    override *allow_nan*.
+
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
-    the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
-    whenever possible.
+    the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead
+    of subclassing whenever possible.
 
     """
     # cached encoder
@@ -226,7 +238,8 @@
         cls is None and indent is None and separators is None and
         encoding == 'utf-8' and default is None and use_decimal
         and namedtuple_as_object and tuple_as_array
-        and not bigint_as_string and not item_sort_key and not kw):
+        and not bigint_as_string and not item_sort_key
+        and not for_json and not ignore_nan and not kw):
         iterable = _default_encoder.iterencode(obj)
     else:
         if cls is None:
@@ -240,6 +253,8 @@
             bigint_as_string=bigint_as_string,
             sort_keys=sort_keys,
             item_sort_key=item_sort_key,
+            for_json=for_json,
+            ignore_nan=ignore_nan,
             **kw).iterencode(obj)
     # could accelerate with writelines in some versions of Python, at
     # a debuggability cost
@@ -252,7 +267,7 @@
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
         bigint_as_string=False, sort_keys=False, item_sort_key=None,
-        **kw):
+        for_json=False, ignore_nan=False, **kw):
     """Serialize ``obj`` to a JSON formatted ``str``.
 
     If ``skipkeys`` is false then ``dict`` keys that are not basic types
@@ -312,6 +327,15 @@
     If *sort_keys* is true (default: ``False``), the output of dictionaries
     will be sorted by item.
 
+    If *for_json* is true (default: ``False``), objects with a ``for_json()``
+    method will use the return value of that method for encoding as JSON
+    instead of the object.
+
+    If *ignore_nan* is true (default: ``False``), then out of range
+    :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
+    ``null`` in compliance with the ECMA-262 specification. If true, this will
+    override *allow_nan*.
+
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
     the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
@@ -325,7 +349,8 @@
         encoding == 'utf-8' and default is None and use_decimal
         and namedtuple_as_object and tuple_as_array
         and not bigint_as_string and not sort_keys
-        and not item_sort_key and not kw):
+        and not item_sort_key and not for_json
+        and not ignore_nan and not kw):
         return _default_encoder.encode(obj)
     if cls is None:
         cls = JSONEncoder
@@ -339,6 +364,8 @@
         bigint_as_string=bigint_as_string,
         sort_keys=sort_keys,
         item_sort_key=item_sort_key,
+        for_json=for_json,
+        ignore_nan=ignore_nan,
         **kw).encode(obj)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/_speedups.c 
new/simplejson-3.3.0/simplejson/_speedups.c
--- old/simplejson-3.1.3/simplejson/_speedups.c 2013-02-22 00:37:09.000000000 
+0100
+++ new/simplejson-3.3.0/simplejson/_speedups.c 2013-05-08 08:04:12.000000000 
+0200
@@ -93,6 +93,9 @@
 #define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType)
 #define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType)
 
+#define JSON_ALLOW_NAN 1
+#define JSON_IGNORE_NAN 2
+
 static PyTypeObject PyScannerType;
 static PyTypeObject PyEncoderType;
 
@@ -121,9 +124,6 @@
 #define ERR_STRING_CONTROL "Invalid control character %r at"
 #define ERR_STRING_ESC1 "Invalid \\X escape sequence %r"
 #define ERR_STRING_ESC4 "Invalid \\uXXXX escape sequence"
-#define ERR_STRING_SURROGATE "Invalid \\uXXXX\\uXXXX surrogate pair"
-#define ERR_STRING_HIGH_SURROGATE "Unpaired high surrogate"
-#define ERR_STRING_LOW_SURROGATE "Unpaired low surrogate"
 
 typedef struct _PyScannerObject {
     PyObject_HEAD
@@ -163,13 +163,15 @@
     PyObject *skipkeys_bool;
     int skipkeys;
     int fast_encode;
-    int allow_nan;
+    /* 0, JSON_ALLOW_NAN, JSON_IGNORE_NAN */
+    int allow_or_ignore_nan;
     int use_decimal;
     int namedtuple_as_object;
     int tuple_as_array;
     int bigint_as_string;
     PyObject *item_sort_key;
     PyObject *item_sort_kw;
+    int for_json;
 } PyEncoderObject;
 
 static PyMemberDef encoder_members[] = {
@@ -260,6 +262,8 @@
 encoder_encode_float(PyEncoderObject *s, PyObject *obj);
 static int
 _is_namedtuple(PyObject *obj);
+static int
+_has_for_json_hook(PyObject *obj);
 static PyObject *
 moduleinit(void);
 
@@ -427,6 +431,20 @@
 }
 
 static int
+_has_for_json_hook(PyObject *obj)
+{
+    int rval = 0;
+    PyObject *for_json = PyObject_GetAttrString(obj, "for_json");
+    if (for_json == NULL) {
+        PyErr_Clear();
+        return 0;
+    }
+    rval = PyCallable_Check(for_json);
+    Py_DECREF(for_json);
+    return rval;
+}
+
+static int
 _convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr)
 {
     /* PyObject to Py_ssize_t converter */
@@ -708,11 +726,11 @@
             goto bail;
 #if PY_MAJOR_VERSION < 3
         else if (PyString_Check(key)) {
-            // item can be added as-is
+            /* item can be added as-is */
         }
 #endif /* PY_MAJOR_VERSION < 3 */
         else if (PyUnicode_Check(key)) {
-            // item can be added as-is
+            /* item can be added as-is */
         }
         else {
             PyObject *tpl;
@@ -720,7 +738,7 @@
             if (kstr == NULL)
                 goto bail;
             else if (kstr == Py_None) {
-                // skipkeys
+                /* skipkeys */
                 Py_DECREF(kstr);
                 continue;
             }
@@ -1004,21 +1022,14 @@
 #if (PY_MAJOR_VERSION >= 3 || defined(Py_UNICODE_WIDE))
             /* Surrogate pair */
             if ((c & 0xfc00) == 0xd800) {
-                JSON_UNICHR c2 = 0;
-                if (end + 6 >= len) {
-                    raise_errmsg(ERR_STRING_HIGH_SURROGATE, pystr, end - 5);
-                    goto bail;
-                }
-                if (buf[next++] != '\\' || buf[next++] != 'u') {
-                    raise_errmsg(ERR_STRING_HIGH_SURROGATE, pystr, end - 5);
-                    goto bail;
-                }
-                end += 6;
-                /* Decode 4 hex digits */
-                for (; next < end; next++) {
-                    c2 <<= 4;
-                    JSON_UNICHR digit = buf[next];
-                    switch (digit) {
+                if (end + 6 < len && buf[next] == '\\' && buf[next+1] == 'u') {
+                   JSON_UNICHR c2 = 0;
+                   end += 6;
+                   /* Decode 4 hex digits */
+                   for (next += 2; next < end; next++) {
+                       c2 <<= 4;
+                       JSON_UNICHR digit = buf[next];
+                       switch (digit) {
                         case '0': case '1': case '2': case '3': case '4':
                         case '5': case '6': case '7': case '8': case '9':
                             c2 |= (digit - '0'); break;
@@ -1031,18 +1042,18 @@
                         default:
                             raise_errmsg(ERR_STRING_ESC4, pystr, end - 5);
                             goto bail;
-                    }
-                }
-                if ((c2 & 0xfc00) != 0xdc00) {
-                    raise_errmsg(ERR_STRING_HIGH_SURROGATE, pystr, end - 5);
-                    goto bail;
-                }
-                c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00));
-            }
-            else if ((c & 0xfc00) == 0xdc00) {
-                raise_errmsg(ERR_STRING_LOW_SURROGATE, pystr, end - 5);
-                goto bail;
-            }
+                       }
+                   }
+                   if ((c2 & 0xfc00) != 0xdc00) {
+                       /* not a low surrogate, rewind */
+                       end -= 6;
+                       next = end;
+                   }
+                   else {
+                       c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00));
+                   }
+               }
+           }
 #endif /* PY_MAJOR_VERSION >= 3 || Py_UNICODE_WIDE */
         }
         if (c > 0x7f) {
@@ -1213,21 +1224,15 @@
             /* Surrogate pair */
             if ((c & 0xfc00) == 0xd800) {
                 JSON_UNICHR c2 = 0;
-                if (end + 6 >= len) {
-                    raise_errmsg(ERR_STRING_HIGH_SURROGATE, pystr, end - 5);
-                    goto bail;
-                }
-                if (PyUnicode_READ(kind, buf, next++) != '\\' ||
-                    PyUnicode_READ(kind, buf, next++) != 'u') {
-                    raise_errmsg(ERR_STRING_HIGH_SURROGATE, pystr, end - 5);
-                    goto bail;
-                }
-                end += 6;
-                /* Decode 4 hex digits */
-                for (; next < end; next++) {
-                    JSON_UNICHR digit = PyUnicode_READ(kind, buf, next);
-                    c2 <<= 4;
-                    switch (digit) {
+               if (end + 6 < len &&
+                   PyUnicode_READ(kind, buf, next) == '\\' &&
+                   PyUnicode_READ(kind, buf, next + 1) == 'u') {
+                   end += 6;
+                   /* Decode 4 hex digits */
+                   for (next += 2; next < end; next++) {
+                       JSON_UNICHR digit = PyUnicode_READ(kind, buf, next);
+                       c2 <<= 4;
+                       switch (digit) {
                         case '0': case '1': case '2': case '3': case '4':
                         case '5': case '6': case '7': case '8': case '9':
                             c2 |= (digit - '0'); break;
@@ -1240,18 +1245,18 @@
                         default:
                             raise_errmsg(ERR_STRING_ESC4, pystr, end - 5);
                             goto bail;
-                    }
-                }
-                if ((c2 & 0xfc00) != 0xdc00) {
-                    raise_errmsg(ERR_STRING_HIGH_SURROGATE, pystr, end - 5);
-                    goto bail;
-                }
-                c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00));
-            }
-            else if ((c & 0xfc00) == 0xdc00) {
-                raise_errmsg(ERR_STRING_LOW_SURROGATE, pystr, end - 5);
-                goto bail;
-            }
+                       }
+                   }
+                   if ((c2 & 0xfc00) != 0xdc00) {
+                       /* not a low surrogate, rewind */
+                       end -= 6;
+                       next = end;
+                   }
+                   else {
+                       c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00));
+                   }
+               }
+           }
 #endif
         }
         APPEND_OLD_CHUNK
@@ -2571,22 +2576,23 @@
 encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
     /* initialize Encoder object */
-    static char *kwlist[] = {"markers", "default", "encoder", "indent", 
"key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", 
"key_memo", "use_decimal", "namedtuple_as_object", "tuple_as_array", 
"bigint_as_string", "item_sort_key", "encoding", "Decimal", NULL};
+    static char *kwlist[] = {"markers", "default", "encoder", "indent", 
"key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", 
"key_memo", "use_decimal", "namedtuple_as_object", "tuple_as_array", 
"bigint_as_string", "item_sort_key", "encoding", "for_json", "ignore_nan", 
"Decimal", NULL};
 
     PyEncoderObject *s;
     PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
     PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan, *key_memo;
     PyObject *use_decimal, *namedtuple_as_object, *tuple_as_array;
-    PyObject *bigint_as_string, *item_sort_key, *encoding, *Decimal;
+    PyObject *bigint_as_string, *item_sort_key, *encoding, *for_json;
+    PyObject *ignore_nan, *Decimal;
 
     assert(PyEncoder_Check(self));
     s = (PyEncoderObject *)self;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"OOOOOOOOOOOOOOOOO:make_encoder", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"OOOOOOOOOOOOOOOOOOO:make_encoder", kwlist,
         &markers, &defaultfn, &encoder, &indent, &key_separator, 
&item_separator,
         &sort_keys, &skipkeys, &allow_nan, &key_memo, &use_decimal,
         &namedtuple_as_object, &tuple_as_array, &bigint_as_string,
-        &item_sort_key, &encoding, &Decimal))
+        &item_sort_key, &encoding, &for_json, &ignore_nan, &Decimal))
         return -1;
 
     s->markers = markers;
@@ -2602,7 +2608,9 @@
     s->skipkeys = PyObject_IsTrue(skipkeys);
     s->key_memo = key_memo;
     s->fast_encode = (PyCFunction_Check(s->encoder) && 
PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii);
-    s->allow_nan = PyObject_IsTrue(allow_nan);
+    s->allow_or_ignore_nan = (
+        (PyObject_IsTrue(ignore_nan) ? JSON_IGNORE_NAN : 0) |
+        (PyObject_IsTrue(allow_nan) ? JSON_ALLOW_NAN : 0));
     s->use_decimal = PyObject_IsTrue(use_decimal);
     s->namedtuple_as_object = PyObject_IsTrue(namedtuple_as_object);
     s->tuple_as_array = PyObject_IsTrue(tuple_as_array);
@@ -2638,6 +2646,7 @@
     s->sort_keys = sort_keys;
     s->item_sort_key = item_sort_key;
     s->Decimal = Decimal;
+    s->for_json = PyObject_IsTrue(for_json);
 
     Py_INCREF(s->markers);
     Py_INCREF(s->defaultfn);
@@ -2716,11 +2725,15 @@
     /* Return the JSON representation of a PyFloat */
     double i = PyFloat_AS_DOUBLE(obj);
     if (!Py_IS_FINITE(i)) {
-        if (!s->allow_nan) {
+        if (!s->allow_or_ignore_nan) {
             PyErr_SetString(PyExc_ValueError, "Out of range float values are 
not JSON compliant");
             return NULL;
         }
-        if (i > 0) {
+        if (s->allow_or_ignore_nan & JSON_IGNORE_NAN) {
+            return _encoded_const(Py_None);
+        }
+        /* JSON_ALLOW_NAN is set */
+        else if (i > 0) {
             static PyObject *sInfinity = NULL;
             if (sInfinity == NULL)
                 sInfinity = JSON_InternFromString("Infinity");
@@ -2801,6 +2814,17 @@
             if (encoded != NULL)
                 rv = _steal_accumulate(rval, encoded);
         }
+        else if (s->for_json && _has_for_json_hook(obj)) {
+            PyObject *newobj;
+            if (Py_EnterRecursiveCall(" while encoding a JSON object"))
+                return rv;
+            newobj = PyObject_CallMethod(obj, "for_json", NULL);
+            if (newobj != NULL) {
+                rv = encoder_listencode_obj(s, rval, newobj, indent_level);
+                Py_DECREF(newobj);
+            }
+            Py_LeaveRecursiveCall();
+        }
         else if (s->namedtuple_as_object && _is_namedtuple(obj)) {
             PyObject *newobj;
             if (Py_EnterRecursiveCall(" while encoding a JSON object"))
@@ -2956,7 +2980,7 @@
             if (kstr == NULL)
                 goto bail;
             else if (kstr == Py_None) {
-                // skipkeys
+                /* skipkeys */
                 Py_DECREF(item);
                 Py_DECREF(kstr);
                 continue;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/decoder.py 
new/simplejson-3.3.0/simplejson/decoder.py
--- old/simplejson-3.1.3/simplejson/decoder.py  2013-02-22 00:37:09.000000000 
+0100
+++ new/simplejson-3.3.0/simplejson/decoder.py  2013-05-08 08:04:12.000000000 
+0200
@@ -102,36 +102,32 @@
             # Unicode escape sequence
             msg = "Invalid \\uXXXX escape sequence"
             esc = s[end + 1:end + 5]
-            next_end = end + 5
-            if len(esc) != 4:
-                raise JSONDecodeError(msg, s, end)
+            escX = esc[1:2]
+            if len(esc) != 4 or escX == 'x' or escX == 'X':
+                raise JSONDecodeError(msg, s, end - 1)
             try:
                 uni = int(esc, 16)
             except ValueError:
-                raise JSONDecodeError(msg, s, end)
+                raise JSONDecodeError(msg, s, end - 1)
+            end += 5
             # Check for surrogate pair on UCS-4 systems
-            if _maxunicode > 65535:
-                unimask = uni & 0xfc00
-                if unimask == 0xd800:
-                    msg = "Unpaired high surrogate"
-                    if not s[end + 5:end + 7] == '\\u':
-                        raise JSONDecodeError(msg, s, end)
-                    esc2 = s[end + 7:end + 11]
-                    if len(esc2) != 4:
-                        raise JSONDecodeError(msg, s, end)
+            # Note that this will join high/low surrogate pairs
+            # but will also pass unpaired surrogates through
+            if (_maxunicode > 65535 and
+                uni & 0xfc00 == 0xd800 and
+                s[end:end + 2] == '\\u'):
+                esc2 = s[end + 2:end + 6]
+                escX = esc2[1:2]
+                if len(esc2) == 4 and not (escX == 'x' or escX == 'X'):
                     try:
                         uni2 = int(esc2, 16)
                     except ValueError:
                         raise JSONDecodeError(msg, s, end)
-                    if uni2 & 0xfc00 != 0xdc00:
-                        raise JSONDecodeError(msg, s, end)
-                    uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
-                    next_end += 6
-                elif unimask == 0xdc00:
-                    msg = "Unpaired low surrogate"
-                    raise JSONDecodeError(msg, s, end)
+                    if uni2 & 0xfc00 == 0xdc00:
+                        uni = 0x10000 + (((uni - 0xd800) << 10) |
+                                         (uni2 - 0xdc00))
+                        end += 6
             char = unichr(uni)
-            end = next_end
         # Append the unescaped character
         _append(char)
     return _join(chunks), end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/encoder.py 
new/simplejson-3.3.0/simplejson/encoder.py
--- old/simplejson-3.1.3/simplejson/encoder.py  2013-02-22 20:23:53.000000000 
+0100
+++ new/simplejson-3.3.0/simplejson/encoder.py  2013-05-01 22:01:12.000000000 
+0200
@@ -121,7 +121,7 @@
             indent=None, separators=None, encoding='utf-8', default=None,
             use_decimal=True, namedtuple_as_object=True,
             tuple_as_array=True, bigint_as_string=False,
-            item_sort_key=None):
+            item_sort_key=None, for_json=False, ignore_nan=False):
         """Constructor for JSONEncoder, with sensible defaults.
 
         If skipkeys is false, then it is a TypeError to attempt
@@ -183,6 +183,16 @@
         If specified, item_sort_key is a callable used to sort the items in
         each dictionary. This is useful if you want to sort items other than
         in alphabetical order by key.
+
+        If for_json is true (not the default), objects with a ``for_json()``
+        method will use the return value of that method for encoding as JSON
+        instead of the object.
+
+        If *ignore_nan* is true (default: ``False``), then out of range
+        :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized
+        as ``null`` in compliance with the ECMA-262 specification. If true,
+        this will override *allow_nan*.
+
         """
 
         self.skipkeys = skipkeys
@@ -195,6 +205,8 @@
         self.tuple_as_array = tuple_as_array
         self.bigint_as_string = bigint_as_string
         self.item_sort_key = item_sort_key
+        self.for_json = for_json
+        self.ignore_nan = ignore_nan
         if indent is not None and not isinstance(indent, string_types):
             indent = indent * ' '
         self.indent = indent
@@ -279,7 +291,7 @@
                     o = o.decode(_encoding)
                 return _orig_encoder(o)
 
-        def floatstr(o, allow_nan=self.allow_nan,
+        def floatstr(o, allow_nan=self.allow_nan, ignore_nan=self.ignore_nan,
                 _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf):
             # Check for specials. Note that this type of test is processor
             # and/or platform-specific, so do tests which don't depend on
@@ -294,7 +306,9 @@
             else:
                 return _repr(o)
 
-            if not allow_nan:
+            if ignore_nan:
+                text = 'null'
+            elif not allow_nan:
                 raise ValueError(
                     "Out of range float values are not JSON compliant: " +
                     repr(o))
@@ -311,7 +325,7 @@
                 self.skipkeys, self.allow_nan, key_memo, self.use_decimal,
                 self.namedtuple_as_object, self.tuple_as_array,
                 self.bigint_as_string, self.item_sort_key,
-                self.encoding,
+                self.encoding, self.for_json, self.ignore_nan,
                 Decimal)
         else:
             _iterencode = _make_iterencode(
@@ -320,7 +334,7 @@
                 self.skipkeys, _one_shot, self.use_decimal,
                 self.namedtuple_as_object, self.tuple_as_array,
                 self.bigint_as_string, self.item_sort_key,
-                self.encoding,
+                self.encoding, self.for_json,
                 Decimal=Decimal)
         try:
             return _iterencode(o, 0)
@@ -358,7 +372,7 @@
 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
         _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
         _use_decimal, _namedtuple_as_object, _tuple_as_array,
-        _bigint_as_string, _item_sort_key, _encoding,
+        _bigint_as_string, _item_sort_key, _encoding, _for_json,
         ## HACK: hand-optimized bytecode; turn globals into locals
         _PY3=PY3,
         ValueError=ValueError,
@@ -422,7 +436,10 @@
                 yield buf + str(value)
             else:
                 yield buf
-                if isinstance(value, list):
+                for_json = _for_json and getattr(value, 'for_json', None)
+                if for_json and callable(for_json):
+                    chunks = _iterencode(for_json(), _current_indent_level)
+                elif isinstance(value, list):
                     chunks = _iterencode_list(value, _current_indent_level)
                 else:
                     _asdict = _namedtuple_as_object and getattr(value, 
'_asdict', None)
@@ -532,7 +549,10 @@
             elif _use_decimal and isinstance(value, Decimal):
                 yield str(value)
             else:
-                if isinstance(value, list):
+                for_json = _for_json and getattr(value, 'for_json', None)
+                if for_json and callable(for_json):
+                    chunks = _iterencode(for_json(), _current_indent_level)
+                elif isinstance(value, list):
                     chunks = _iterencode_list(value, _current_indent_level)
                 else:
                     _asdict = _namedtuple_as_object and getattr(value, 
'_asdict', None)
@@ -571,32 +591,38 @@
                        else ('"' + str(o) + '"'))
         elif isinstance(o, float):
             yield _floatstr(o)
-        elif isinstance(o, list):
-            for chunk in _iterencode_list(o, _current_indent_level):
-                yield chunk
-        else:
-            _asdict = _namedtuple_as_object and getattr(o, '_asdict', None)
-            if _asdict and callable(_asdict):
-                for chunk in _iterencode_dict(_asdict(), 
_current_indent_level):
+        else:
+            for_json = _for_json and getattr(o, 'for_json', None)
+            if for_json and callable(for_json):
+                for chunk in _iterencode(for_json(), _current_indent_level):
                     yield chunk
-            elif (_tuple_as_array and isinstance(o, tuple)):
+            elif isinstance(o, list):
                 for chunk in _iterencode_list(o, _current_indent_level):
                     yield chunk
-            elif isinstance(o, dict):
-                for chunk in _iterencode_dict(o, _current_indent_level):
-                    yield chunk
-            elif _use_decimal and isinstance(o, Decimal):
-                yield str(o)
             else:
-                if markers is not None:
-                    markerid = id(o)
-                    if markerid in markers:
-                        raise ValueError("Circular reference detected")
-                    markers[markerid] = o
-                o = _default(o)
-                for chunk in _iterencode(o, _current_indent_level):
-                    yield chunk
-                if markers is not None:
-                    del markers[markerid]
+                _asdict = _namedtuple_as_object and getattr(o, '_asdict', None)
+                if _asdict and callable(_asdict):
+                    for chunk in _iterencode_dict(_asdict(),
+                            _current_indent_level):
+                        yield chunk
+                elif (_tuple_as_array and isinstance(o, tuple)):
+                    for chunk in _iterencode_list(o, _current_indent_level):
+                        yield chunk
+                elif isinstance(o, dict):
+                    for chunk in _iterencode_dict(o, _current_indent_level):
+                        yield chunk
+                elif _use_decimal and isinstance(o, Decimal):
+                    yield str(o)
+                else:
+                    if markers is not None:
+                        markerid = id(o)
+                        if markerid in markers:
+                            raise ValueError("Circular reference detected")
+                        markers[markerid] = o
+                    o = _default(o)
+                    for chunk in _iterencode(o, _current_indent_level):
+                        yield chunk
+                    if markers is not None:
+                        del markers[markerid]
 
     return _iterencode
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/tests/__init__.py 
new/simplejson-3.3.0/simplejson/tests/__init__.py
--- old/simplejson-3.1.3/simplejson/tests/__init__.py   2013-02-22 
00:37:09.000000000 +0100
+++ new/simplejson-3.3.0/simplejson/tests/__init__.py   2013-05-01 
20:48:26.000000000 +0200
@@ -60,6 +60,7 @@
         'simplejson.tests.test_tuple',
         'simplejson.tests.test_namedtuple',
         'simplejson.tests.test_tool',
+        'simplejson.tests.test_for_json',
     ])
     suite = additional_tests(suite)
     return OptionalExtensionTestSuite([suite])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/tests/test_float.py 
new/simplejson-3.3.0/simplejson/tests/test_float.py
--- old/simplejson-3.1.3/simplejson/tests/test_float.py 2013-01-03 
20:20:21.000000000 +0100
+++ new/simplejson-3.3.0/simplejson/tests/test_float.py 2013-05-01 
22:01:12.000000000 +0200
@@ -5,13 +5,21 @@
 from simplejson.decoder import NaN, PosInf, NegInf
 
 class TestFloat(TestCase):
-    def test_degenerates(self):
+    def test_degenerates_allow(self):
         for inf in (PosInf, NegInf):
             self.assertEqual(json.loads(json.dumps(inf)), inf)
         # Python 2.5 doesn't have math.isnan
         nan = json.loads(json.dumps(NaN))
         self.assertTrue((0 + nan) != nan)
 
+    def test_degenerates_ignore(self):
+        for f in (PosInf, NegInf, NaN):
+            self.assertEqual(json.loads(json.dumps(f, ignore_nan=True)), None)
+
+    def test_degenerates_deny(self):
+        for f in (PosInf, NegInf, NaN):
+            self.assertRaises(ValueError, json.dumps, f, allow_nan=False)
+
     def test_floats(self):
         for num in [1617161771.7650001, math.pi, math.pi**100,
                     math.pi**-100, 3.1]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/tests/test_for_json.py 
new/simplejson-3.3.0/simplejson/tests/test_for_json.py
--- old/simplejson-3.1.3/simplejson/tests/test_for_json.py      1970-01-01 
01:00:00.000000000 +0100
+++ new/simplejson-3.3.0/simplejson/tests/test_for_json.py      2013-05-01 
20:48:26.000000000 +0200
@@ -0,0 +1,97 @@
+import unittest
+import simplejson as json
+
+
+class ForJson(object):
+    def for_json(self):
+        return {'for_json': 1}
+
+
+class NestedForJson(object):
+    def for_json(self):
+        return {'nested': ForJson()}
+
+
+class ForJsonList(object):
+    def for_json(self):
+        return ['list']
+
+
+class DictForJson(dict):
+    def for_json(self):
+        return {'alpha': 1}
+
+
+class ListForJson(list):
+    def for_json(self):
+        return ['list']
+
+
+class TestForJson(unittest.TestCase):
+    def assertRoundTrip(self, obj, other, for_json=True):
+        if for_json is None:
+            # None will use the default
+            s = json.dumps(obj)
+        else:
+            s = json.dumps(obj, for_json=for_json)
+        self.assertEqual(
+            json.loads(s),
+            other)
+
+    def test_for_json_encodes_stand_alone_object(self):
+        self.assertRoundTrip(
+            ForJson(),
+            ForJson().for_json())
+
+    def test_for_json_encodes_object_nested_in_dict(self):
+        self.assertRoundTrip(
+            {'hooray': ForJson()},
+            {'hooray': ForJson().for_json()})
+
+    def test_for_json_encodes_object_nested_in_list_within_dict(self):
+        self.assertRoundTrip(
+            {'list': [0, ForJson(), 2, 3]},
+            {'list': [0, ForJson().for_json(), 2, 3]})
+
+    def test_for_json_encodes_object_nested_within_object(self):
+        self.assertRoundTrip(
+            NestedForJson(),
+            {'nested': {'for_json': 1}})
+
+    def test_for_json_encodes_list(self):
+        self.assertRoundTrip(
+            ForJsonList(),
+            ForJsonList().for_json())
+
+    def test_for_json_encodes_list_within_object(self):
+        self.assertRoundTrip(
+            {'nested': ForJsonList()},
+            {'nested': ForJsonList().for_json()})
+
+    def test_for_json_encodes_dict_subclass(self):
+        self.assertRoundTrip(
+            DictForJson(a=1),
+            DictForJson(a=1).for_json())
+
+    def test_for_json_encodes_list_subclass(self):
+        self.assertRoundTrip(
+            ListForJson(['l']),
+            ListForJson(['l']).for_json())
+
+    def test_for_json_ignored_if_not_true_with_dict_subclass(self):
+        for for_json in (None, False):
+            self.assertRoundTrip(
+                DictForJson(a=1),
+                {'a': 1},
+                for_json=for_json)
+
+    def test_for_json_ignored_if_not_true_with_list_subclass(self):
+        for for_json in (None, False):
+            self.assertRoundTrip(
+                ListForJson(['l']),
+                ['l'],
+                for_json=for_json)
+
+    def test_raises_typeerror_if_for_json_not_true_with_object(self):
+        self.assertRaises(TypeError, json.dumps, ForJson())
+        self.assertRaises(TypeError, json.dumps, ForJson(), for_json=False)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/tests/test_scanstring.py 
new/simplejson-3.3.0/simplejson/tests/test_scanstring.py
--- old/simplejson-3.1.3/simplejson/tests/test_scanstring.py    2013-01-03 
20:20:21.000000000 +0100
+++ new/simplejson-3.3.0/simplejson/tests/test_scanstring.py    2013-05-08 
08:04:12.000000000 +0200
@@ -23,10 +23,6 @@
         self._test_scanstring(simplejson.decoder.c_scanstring)
 
     def _test_scanstring(self, scanstring):
-        self.assertEqual(
-            scanstring('"z\\ud834\\udd20x"', 1, None, True),
-            (u'z\U0001d120x', 16))
-
         if sys.maxunicode == 65535:
             self.assertEqual(
                 scanstring(u'"z\U0001d120x"', 1, None, True),
@@ -129,9 +125,10 @@
         self.assertRaises(ValueError, scanstring, '\\u012', 0, None, True)
         self.assertRaises(ValueError, scanstring, '\\u0123', 0, None, True)
         if sys.maxunicode > 65535:
-            self.assertRaises(ValueError, scanstring, '\\ud834"', 0, None, 
True),
-            self.assertRaises(ValueError, scanstring, '\\ud834\\u"', 0, None, 
True),
-            self.assertRaises(ValueError, scanstring, '\\ud834\\x0123"', 0, 
None, True),
+            self.assertRaises(ValueError,
+                              scanstring, '\\ud834\\u"', 0, None, True)
+            self.assertRaises(ValueError,
+                              scanstring, '\\ud834\\x0123"', 0, None, True)
 
     def test_issue3623(self):
         self.assertRaises(ValueError, json.decoder.scanstring, "xxx", 1,
@@ -145,3 +142,53 @@
         assert maxsize is not None
         self.assertRaises(OverflowError, json.decoder.scanstring, "xxx",
                           maxsize + 1)
+
+    def test_surrogates(self):
+        scanstring = json.decoder.scanstring
+
+        def assertScan(given, expect, test_utf8=True):
+            givens = [given]
+            if not PY3 and test_utf8:
+                givens.append(given.encode('utf8'))
+            for given in givens:
+                (res, count) = scanstring(given, 1, None, True)
+                self.assertEqual(len(given), count)
+                self.assertEqual(res, expect)
+
+        assertScan(
+            u'"z\\ud834\\u0079x"',
+            u'z\ud834yx')
+        assertScan(
+            u'"z\\ud834\\udd20x"',
+            u'z\U0001d120x')
+        assertScan(
+            u'"z\\ud834\\ud834\\udd20x"',
+            u'z\ud834\U0001d120x')
+        assertScan(
+            u'"z\\ud834x"',
+            u'z\ud834x')
+        assertScan(
+            u'"z\\udd20x"',
+            u'z\udd20x')
+        assertScan(
+            u'"z\ud834x"',
+            u'z\ud834x')
+        # It may look strange to join strings together, but Python is drunk.
+        # https://gist.github.com/etrepum/5538443
+        assertScan(
+            u'"z\\ud834\udd20x12345"',
+            u''.join([u'z\ud834', u'\udd20x12345']))
+        assertScan(
+            u'"z\ud834\\udd20x"',
+            u''.join([u'z\ud834', u'\udd20x']))
+        # these have different behavior given UTF8 input, because the surrogate
+        # pair may be joined (in maxunicode > 65535 builds)
+        assertScan(
+            u''.join([u'"z\ud834', u'\udd20x"']),
+            u''.join([u'z\ud834', u'\udd20x']),
+            test_utf8=False)
+
+        self.assertRaises(ValueError,
+                          scanstring, u'"z\\ud83x"', 1, None, True)
+        self.assertRaises(ValueError,
+                          scanstring, u'"z\\ud834\\udd2x"', 1, None, True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-3.1.3/simplejson/tests/test_unicode.py 
new/simplejson-3.3.0/simplejson/tests/test_unicode.py
--- old/simplejson-3.1.3/simplejson/tests/test_unicode.py       2013-01-11 
18:04:02.000000000 +0100
+++ new/simplejson-3.3.0/simplejson/tests/test_unicode.py       2013-05-08 
08:04:12.000000000 +0200
@@ -123,26 +123,15 @@
         self.assertRaises(json.JSONDecodeError, json.loads, '"\\u1x34"')
         self.assertRaises(json.JSONDecodeError, json.loads, '"\\ux234"')
         if sys.maxunicode > 65535:
-            # unpaired low surrogate
-            self.assertRaises(json.JSONDecodeError, json.loads, '"\\udc00"')
-            self.assertRaises(json.JSONDecodeError, json.loads, '"\\udcff"')
-            # unpaired high surrogate
-            self.assertRaises(json.JSONDecodeError, json.loads, '"\\ud800"')
-            self.assertRaises(json.JSONDecodeError, json.loads, '"\\ud800x"')
-            self.assertRaises(json.JSONDecodeError, json.loads, '"\\ud800xx"')
-            self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800xxxxxx"')
+            # invalid escape sequence for low surrogate
             self.assertRaises(json.JSONDecodeError, json.loads, '"\\ud800\\u"')
             self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\u0"')
             self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\u00"')
             self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\u000"')
-            # invalid escape sequence for low surrogate
             self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\u000x"')
             self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\u00x0"')
             self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\u0x00"')
             self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\ux000"')
-            # invalid value for low surrogate
-            self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\u0000"')
-            self.assertRaises(json.JSONDecodeError, json.loads, 
'"\\ud800\\ufc00"')
 
     def test_ensure_ascii_still_works(self):
         # in the ascii range, ensure that everything is the same

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to