Hello community,

here is the log from the commit of package python-simplejson for 
openSUSE:Factory checked in at 2012-05-29 11:44:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-simplejson (Old)
 and      /work/SRC/openSUSE:Factory/.python-simplejson.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-simplejson", Maintainer is "[email protected]"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-simplejson/python-simplejson.changes      
2012-03-13 09:39:11.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-simplejson.new/python-simplejson.changes 
2012-05-29 11:44:40.000000000 +0200
@@ -1,0 +2,13 @@
+Fri May 25 12:26:32 UTC 2012 - [email protected]
+
+- Clean up spec file
+- Update to version 2.5.2:
+  * Fix for regression introduced in 2.5.1
+- Update to version 2.5.1:
+  * Support for use_decimal=True in environments that use Python
+    sub-interpreters such as uWSGI
+- Update to version 2.5.1:
+  * New item_sort_key option for encoder to allow fine grained 
+    control of sorted output
+
+-------------------------------------------------------------------

Old:
----
  simplejson-2.4.0.tar.gz

New:
----
  simplejson-2.5.2.tar.gz

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

Other differences:
------------------
++++++ python-simplejson.spec ++++++
--- /var/tmp/diff_new_pack.MSMYXI/_old  2012-05-29 11:44:41.000000000 +0200
+++ /var/tmp/diff_new_pack.MSMYXI/_new  2012-05-29 11:44:41.000000000 +0200
@@ -15,20 +15,22 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
 
-
-Name:           python-simplejson
-Version:        2.4.0
+%define modname simplejson
+Name:           python-%{modname}
+Version:        2.5.2
 Release:        0
 Url:            http://github.com/simplejson/simplejson
 Summary:        Simple, fast, extensible JSON encoder/decoder for Python
 License:        MIT
 Group:          Development/Languages/Python
-Source:         
http://pypi.python.org/packages/source/s/simplejson/simplejson-%{version}.tar.gz
+Source:         
http://pypi.python.org/packages/source/s/%{modname}/%{modname}-%{version}.tar.gz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  python-devel
 BuildRequires:  python-distribute
