- Update to 1.2.2
* Fix encoding of UTF-16 surrogate pairs
* Made MANIFEST.in more explicit
* Refactored setup.py to be PEP-8 compliant
* Pass command line arguments from build_inplace to setup.py
* Cleanup after build_inplace
* Explicitly use python2 in shebang lines
* Updated license
- Rebase py3.patch
OBS-URL: https://build.opensuse.org/request/show/824518
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-python-cjson?expand=0&rev=7
646 lines
20 KiB
Diff
646 lines
20 KiB
Diff
From f9060f9981dfc6bc7aed6ced93f10477b0a77d60 Mon Sep 17 00:00:00 2001
|
|
From: Felipe Machado <felipou@gmail.com>
|
|
Date: Wed, 9 Aug 2017 15:48:27 -0300
|
|
Subject: [PATCH] Python 3 support - initial attempt
|
|
|
|
---
|
|
cjson.c | 268 ++++++++++++++++++++++++++--------------------------
|
|
jsontest.py | 16 ++--
|
|
2 files changed, 144 insertions(+), 140 deletions(-)
|
|
|
|
Index: python-cjson-1.2.2/cjson.c
|
|
===================================================================
|
|
--- python-cjson-1.2.2.orig/cjson.c
|
|
+++ python-cjson-1.2.2/cjson.c
|
|
@@ -8,6 +8,16 @@
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
+#define IS_PY3K
|
|
+#endif
|
|
+
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
+#define STRING_TYPE PyUnicodeObject
|
|
+#else
|
|
+#define STRING_TYPE PyStringObject
|
|
+#endif
|
|
+
|
|
typedef struct JSONData {
|
|
char *str; // the actual json string
|
|
char *end; // pointer to the string end
|
|
@@ -16,7 +26,6 @@ typedef struct JSONData {
|
|
} JSONData;
|
|
|
|
static PyObject* encode_object(PyObject *object);
|
|
-static PyObject* encode_string(PyObject *object);
|
|
static PyObject* encode_unicode(PyObject *object);
|
|
static PyObject* encode_tuple(PyObject *object);
|
|
static PyObject* encode_list(PyObject *object);
|
|
@@ -68,6 +77,17 @@ typedef int Py_ssize_t;
|
|
#define skipSpaces(d) while(isspace(*((d)->ptr))) (d)->ptr++
|
|
|
|
|
|
+static inline void
|
|
+PyUnicode_ConcatAndDel(PyObject **left, PyObject *right)
|
|
+{
|
|
+ PyObject *newobj;
|
|
+ newobj = PyUnicode_Concat(*left, right);
|
|
+ Py_DECREF(*left);
|
|
+ Py_DECREF(right);
|
|
+ *left = newobj;
|
|
+}
|
|
+
|
|
+
|
|
/* ------------------------------ Decoding ----------------------------- */
|
|
|
|
static PyObject*
|
|
@@ -161,12 +181,7 @@ decode_string(JSONData *jsondata)
|
|
|
|
len = ptr - jsondata->ptr - 1;
|
|
|
|
- if (has_unicode || jsondata->all_unicode)
|
|
- object = PyUnicode_DecodeUnicodeEscape(jsondata->ptr+1, len, NULL);
|
|
- else if (string_escape)
|
|
- object = PyString_DecodeEscape(jsondata->ptr+1, len, NULL, 0, NULL);
|
|
- else
|
|
- object = PyString_FromStringAndSize(jsondata->ptr+1, len);
|
|
+ object = PyUnicode_DecodeUnicodeEscape(jsondata->ptr+1, len, NULL);
|
|
|
|
if (object == NULL) {
|
|
PyObject *type, *value, *tb, *reason;
|
|
@@ -182,7 +197,7 @@ decode_string(JSONData *jsondata)
|
|
PyErr_Format(JSON_DecodeError, "cannot decode string starting"
|
|
" at position " SSIZE_T_F ": %s",
|
|
(Py_ssize_t)(jsondata->ptr - jsondata->str),
|
|
- reason ? PyString_AsString(reason) : "bad format");
|
|
+ reason ? PyUnicode_AsUTF8(reason) : "bad format");
|
|
Py_XDECREF(reason);
|
|
} else {
|
|
PyErr_Format(JSON_DecodeError,
|
|
@@ -292,14 +307,14 @@ decode_number(JSONData *jsondata)
|
|
skipDigits(ptr);
|
|
}
|
|
|
|
- str = PyString_FromStringAndSize(jsondata->ptr, ptr - jsondata->ptr);
|
|
+ str = PyUnicode_FromStringAndSize(jsondata->ptr, ptr - jsondata->ptr);
|
|
if (str == NULL)
|
|
return NULL;
|
|
|
|
if (is_float)
|
|
- object = PyFloat_FromString(str, NULL);
|
|
+ object = PyFloat_FromString(str);
|
|
else
|
|
- object = PyInt_FromString(PyString_AS_STRING(str), NULL, 10);
|
|
+ object = PyLong_FromUnicodeObject(str, 10);
|
|
|
|
Py_DECREF(str);
|
|
|
|
@@ -580,75 +595,6 @@ decode_json(JSONData *jsondata)
|
|
/* ------------------------------ Encoding ----------------------------- */
|
|
|
|
/*
|
|
- * This function is an almost verbatim copy of PyString_Repr() from
|
|
- * Python's stringobject.c with the following differences:
|
|
- *
|
|
- * - it always quotes the output using double quotes.
|
|
- * - it also quotes \b and \f
|
|
- * - it replaces any non ASCII character hh with \u00hh instead of \xhh
|
|
- */
|
|
-static PyObject*
|
|
-encode_string(PyObject *string)
|
|
-{
|
|
- register PyStringObject* op = (PyStringObject*) string;
|
|
- size_t newsize = 2 + 6 * op->ob_size;
|
|
- PyObject *v;
|
|
-
|
|
- if (op->ob_size > (PY_SSIZE_T_MAX-2)/6) {
|
|
- PyErr_SetString(PyExc_OverflowError,
|
|
- "string is too large to make repr");
|
|
- return NULL;
|
|
- }
|
|
- v = PyString_FromStringAndSize((char *)NULL, newsize);
|
|
- if (v == NULL) {
|
|
- return NULL;
|
|
- }
|
|
- else {
|
|
- register Py_ssize_t i;
|
|
- register char c;
|
|
- register char *p;
|
|
- int quote;
|
|
-
|
|
- quote = '"';
|
|
-
|
|
- p = PyString_AS_STRING(v);
|
|
- *p++ = quote;
|
|
- for (i = 0; i < op->ob_size; i++) {
|
|
- /* There's at least enough room for a hex escape
|
|
- and a closing quote. */
|
|
- assert(newsize - (p - PyString_AS_STRING(v)) >= 7);
|
|
- c = op->ob_sval[i];
|
|
- if (c == quote || c == '\\')
|
|
- *p++ = '\\', *p++ = c;
|
|
- else if (c == '\t')
|
|
- *p++ = '\\', *p++ = 't';
|
|
- else if (c == '\n')
|
|
- *p++ = '\\', *p++ = 'n';
|
|
- else if (c == '\r')
|
|
- *p++ = '\\', *p++ = 'r';
|
|
- else if (c == '\f')
|
|
- *p++ = '\\', *p++ = 'f';
|
|
- else if (c == '\b')
|
|
- *p++ = '\\', *p++ = 'b';
|
|
- else if (c < ' ' || c >= 0x7f) {
|
|
- /* For performance, we don't want to call
|
|
- * PyOS_snprintf here (extra layers of
|
|
- * function call). */
|
|
- sprintf(p, "\\u%04x", c & 0xff);
|
|
- p += 6;
|
|
- }
|
|
- else
|
|
- *p++ = c;
|
|
- }
|
|
- assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
|
|
- *p++ = quote;
|
|
- *p = '\0';
|
|
- _PyString_Resize(&v, (int) (p - PyString_AS_STRING(v)));
|
|
- return v;
|
|
- }
|
|
-}
|
|
-
|
|
-/*
|
|
* This function is an almost verbatim copy of unicodeescape_string() from
|
|
* Python's unicodeobject.c with the following differences:
|
|
*
|
|
@@ -662,7 +608,7 @@ encode_unicode(PyObject *unicode)
|
|
PyObject *repr;
|
|
Py_UNICODE *s;
|
|
Py_ssize_t size;
|
|
- char *p;
|
|
+ Py_UNICODE *p;
|
|
|
|
static const char *hexdigit = "0123456789abcdef";
|
|
#ifdef Py_UNICODE_WIDE
|
|
@@ -694,11 +640,11 @@ encode_unicode(PyObject *unicode)
|
|
return NULL;
|
|
}
|
|
|
|
- repr = PyString_FromStringAndSize(NULL, 2 + expandsize*size + 1);
|
|
+ repr = PyUnicode_FromStringAndSize(NULL, 2 + expandsize*size + 1);
|
|
if (repr == NULL)
|
|
return NULL;
|
|
|
|
- p = PyString_AS_STRING(repr);
|
|
+ p = PyUnicode_AS_UNICODE(repr);
|
|
|
|
*p++ = '"';
|
|
|
|
@@ -706,7 +652,7 @@ encode_unicode(PyObject *unicode)
|
|
Py_UNICODE ch = *s++;
|
|
|
|
/* Escape quotes */
|
|
- if ((ch == (Py_UNICODE) PyString_AS_STRING(repr)[0] || ch == '\\')) {
|
|
+ if ((ch == (Py_UNICODE) PyUnicode_AS_UNICODE(repr)[0] || ch == '\\')) {
|
|
*p++ = '\\';
|
|
*p++ = (char) ch;
|
|
continue;
|
|
@@ -782,10 +728,11 @@ encode_unicode(PyObject *unicode)
|
|
*p++ = (char) ch;
|
|
}
|
|
|
|
- *p++ = PyString_AS_STRING(repr)[0];
|
|
+ *p++ = PyUnicode_AS_UNICODE(repr)[0];
|
|
|
|
*p = '\0';
|
|
- _PyString_Resize(&repr, p - PyString_AS_STRING(repr));
|
|
+ PyUnicode_Resize(&repr, p - PyUnicode_AS_UNICODE(repr));
|
|
+
|
|
return repr;
|
|
}
|
|
|
|
@@ -806,9 +753,9 @@ encode_tuple(PyObject *tuple)
|
|
PyObject *pieces, *result = NULL;
|
|
PyTupleObject *v = (PyTupleObject*) tuple;
|
|
|
|
- n = v->ob_size;
|
|
+ n = v->ob_base.ob_size;
|
|
if (n == 0)
|
|
- return PyString_FromString("[]");
|
|
+ return PyUnicode_FromString("[]");
|
|
|
|
pieces = PyTuple_New(n);
|
|
if (pieces == NULL)
|
|
@@ -824,29 +771,29 @@ encode_tuple(PyObject *tuple)
|
|
|
|
/* Add "[]" decorations to the first and last items. */
|
|
assert(n > 0);
|
|
- s = PyString_FromString("[");
|
|
+ s = PyUnicode_FromString("[");
|
|
if (s == NULL)
|
|
goto Done;
|
|
temp = PyTuple_GET_ITEM(pieces, 0);
|
|
- PyString_ConcatAndDel(&s, temp);
|
|
+ PyUnicode_ConcatAndDel(&s, temp);
|
|
PyTuple_SET_ITEM(pieces, 0, s);
|
|
if (s == NULL)
|
|
goto Done;
|
|
|
|
- s = PyString_FromString("]");
|
|
+ s = PyUnicode_FromString("]");
|
|
if (s == NULL)
|
|
goto Done;
|
|
temp = PyTuple_GET_ITEM(pieces, n-1);
|
|
- PyString_ConcatAndDel(&temp, s);
|
|
+ PyUnicode_ConcatAndDel(&temp, s);
|
|
PyTuple_SET_ITEM(pieces, n-1, temp);
|
|
if (temp == NULL)
|
|
goto Done;
|
|
|
|
/* Paste them all together with ", " between. */
|
|
- s = PyString_FromString(", ");
|
|
+ s = PyUnicode_FromString(", ");
|
|
if (s == NULL)
|
|
goto Done;
|
|
- result = _PyString_Join(s, pieces);
|
|
+ result = PyUnicode_Join(s, pieces);
|
|
Py_DECREF(s);
|
|
|
|
Done:
|
|
@@ -880,8 +827,8 @@ encode_list(PyObject *list)
|
|
return NULL;
|
|
}
|
|
|
|
- if (v->ob_size == 0) {
|
|
- result = PyString_FromString("[]");
|
|
+ if (v->ob_base.ob_size == 0) {
|
|
+ result = PyUnicode_FromString("[]");
|
|
goto Done;
|
|
}
|
|
|
|
@@ -891,7 +838,7 @@ encode_list(PyObject *list)
|
|
|
|
/* Do repr() on each element. Note that this may mutate the list,
|
|
* so must refetch the list size on each iteration. */
|
|
- for (i = 0; i < v->ob_size; ++i) {
|
|
+ for (i = 0; i < v->ob_base.ob_size; ++i) {
|
|
int status;
|
|
s = encode_object(v->ob_item[i]);
|
|
if (s == NULL)
|
|
@@ -904,29 +851,29 @@ encode_list(PyObject *list)
|
|
|
|
/* Add "[]" decorations to the first and last items. */
|
|
assert(PyList_GET_SIZE(pieces) > 0);
|
|
- s = PyString_FromString("[");
|
|
+ s = PyUnicode_FromString("[");
|
|
if (s == NULL)
|
|
goto Done;
|
|
temp = PyList_GET_ITEM(pieces, 0);
|
|
- PyString_ConcatAndDel(&s, temp);
|
|
+ PyUnicode_ConcatAndDel(&s, temp);
|
|
PyList_SET_ITEM(pieces, 0, s);
|
|
if (s == NULL)
|
|
goto Done;
|
|
|
|
- s = PyString_FromString("]");
|
|
+ s = PyUnicode_FromString("]");
|
|
if (s == NULL)
|
|
goto Done;
|
|
temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
|
|
- PyString_ConcatAndDel(&temp, s);
|
|
+ PyUnicode_ConcatAndDel(&temp, s);
|
|
PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
|
|
if (temp == NULL)
|
|
goto Done;
|
|
|
|
/* Paste them all together with ", " between. */
|
|
- s = PyString_FromString(", ");
|
|
+ s = PyUnicode_FromString(", ");
|
|
if (s == NULL)
|
|
goto Done;
|
|
- result = _PyString_Join(s, pieces);
|
|
+ result = PyUnicode_Join(s, pieces);
|
|
Py_DECREF(s);
|
|
|
|
Done:
|
|
@@ -965,7 +912,7 @@ encode_dict(PyObject *dict)
|
|
}
|
|
|
|
if (mp->ma_used == 0) {
|
|
- result = PyString_FromString("{}");
|
|
+ result = PyUnicode_FromString("{}");
|
|
goto Done;
|
|
}
|
|
|
|
@@ -973,7 +920,7 @@ encode_dict(PyObject *dict)
|
|
if (pieces == NULL)
|
|
goto Done;
|
|
|
|
- colon = PyString_FromString(": ");
|
|
+ colon = PyUnicode_FromString(": ");
|
|
if (colon == NULL)
|
|
goto Done;
|
|
|
|
@@ -983,7 +930,7 @@ encode_dict(PyObject *dict)
|
|
while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
|
|
int status;
|
|
|
|
- if (!PyString_Check(key) && !PyUnicode_Check(key)) {
|
|
+ if (!PyUnicode_Check(key)) {
|
|
PyErr_SetString(JSON_EncodeError, "JSON encodable dictionaries "
|
|
"must have string/unicode keys");
|
|
goto Done;
|
|
@@ -991,9 +938,10 @@ encode_dict(PyObject *dict)
|
|
|
|
/* Prevent repr from deleting value during key format. */
|
|
Py_INCREF(value);
|
|
- s = encode_object(key);
|
|
- PyString_Concat(&s, colon);
|
|
- PyString_ConcatAndDel(&s, encode_object(value));
|
|
+ temp = encode_object(key);
|
|
+ s = PyUnicode_Concat(temp, colon);
|
|
+ Py_DECREF(temp);
|
|
+ PyUnicode_ConcatAndDel(&s, encode_object(value));
|
|
Py_DECREF(value);
|
|
if (s == NULL)
|
|
goto Done;
|
|
@@ -1005,35 +953,36 @@ encode_dict(PyObject *dict)
|
|
|
|
/* Add "{}" decorations to the first and last items. */
|
|
assert(PyList_GET_SIZE(pieces) > 0);
|
|
- s = PyString_FromString("{");
|
|
+ s = PyUnicode_FromString("{");
|
|
if (s == NULL)
|
|
goto Done;
|
|
temp = PyList_GET_ITEM(pieces, 0);
|
|
- PyString_ConcatAndDel(&s, temp);
|
|
+ PyUnicode_ConcatAndDel(&s, temp);
|
|
PyList_SET_ITEM(pieces, 0, s);
|
|
if (s == NULL)
|
|
goto Done;
|
|
|
|
- s = PyString_FromString("}");
|
|
+ s = PyUnicode_FromString("}");
|
|
if (s == NULL)
|
|
goto Done;
|
|
temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
|
|
- PyString_ConcatAndDel(&temp, s);
|
|
+ PyUnicode_ConcatAndDel(&temp, s);
|
|
PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
|
|
if (temp == NULL)
|
|
goto Done;
|
|
|
|
/* Paste them all together with ", " between. */
|
|
- s = PyString_FromString(", ");
|
|
+ s = PyUnicode_FromString(", ");
|
|
if (s == NULL)
|
|
goto Done;
|
|
- result = _PyString_Join(s, pieces);
|
|
+ result = PyUnicode_Join(s, pieces);
|
|
Py_DECREF(s);
|
|
|
|
Done:
|
|
Py_XDECREF(pieces);
|
|
Py_XDECREF(colon);
|
|
Py_ReprLeave((PyObject *)mp);
|
|
+
|
|
return result;
|
|
}
|
|
|
|
@@ -1042,29 +991,27 @@ static PyObject*
|
|
encode_object(PyObject *object)
|
|
{
|
|
if (object == Py_True) {
|
|
- return PyString_FromString("true");
|
|
+ return PyUnicode_FromString("true");
|
|
} else if (object == Py_False) {
|
|
- return PyString_FromString("false");
|
|
+ return PyUnicode_FromString("false");
|
|
} else if (object == Py_None) {
|
|
- return PyString_FromString("null");
|
|
- } else if (PyString_Check(object)) {
|
|
- return encode_string(object);
|
|
+ return PyUnicode_FromString("null");
|
|
} else if (PyUnicode_Check(object)) {
|
|
return encode_unicode(object);
|
|
} else if (PyFloat_Check(object)) {
|
|
double val = PyFloat_AS_DOUBLE(object);
|
|
if (Py_IS_NAN(val)) {
|
|
- return PyString_FromString("NaN");
|
|
+ return PyUnicode_FromString("NaN");
|
|
} else if (Py_IS_INFINITY(val)) {
|
|
if (val > 0) {
|
|
- return PyString_FromString("Infinity");
|
|
+ return PyUnicode_FromString("Infinity");
|
|
} else {
|
|
- return PyString_FromString("-Infinity");
|
|
+ return PyUnicode_FromString("-Infinity");
|
|
}
|
|
} else {
|
|
return PyObject_Repr(object);
|
|
}
|
|
- } else if (PyInt_Check(object) || PyLong_Check(object)) {
|
|
+ } else if (PyLong_Check(object)) {
|
|
return PyObject_Str(object);
|
|
} else if (PyList_Check(object)) {
|
|
PyObject *result;
|
|
@@ -1111,6 +1058,7 @@ JSON_decode(PyObject *self, PyObject *ar
|
|
static char *kwlist[] = {"json", "all_unicode", NULL};
|
|
int all_unicode = False; // by default return unicode only when needed
|
|
PyObject *object, *string, *str;
|
|
+ Py_ssize_t str_size;
|
|
JSONData jsondata;
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:decode", kwlist,
|
|
@@ -1127,13 +1075,13 @@ JSON_decode(PyObject *self, PyObject *ar
|
|
str = string;
|
|
}
|
|
|
|
- if (PyString_AsStringAndSize(str, &(jsondata.str), NULL) == -1) {
|
|
+ if (PyBytes_AsStringAndSize(str, &(jsondata.str), &str_size) == -1) {
|
|
Py_DECREF(str);
|
|
return NULL; // not a string object or it contains null bytes
|
|
}
|
|
|
|
jsondata.ptr = jsondata.str;
|
|
- jsondata.end = jsondata.str + PyString_GET_SIZE(str);
|
|
+ jsondata.end = jsondata.str + str_size;
|
|
jsondata.all_unicode = all_unicode;
|
|
|
|
object = decode_json(&jsondata);
|
|
@@ -1179,37 +1127,93 @@ PyDoc_STRVAR(module_doc,
|
|
|
|
/* Initialization function for the module (*must* be called initcjson) */
|
|
|
|
+struct module_state {
|
|
+ PyObject *error;
|
|
+};
|
|
+
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
+//#############################################################################
|
|
+//# PYTHON 3 ##################################################################
|
|
+//#############################################################################
|
|
+
|
|
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
|
|
+
|
|
+static int cjson_traverse(PyObject *m, visitproc visit, void *arg) {
|
|
+ Py_VISIT(GETSTATE(m)->error);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cjson_clear(PyObject *m) {
|
|
+ Py_CLEAR(GETSTATE(m)->error);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static struct PyModuleDef moduledef = {
|
|
+ PyModuleDef_HEAD_INIT,
|
|
+ "cjson",
|
|
+ module_doc,
|
|
+ sizeof(struct module_state),
|
|
+ cjson_methods,
|
|
+ NULL,
|
|
+ cjson_traverse,
|
|
+ cjson_clear,
|
|
+ NULL
|
|
+};
|
|
+
|
|
+#define INITERROR return NULL
|
|
+
|
|
+PyMODINIT_FUNC
|
|
+PyInit_cjson(void)
|
|
+//#############################################################################
|
|
+#else
|
|
+//#############################################################################
|
|
+//# PYTHON 2 ##################################################################
|
|
+//#############################################################################
|
|
+
|
|
+#define GETSTATE(m) (&_state)
|
|
+static struct module_state _state;
|
|
+
|
|
+#define INITERROR return
|
|
+
|
|
PyMODINIT_FUNC
|
|
initcjson(void)
|
|
+//#############################################################################
|
|
+#endif
|
|
{
|
|
PyObject *m;
|
|
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
+ m = PyModule_Create(&moduledef);
|
|
+#else
|
|
m = Py_InitModule3("cjson", cjson_methods, module_doc);
|
|
+#endif
|
|
|
|
if (m == NULL)
|
|
- return;
|
|
+ INITERROR;
|
|
|
|
JSON_Error = PyErr_NewException("cjson.Error", NULL, NULL);
|
|
if (JSON_Error == NULL)
|
|
- return;
|
|
+ INITERROR;
|
|
Py_INCREF(JSON_Error);
|
|
PyModule_AddObject(m, "Error", JSON_Error);
|
|
|
|
JSON_EncodeError = PyErr_NewException("cjson.EncodeError", JSON_Error, NULL);
|
|
if (JSON_EncodeError == NULL)
|
|
- return;
|
|
+ INITERROR;
|
|
Py_INCREF(JSON_EncodeError);
|
|
PyModule_AddObject(m, "EncodeError", JSON_EncodeError);
|
|
|
|
JSON_DecodeError = PyErr_NewException("cjson.DecodeError", JSON_Error, NULL);
|
|
if (JSON_DecodeError == NULL)
|
|
- return;
|
|
+ INITERROR;
|
|
Py_INCREF(JSON_DecodeError);
|
|
PyModule_AddObject(m, "DecodeError", JSON_DecodeError);
|
|
|
|
// Module version (the MODULE_VERSION macro is defined by setup.py)
|
|
PyModule_AddStringConstant(m, "__version__", string(MODULE_VERSION));
|
|
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
+ return m;
|
|
+#endif
|
|
}
|
|
-
|
|
-
|
|
Index: python-cjson-1.2.2/jsontest.py
|
|
===================================================================
|
|
--- python-cjson-1.2.2.orig/jsontest.py
|
|
+++ python-cjson-1.2.2/jsontest.py
|
|
@@ -128,7 +128,7 @@ class JsonTest(unittest.TestCase):
|
|
self.assertRaises(_exception, self.doReadBadEscapedHexCharacter)
|
|
|
|
def doReadBadEscapedHexCharacter(self):
|
|
- cjson.decode('"\u10K5"')
|
|
+ cjson.decode(u'"\\u10K5"')
|
|
|
|
def testReadBadObjectKey(self):
|
|
self.assertRaises(_exception, self.doReadBadObjectKey)
|
|
@@ -141,7 +141,7 @@ class JsonTest(unittest.TestCase):
|
|
|
|
def doReadBadArray(self):
|
|
cjson.decode('[1,2,3,,]')
|
|
-
|
|
+
|
|
def testReadBadObjectSyntax(self):
|
|
self.assertRaises(_exception, self.doReadBadObjectSyntax)
|
|
|
|
@@ -159,7 +159,7 @@ class JsonTest(unittest.TestCase):
|
|
def testReadNegativeIntegerValue(self):
|
|
obj = cjson.decode('{ "key" : -44 }')
|
|
self.assertEqual({ "key" : -44 }, obj)
|
|
-
|
|
+
|
|
def testReadFloatValue(self):
|
|
obj = cjson.decode('{ "age" : 44.5 }')
|
|
self.assertEqual({ "age" : 44.5 }, obj)
|
|
@@ -176,7 +176,7 @@ class JsonTest(unittest.TestCase):
|
|
|
|
def testReadSmallObject(self):
|
|
obj = cjson.decode('{ "name" : "Patrick", "age":44} ')
|
|
- self.assertEqual({ "age" : 44, "name" : "Patrick" }, obj)
|
|
+ self.assertEqual({ "age" : 44, "name" : "Patrick" }, obj)
|
|
|
|
def testReadEmptyArray(self):
|
|
obj = cjson.decode('[]')
|
|
@@ -194,7 +194,7 @@ class JsonTest(unittest.TestCase):
|
|
|
|
def testWriteSmallObject(self):
|
|
s = cjson.encode({ "name" : "Patrick", "age": 44 })
|
|
- self.assertEqual('{"age":44,"name":"Patrick"}', _removeWhitespace(s))
|
|
+ self.assertEqual('{"name":"Patrick","age":44}', _removeWhitespace(s))
|
|
|
|
def testWriteFloat(self):
|
|
n = 3.44556677
|
|
@@ -276,7 +276,7 @@ class JsonTest(unittest.TestCase):
|
|
obj = [{"name":"Patrick","age":44,"Employed?":True,"Female?":False,"grandchildren":None},
|
|
"used","abused","confused",
|
|
1,2,[3,4,5]]
|
|
- self.assertEqual('[{"Female?":false,"age":44,"name":"Patrick","grandchildren":null,"Employed?":true},"used","abused","confused",1,2,[3,4,5]]',
|
|
+ self.assertEqual('[{"name":"Patrick","age":44,"Employed?":true,"Female?":false,"grandchildren":null},"used","abused","confused",1,2,[3,4,5]]',
|
|
_removeWhitespace(cjson.encode(obj)))
|
|
|
|
|
|
@@ -290,7 +290,7 @@ class JsonTest(unittest.TestCase):
|
|
|
|
def testStringEncoding(self):
|
|
s = cjson.encode([1, 2, 3])
|
|
- self.assertEqual(unicode("[1,2,3]", "utf-8"), _removeWhitespace(s))
|
|
+ self.assertEqual("[1,2,3]", _removeWhitespace(s))
|
|
|
|
def testReadEmptyObjectAtEndOfArray(self):
|
|
self.assertEqual(["a","b","c",{}],
|
|
@@ -331,7 +331,7 @@ class JsonTest(unittest.TestCase):
|
|
u'\u1234\u1234\u1234\u1234\u1234\u1234')
|
|
self.assertEqual(r'"\ud834\udd1e\ud834\udd1e\ud834\udd1e\ud834\udd1e'
|
|
r'\u1234\u1234\u1234\u1234\u1234\u1234"', s)
|
|
-
|
|
+
|
|
def main():
|
|
unittest.main()
|
|
|