-%if 0%{?suse_version} && 0%{?suse_version} <= 1110
-%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
+%if 0%{?suse_version} <= 1110
+%{!?python_sitearch: %global python_sitearch %(python -c "from 
distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
+%else
+%py_requires
 %endif
 
 %description
@@ -38,7 +40,7 @@
 serious speed boost.
 
 %prep
-%setup -q -n simplejson-%{version}
+%setup -q -n %{modname}-%{version}
 
 %build
 CFLAGS="%{optflags} -fno-strict-aliasing" python setup.py build
@@ -52,6 +54,7 @@
 %files
 %defattr(-,root,root)
 %doc CHANGES.txt LICENSE.txt README.rst
-%{python_sitearch}/*
+%{python_sitearch}/%{modname}/
+%{python_sitearch}/%{modname}-%{version}-py%{py_ver}.egg-info
 
 %changelog

++++++ simplejson-2.4.0.tar.gz -> simplejson-2.5.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-2.4.0/CHANGES.txt 
new/simplejson-2.5.2/CHANGES.txt
--- old/simplejson-2.4.0/CHANGES.txt    2012-03-07 05:26:32.000000000 +0100
+++ new/simplejson-2.5.2/CHANGES.txt    2012-05-11 00:12:34.000000000 +0200
@@ -1,4 +1,20 @@
-Version 2.4.0 released 2012-03-XX
+Version 2.5.2 released 2012-05-10
+
+* Fix for regression introduced in 2.5.1
+  https://github.com/simplejson/simplejson/issues/35
+
+Version 2.5.1 released 2012-05-10
+
+* Support for use_decimal=True in environments that use Python
+  sub-interpreters such as uWSGI
+  https://github.com/simplejson/simplejson/issues/34
+
+Version 2.5.0 released 2012-03-29
+
+* New item_sort_key option for encoder to allow fine grained control of sorted
+  output
+
+Version 2.4.0 released 2012-03-06
 
 * New bigint_as_string option for encoder to trade JavaScript number precision
   issues for type issues.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-2.4.0/PKG-INFO 
new/simplejson-2.5.2/PKG-INFO
--- old/simplejson-2.4.0/PKG-INFO       2012-03-07 05:26:53.000000000 +0100
+++ new/simplejson-2.5.2/PKG-INFO       2012-05-11 00:12:41.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: simplejson
-Version: 2.4.0
+Version: 2.5.2
 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-2.4.0/conf.py new/simplejson-2.5.2/conf.py
--- old/simplejson-2.4.0/conf.py        2012-03-07 05:26:32.000000000 +0100
+++ new/simplejson-2.5.2/conf.py        2012-05-11 00:12:34.000000000 +0200
@@ -42,9 +42,9 @@
 # other places throughout the built documents.
 #
 # The short X.Y version.
-version = '2.4'
+version = '2.5'
 # The full version, including alpha/beta/rc tags.
-release = '2.4.0'
+release = '2.5.2'
 
 # 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-2.4.0/index.rst 
new/simplejson-2.5.2/index.rst
--- old/simplejson-2.4.0/index.rst      2011-12-05 22:17:44.000000000 +0100
+++ new/simplejson-2.5.2/index.rst      2012-03-29 21:02:31.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[, **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[, **kw]]]]]]]]]]]]]]]])
 
    Serialize *obj* as a JSON formatted stream to *fp* (a 
``.write()``-supporting
    file-like object).
@@ -189,22 +189,42 @@
    .. versionchanged:: 2.2.0
       The default of *use_decimal* changed to ``True`` in 2.2.0.
 
-  If *namedtuple_as_object* is true (default: ``True``),
-  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 *namedtuple_as_object* is true (default: ``True``),
+   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.
+   If *tuple_as_array* is true (default: ``True``),
+   :class:`tuple` (and subclasses) will be encoded as JSON arrays.
 
-  .. versionchanged:: 2.2.0
-    *tuple_as_array* is new in 2.2.0.
+   .. versionchanged:: 2.2.0
+     *tuple_as_array* is new in 2.2.0.
+
+   If *bigint_as_string* is true (default: ``False``), :class:`int`` ``2**53``
+   and higher or lower than ``-2**53`` will be encoded as strings. This is to
+   avoid the rounding that happens in Javascript otherwise. Note that this
+   option loses type information, so use with extreme caution.
+
+   .. versionchanged:: 2.4.0
+     *bigint_as_string* is new in 2.4.0.
+
+   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
+   JSON serializations can be compared on a day-to-day basis.
+
+   If *item_sort_key* is a callable (not the default), then the output of
+   dictionaries will be sorted with it. The callable will be used like this:
+   ``sorted(dct.items(), key=item_sort_key)``. This option takes precedence
+   over *sort_keys*.
+
+   .. versionchanged:: 2.5.0
+      *item_sort_key* is new in 2.5.0.
 
     .. note::
 
@@ -213,7 +233,7 @@
         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[, **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[, **kw]]]]]]]]]]]]]]]])
 
    Serialize *obj* to a JSON formatted :class:`str`.
 
@@ -410,7 +430,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]]]]]]]]]]]])
+.. 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]]]]]]]]]]]]])
 
    Extensible JSON encoder for Python data structures.
 
@@ -465,6 +485,14 @@
    will be sorted by key; this is useful for regression tests to ensure that
    JSON serializations can be compared on a day-to-day basis.
 
+   If *item_sort_key* is a callable (not the default), then the output of
+   dictionaries will be sorted with it. The callable will be used like this:
+   ``sorted(dct.items(), key=item_sort_key)``. This option takes precedence
+   over *sort_keys*.
+
+   .. versionchanged:: 2.5.0
+      *item_sort_key* is new in 2.5.0.
+
    If *indent* is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
@@ -504,6 +532,15 @@
    .. versionchanged:: 2.2.0
      *tuple_as_array* is new in 2.2.0.
 
+   If *bigint_as_string* is true (default: ``False``), :class:`int`` ``2**53``
+   and higher or lower than ``-2**53`` will be encoded as strings. This is to
+   avoid the rounding that happens in Javascript otherwise. Note that this
+   option loses type information, so use with extreme caution.
+
+   .. versionchanged:: 2.4.0
+     *bigint_as_string* is new in 2.4.0.
+
+
    .. method:: default(o)
 
       Implement this method in a subclass such that it returns a serializable
@@ -544,7 +581,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]]]]]]]]])
+.. 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]]]]]]]]]]]]])
 
    Subclass of :class:`JSONEncoder` that escapes &, <, and > for embedding in 
HTML.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-2.4.0/setup.py 
new/simplejson-2.5.2/setup.py
--- old/simplejson-2.4.0/setup.py       2012-03-07 05:26:32.000000000 +0100
+++ new/simplejson-2.5.2/setup.py       2012-05-11 00:12:34.000000000 +0200
@@ -7,7 +7,7 @@
     DistutilsPlatformError
 
 IS_PYPY = hasattr(sys, 'pypy_translation_info')
-VERSION = '2.4.0'
+VERSION = '2.5.2'
 DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python"
 LONG_DESCRIPTION = open('README.rst', 'r').read()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-2.4.0/simplejson/__init__.py 
new/simplejson-2.5.2/simplejson/__init__.py
--- old/simplejson-2.4.0/simplejson/__init__.py 2012-03-07 05:26:32.000000000 
+0100
+++ new/simplejson-2.5.2/simplejson/__init__.py 2012-05-11 00:12:34.000000000 
+0200
@@ -97,11 +97,11 @@
     $ echo '{ 1.2:3.4}' | python -m simplejson.tool
     Expecting property name: line 1 column 2 (char 2)
 """
-__version__ = '2.4.0'
+__version__ = '2.5.2'
 __all__ = [
     'dump', 'dumps', 'load', 'loads',
     'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
-    'OrderedDict',
+    'OrderedDict', 'simple_first',
 ]
 
 __author__ = 'Bob Ippolito <[email protected]>'
@@ -139,13 +139,15 @@
     namedtuple_as_object=True,
     tuple_as_array=True,
     bigint_as_string=False,
+    item_sort_key=None,
 )
 
 def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
         allow_nan=True, cls=None, indent=None, separators=None,
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
-        bigint_as_string=False, **kw):
+        bigint_as_string=False, sort_keys=False, item_sort_key=None,
+        **kw):
     """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
     ``.write()``-supporting file-like object).
 
@@ -200,6 +202,14 @@
     lossy operation that will not round-trip correctly and should be used
     sparingly.
 
+    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. This option takes precedence over
+    *sort_keys*.
+
+    If *sort_keys* is true (default: ``False``), the output of dictionaries
+    will be sorted by item.
+
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
     the ``cls`` kwarg.
@@ -211,7 +221,7 @@
         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 kw):
+        and not bigint_as_string and not item_sort_key and not kw):
         iterable = _default_encoder.iterencode(obj)
     else:
         if cls is None:
@@ -223,6 +233,8 @@
             namedtuple_as_object=namedtuple_as_object,
             tuple_as_array=tuple_as_array,
             bigint_as_string=bigint_as_string,
+            sort_keys=sort_keys,
+            item_sort_key=item_sort_key,
             **kw).iterencode(obj)
     # could accelerate with writelines in some versions of Python, at
     # a debuggability cost
@@ -233,8 +245,8 @@
 def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
         allow_nan=True, cls=None, indent=None, separators=None,
         encoding='utf-8', default=None, use_decimal=True,
-        namedtuple_as_object=True,
-        tuple_as_array=True, bigint_as_string=False,
+        namedtuple_as_object=True, tuple_as_array=True,
+        bigint_as_string=False, sort_keys=False, item_sort_key=None,
         **kw):
     """Serialize ``obj`` to a JSON formatted ``str``.
 
@@ -281,10 +293,18 @@
     If *tuple_as_array* is true (default: ``True``),
     :class:`tuple` (and subclasses) will be encoded as JSON arrays.
 
-    If bigint_as_string is true (not the default), ints 2**53 and higher
+    If *bigint_as_string* is true (not the default), ints 2**53 and higher
     or lower than -2**53 will be encoded as strings. This is to avoid the
     rounding that happens in Javascript otherwise.
 
+    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. This option takes precendence over
+    *sort_keys*.
+
+    If *sort_keys* is true (default: ``False``), the output of dictionaries
+    will be sorted by item.
+
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
     the ``cls`` kwarg.
@@ -296,7 +316,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 kw):
+        and not bigint_as_string and not sort_keys
+        and not item_sort_key and not kw):
         return _default_encoder.encode(obj)
     if cls is None:
         cls = JSONEncoder
@@ -308,6 +329,8 @@
         namedtuple_as_object=namedtuple_as_object,
         tuple_as_array=tuple_as_array,
         bigint_as_string=bigint_as_string,
+        sort_keys=sort_keys,
+        item_sort_key=item_sort_key,
         **kw).encode(obj)
 
 
@@ -479,3 +502,9 @@
        encoding='utf-8',
        default=None,
    )
+
+def simple_first(kv):
+    """Helper function to pass to item_sort_key to sort simple
+    elements to the top, then container elements.
+    """
+    return (isinstance(kv[1], (list, dict, tuple)), kv[0])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-2.4.0/simplejson/_speedups.c 
new/simplejson-2.5.2/simplejson/_speedups.c
--- old/simplejson-2.4.0/simplejson/_speedups.c 2012-03-07 05:26:32.000000000 
+0100
+++ new/simplejson-2.5.2/simplejson/_speedups.c 2012-05-11 00:12:34.000000000 
+0200
@@ -44,11 +44,9 @@
 #define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType)
 #define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType)
 #define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType)
-#define Decimal_Check(op) (PyObject_TypeCheck(op, DecimalTypePtr))
 
 static PyTypeObject PyScannerType;
 static PyTypeObject PyEncoderType;
-static PyTypeObject *DecimalTypePtr;
 
 typedef struct _PyScannerObject {
     PyObject_HEAD
@@ -84,12 +82,14 @@
     PyObject *sort_keys;
     PyObject *skipkeys;
     PyObject *key_memo;
+    PyObject *Decimal;
     int fast_encode;
     int allow_nan;
     int use_decimal;
     int namedtuple_as_object;
     int tuple_as_array;
     int bigint_as_string;
+    PyObject *item_sort_key;
 } PyEncoderObject;
 
 static PyMemberDef encoder_members[] = {
@@ -102,6 +102,7 @@
     {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, 
"sort_keys"},
     {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys), READONLY, 
"skipkeys"},
     {"key_memo", T_OBJECT, offsetof(PyEncoderObject, key_memo), READONLY, 
"key_memo"},
+    {"item_sort_key", T_OBJECT, offsetof(PyEncoderObject, item_sort_key), 
READONLY, "item_sort_key"},
     {NULL}
 };
 
@@ -2050,6 +2051,8 @@
         s->sort_keys = NULL;
         s->skipkeys = NULL;
         s->key_memo = NULL;
+        s->item_sort_key = NULL;
+        s->Decimal = NULL;
     }
     return (PyObject *)s;
 }
@@ -2058,19 +2061,22 @@
 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", 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", "Decimal", NULL};
 
     PyEncoderObject *s;
     PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
-    PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan, *key_memo, 
*use_decimal, *namedtuple_as_object, *tuple_as_array, *bigint_as_string;
+    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, *Decimal;
 
     assert(PyEncoder_Check(self));
     s = (PyEncoderObject *)self;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"OOOOOOOOOOOOOO:make_encoder", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"OOOOOOOOOOOOOOOO: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))
+        &namedtuple_as_object, &tuple_as_array, &bigint_as_string,
+        &item_sort_key, &Decimal))
         return -1;
 
     s->markers = markers;
@@ -2088,6 +2094,8 @@
     s->namedtuple_as_object = PyObject_IsTrue(namedtuple_as_object);
     s->tuple_as_array = PyObject_IsTrue(tuple_as_array);
     s->bigint_as_string = PyObject_IsTrue(bigint_as_string);
+    s->item_sort_key = item_sort_key;
+    s->Decimal = Decimal;
 
     Py_INCREF(s->markers);
     Py_INCREF(s->defaultfn);
@@ -2098,6 +2106,8 @@
     Py_INCREF(s->sort_keys);
     Py_INCREF(s->skipkeys);
     Py_INCREF(s->key_memo);
+    Py_INCREF(s->item_sort_key);
+    Py_INCREF(s->Decimal);
     return 0;
 }
 
@@ -2250,7 +2260,7 @@
         else if (PyDict_Check(obj)) {
             rv = encoder_listencode_dict(s, rval, obj, indent_level);
         }
-        else if (s->use_decimal && Decimal_Check(obj)) {
+        else if (s->use_decimal && PyObject_TypeCheck(obj, s->Decimal)) {
             PyObject *encoded = PyObject_Str(obj);
             if (encoded != NULL)
                 rv = _steal_list_append(rval, encoded);
@@ -2356,7 +2366,14 @@
         */
     }
 
-    if (PyObject_IsTrue(s->sort_keys)) {
+    if (PyCallable_Check(s->item_sort_key)) {
+        if (PyDict_CheckExact(dct))
+            items = PyDict_Items(dct);
+        else
+            items = PyMapping_Items(dct);
+        PyObject_CallMethod(items, "sort", "OO", Py_None, s->item_sort_key);
+    }
+    else if (PyObject_IsTrue(s->sort_keys)) {
         /* First sort the keys then replace them with (key, value) tuples. */
         Py_ssize_t i, nitems;
         if (PyDict_CheckExact(dct))
@@ -2616,6 +2633,7 @@
     Py_VISIT(s->sort_keys);
     Py_VISIT(s->skipkeys);
     Py_VISIT(s->key_memo);
+    Py_VISIT(s->item_sort_key);
     return 0;
 }
 
@@ -2635,6 +2653,8 @@
     Py_CLEAR(s->sort_keys);
     Py_CLEAR(s->skipkeys);
     Py_CLEAR(s->key_memo);
+    Py_CLEAR(s->item_sort_key);
+    Py_CLEAR(s->Decimal);
     return 0;
 }
 
@@ -2702,7 +2722,7 @@
 void
 init_speedups(void)
 {
-    PyObject *m, *decimal;
+    PyObject *m;
     PyScannerType.tp_new = PyType_GenericNew;
     if (PyType_Ready(&PyScannerType) < 0)
         return;
@@ -2710,13 +2730,6 @@
     if (PyType_Ready(&PyEncoderType) < 0)
         return;
 
-    decimal = PyImport_ImportModule("decimal");
-    if (decimal == NULL)
-        return;
-    DecimalTypePtr = (PyTypeObject*)PyObject_GetAttrString(decimal, "Decimal");
-    Py_DECREF(decimal);
-    if (DecimalTypePtr == NULL)
-        return;
 
     m = Py_InitModule3("_speedups", speedups_methods, module_doc);
     Py_INCREF((PyObject*)&PyScannerType);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-2.4.0/simplejson/encoder.py 
new/simplejson-2.5.2/simplejson/encoder.py
--- old/simplejson-2.4.0/simplejson/encoder.py  2012-03-07 05:26:32.000000000 
+0100
+++ new/simplejson-2.5.2/simplejson/encoder.py  2012-05-10 22:06:15.000000000 
+0200
@@ -107,7 +107,8 @@
             check_circular=True, allow_nan=True, sort_keys=False,
             indent=None, separators=None, encoding='utf-8', default=None,
             use_decimal=True, namedtuple_as_object=True,
-            tuple_as_array=True, bigint_as_string=False):
+            tuple_as_array=True, bigint_as_string=False,
+            item_sort_key=None):
         """Constructor for JSONEncoder, with sensible defaults.
 
         If skipkeys is false, then it is a TypeError to attempt
@@ -164,6 +165,10 @@
         If bigint_as_string is true (not the default), ints 2**53 and higher
         or lower than -2**53 will be encoded as strings. This is to avoid the
         rounding that happens in Javascript otherwise.
+
+        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.
         """
 
         self.skipkeys = skipkeys
@@ -175,6 +180,7 @@
         self.namedtuple_as_object = namedtuple_as_object
         self.tuple_as_array = tuple_as_array
         self.bigint_as_string = bigint_as_string
+        self.item_sort_key = item_sort_key
         if indent is not None and not isinstance(indent, basestring):
             indent = indent * ' '
         self.indent = indent
@@ -291,14 +297,16 @@
                 self.key_separator, self.item_separator, self.sort_keys,
                 self.skipkeys, self.allow_nan, key_memo, self.use_decimal,
                 self.namedtuple_as_object, self.tuple_as_array,
-                self.bigint_as_string)
+                self.bigint_as_string, self.item_sort_key,
+                Decimal)
         else:
             _iterencode = _make_iterencode(
                 markers, self.default, _encoder, self.indent, floatstr,
                 self.key_separator, self.item_separator, self.sort_keys,
                 self.skipkeys, _one_shot, self.use_decimal,
                 self.namedtuple_as_object, self.tuple_as_array,
-                self.bigint_as_string)
+                self.bigint_as_string, self.item_sort_key,
+                Decimal=Decimal)
         try:
             return _iterencode(o, 0)
         finally:
@@ -335,7 +343,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,
+        _bigint_as_string, _item_sort_key,
         ## HACK: hand-optimized bytecode; turn globals into locals
         False=False,
         True=True,
@@ -352,6 +360,8 @@
         str=str,
         tuple=tuple,
     ):
+    if _item_sort_key and not callable(_item_sort_key):
+        raise TypeError("item_sort_key must be None or callable")
 
     def _iterencode_list(lst, _current_indent_level):
         if not lst:
@@ -437,7 +447,10 @@
             newline_indent = None
             item_separator = _item_separator
         first = True
-        if _sort_keys:
+        if _item_sort_key:
+            items = dct.items()
+            items.sort(key=_item_sort_key)
+        elif _sort_keys:
             items = dct.items()
             items.sort(key=lambda kv: kv[0])
         else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simplejson-2.4.0/simplejson/tests/test_decimal.py 
new/simplejson-2.5.2/simplejson/tests/test_decimal.py
--- old/simplejson-2.4.0/simplejson/tests/test_decimal.py       2011-09-29 
21:25:07.000000000 +0200
+++ new/simplejson-2.5.2/simplejson/tests/test_decimal.py       2012-05-10 
22:06:15.000000000 +0200
@@ -1,3 +1,4 @@
+import decimal
 from decimal import Decimal
 from unittest import TestCase
 from StringIO import StringIO
@@ -22,11 +23,11 @@
     def test_decimal_encode(self):
         for d in map(Decimal, self.NUMS):
             self.assertEquals(self.dumps(d, use_decimal=True), str(d))
-    
+
     def test_decimal_decode(self):
         for s in self.NUMS:
             self.assertEquals(self.loads(s, parse_float=Decimal), Decimal(s))
-    
+
     def test_decimal_roundtrip(self):
         for d in map(Decimal, self.NUMS):
             # The type might not be the same (int and Decimal) but they
@@ -46,10 +47,20 @@
         self.assertRaises(TypeError, json.dumps, d, use_decimal=False)
         self.assertEqual('1.1', json.dumps(d))
         self.assertEqual('1.1', json.dumps(d, use_decimal=True))
-        self.assertRaises(TypeError, json.dump, d, StringIO(), 
use_decimal=False)
+        self.assertRaises(TypeError, json.dump, d, StringIO(),
+                          use_decimal=False)
         sio = StringIO()
         json.dump(d, sio)
         self.assertEqual('1.1', sio.getvalue())
         sio = StringIO()
         json.dump(d, sio, use_decimal=True)
         self.assertEqual('1.1', sio.getvalue())
+
+    def test_decimal_reload(self):
+        # Simulate a subinterpreter that reloads the Python modules but not
+        # the C code https://github.com/simplejson/simplejson/issues/34
+        global Decimal
+        Decimal = reload(decimal).Decimal
+        import simplejson.encoder
+        simplejson.encoder.Decimal = Decimal
+        self.test_decimal_roundtrip()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/simplejson-2.4.0/simplejson/tests/test_item_sort_key.py 
new/simplejson-2.5.2/simplejson/tests/test_item_sort_key.py
--- old/simplejson-2.4.0/simplejson/tests/test_item_sort_key.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/simplejson-2.5.2/simplejson/tests/test_item_sort_key.py 2012-03-29 
21:02:31.000000000 +0200
@@ -0,0 +1,20 @@
+from unittest import TestCase
+
+import simplejson as json
+from operator import itemgetter
+
+class TestItemSortKey(TestCase):
+    def test_simple_first(self):
+        a = {'a': 1, 'c': 5, 'jack': 'jill', 'pick': 'axe', 'array': [1, 5, 6, 
9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
+        self.assertEquals(
+            '{"a": 1, "c": 5, "crate": "dog", "jack": "jill", "pick": "axe", 
"zeak": "oh", "array": [1, 5, 6, 9], "tuple": [83, 12, 3]}',
+            json.dumps(a, item_sort_key=json.simple_first))
+
+    def test_case(self):
+        a = {'a': 1, 'c': 5, 'Jack': 'jill', 'pick': 'axe', 'Array': [1, 5, 6, 
9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
+        self.assertEquals(
+            '{"Array": [1, 5, 6, 9], "Jack": "jill", "a": 1, "c": 5, "crate": 
"dog", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
+            json.dumps(a, item_sort_key=itemgetter(0)))
+        self.assertEquals(
+            '{"a": 1, "Array": [1, 5, 6, 9], "c": 5, "crate": "dog", "Jack": 
"jill", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
+            json.dumps(a, item_sort_key=lambda kv: kv[0].lower()))

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to