diff options
author | Bob Ippolito <bob@redivi.com> | 2018-05-12 10:39:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-12 10:39:42 -0700 |
commit | 424a9e9aabba6f000def57c470a18a44076737d8 (patch) | |
tree | 860519d36aa6c6cfd5ebe1bb890d97142658e604 | |
parent | 476e08369fd151a982cb5aaaacd92a50eccce9f8 (diff) | |
parent | 1bd31cb46b088ed0b3c12f3c6bc4d725c755a1e5 (diff) | |
download | simplejson-424a9e9aabba6f000def57c470a18a44076737d8.tar.gz |
Merge pull request #220 from simplejson/speedups-cleanup
Clean up the C code.
-rw-r--r-- | simplejson/_speedups.c | 246 |
1 files changed, 105 insertions, 141 deletions
diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c index e791618..1b5d441 100644 --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -5,36 +5,24 @@ #if PY_MAJOR_VERSION >= 3 #define PyInt_FromSsize_t PyLong_FromSsize_t #define PyInt_AsSsize_t PyLong_AsSsize_t -#define PyString_Check PyBytes_Check -#define PyString_GET_SIZE PyBytes_GET_SIZE -#define PyString_AS_STRING PyBytes_AS_STRING -#define PyString_FromStringAndSize PyBytes_FromStringAndSize #define PyInt_Check(obj) 0 #define PyInt_CheckExact(obj) 0 #define JSON_UNICHR Py_UCS4 #define JSON_InternFromString PyUnicode_InternFromString -#define JSON_Intern_GET_SIZE PyUnicode_GET_SIZE -#define JSON_ASCII_Check PyUnicode_Check -#define JSON_ASCII_AS_STRING PyUnicode_AsUTF8 -#define PyInt_Type PyLong_Type -#define PyInt_FromString PyLong_FromString +#define PyString_GET_SIZE PyUnicode_GET_LENGTH #define PY2_UNUSED #define PY3_UNUSED UNUSED -#define JSON_NewEmptyUnicode() PyUnicode_New(0, 127) #else /* PY_MAJOR_VERSION >= 3 */ #define PY2_UNUSED UNUSED #define PY3_UNUSED +#define PyBytes_Check PyString_Check #define PyUnicode_READY(obj) 0 #define PyUnicode_KIND(obj) (sizeof(Py_UNICODE)) #define PyUnicode_DATA(obj) ((void *)(PyUnicode_AS_UNICODE(obj))) #define PyUnicode_READ(kind, data, index) ((JSON_UNICHR)((const Py_UNICODE *)(data))[(index)]) -#define PyUnicode_GetLength PyUnicode_GET_SIZE +#define PyUnicode_GET_LENGTH PyUnicode_GET_SIZE #define JSON_UNICHR Py_UNICODE -#define JSON_ASCII_Check PyString_Check -#define JSON_ASCII_AS_STRING PyString_AS_STRING #define JSON_InternFromString PyString_InternFromString -#define JSON_Intern_GET_SIZE PyString_GET_SIZE -#define JSON_NewEmptyUnicode() PyUnicode_FromUnicode(NULL, 0) #endif /* PY_MAJOR_VERSION < 3 */ #if PY_VERSION_HEX < 0x02070000 @@ -84,6 +72,11 @@ json_PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exce #define JSON_ALLOW_NAN 1 #define JSON_IGNORE_NAN 2 +static PyObject *JSON_Infinity = NULL; +static PyObject *JSON_NegInfinity = NULL; +static PyObject *JSON_NaN = NULL; +static PyObject *JSON_EmptyUnicode = NULL; + static PyTypeObject PyScannerType; static PyTypeObject PyEncoderType; @@ -188,8 +181,6 @@ join_list_unicode(PyObject *lst); static PyObject * JSON_ParseEncoding(PyObject *encoding); static PyObject * -JSON_UnicodeFromChar(JSON_UNICHR c); -static PyObject * maybe_quote_bigint(PyEncoderObject* s, PyObject *encoded, PyObject *obj); static Py_ssize_t ascii_char_size(JSON_UNICHR c); @@ -318,7 +309,7 @@ JSON_Accu_Accumulate(JSON_Accu *acc, PyObject *unicode) #if PY_MAJOR_VERSION >= 3 assert(PyUnicode_Check(unicode)); #else /* PY_MAJOR_VERSION >= 3 */ - assert(JSON_ASCII_Check(unicode) || PyUnicode_Check(unicode)); + assert(PyString_Check(unicode) || PyUnicode_Check(unicode)); #endif /* PY_MAJOR_VERSION < 3 */ if (PyList_Append(acc->small_strings, unicode)) @@ -369,19 +360,6 @@ IS_DIGIT(JSON_UNICHR c) } static PyObject * -JSON_UnicodeFromChar(JSON_UNICHR c) -{ -#if PY_MAJOR_VERSION >= 3 - PyObject *rval = PyUnicode_New(1, c); - if (rval) - PyUnicode_WRITE(PyUnicode_KIND(rval), PyUnicode_DATA(rval), 0, c); - return rval; -#else /* PY_MAJOR_VERSION >= 3 */ - return PyUnicode_FromUnicode(&c, 1); -#endif /* PY_MAJOR_VERSION < 3 */ -} - -static PyObject * maybe_quote_bigint(PyEncoderObject* s, PyObject *encoded, PyObject *obj) { if (s->max_long_size != Py_None && s->min_long_size != Py_None) { @@ -466,7 +444,7 @@ ascii_escape_char(JSON_UNICHR c, char *output, Py_ssize_t chars) case '\r': output[chars++] = 'r'; break; case '\t': output[chars++] = 't'; break; default: -#if defined(Py_UNICODE_WIDE) || PY_MAJOR_VERSION >= 3 +#if PY_MAJOR_VERSION >= 3 || defined(Py_UNICODE_WIDE) if (c >= 0x10000) { /* UTF-16 surrogate pair */ JSON_UNICHR v = c - 0x10000; @@ -505,7 +483,7 @@ ascii_char_size(JSON_UNICHR c) c == '\t') { return 2; } -#if defined(Py_UNICODE_WIDE) || PY_MAJOR_VERSION >= 3 +#if PY_MAJOR_VERSION >= 3 || defined(Py_UNICODE_WIDE) else if (c >= 0x10000U) { return 2 * MIN_EXPANSION; } @@ -520,20 +498,14 @@ ascii_escape_unicode(PyObject *pystr) { /* Take a PyUnicode pystr and return a new ASCII-only escaped PyString */ Py_ssize_t i; - Py_ssize_t input_chars; - Py_ssize_t output_size; + Py_ssize_t input_chars = PyUnicode_GET_LENGTH(pystr); + Py_ssize_t output_size = 2; Py_ssize_t chars; - PY2_UNUSED int kind; - void *data; + PY2_UNUSED int kind = PyUnicode_KIND(pystr); + void *data = PyUnicode_DATA(pystr); PyObject *rval; char *output; - if (PyUnicode_READY(pystr)) - return NULL; - - kind = PyUnicode_KIND(pystr); - data = PyUnicode_DATA(pystr); - input_chars = PyUnicode_GetLength(pystr); output_size = 2; for (i = 0; i < input_chars; i++) { output_size += ascii_char_size(PyUnicode_READ(kind, data, i)); @@ -568,7 +540,7 @@ static PyObject * ascii_escape_str(PyObject *pystr) { PyObject *rval; - PyObject *input = PyUnicode_DecodeUTF8(PyString_AS_STRING(pystr), PyString_GET_SIZE(pystr), NULL); + PyObject *input = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(pystr), PyBytes_GET_SIZE(pystr), NULL); if (input == NULL) return NULL; rval = ascii_escape_unicode(input); @@ -635,13 +607,13 @@ encoder_stringify_key(PyEncoderObject *s, PyObject *key) return key; } #if PY_MAJOR_VERSION >= 3 - else if (PyString_Check(key) && s->encoding != NULL) { - const char *encoding = JSON_ASCII_AS_STRING(s->encoding); + else if (PyBytes_Check(key) && s->encoding != NULL) { + const char *encoding = PyUnicode_AsUTF8(s->encoding); if (encoding == NULL) return NULL; return PyUnicode_Decode( - PyString_AS_STRING(key), - PyString_GET_SIZE(key), + PyBytes_AS_STRING(key), + PyBytes_GET_SIZE(key), encoding, NULL); } @@ -801,18 +773,7 @@ static PyObject * join_list_unicode(PyObject *lst) { /* return u''.join(lst) */ - static PyObject *joinfn = NULL; - if (joinfn == NULL) { - PyObject *ustr = JSON_NewEmptyUnicode(); - if (ustr == NULL) - return NULL; - - joinfn = PyObject_GetAttrString(ustr, "join"); - Py_DECREF(ustr); - if (joinfn == NULL) - return NULL; - } - return PyObject_CallFunctionObjArgs(joinfn, lst, NULL); + return PyUnicode_Join(JSON_EmptyUnicode, lst); } #if PY_MAJOR_VERSION >= 3 @@ -934,17 +895,6 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_s /* Pick up this chunk if it's not zero length */ if (next != end) { APPEND_OLD_CHUNK -#if PY_MAJOR_VERSION >= 3 - if (!has_unicode) { - chunk = PyUnicode_DecodeASCII(&buf[end], next - end, NULL); - } - else { - chunk = PyUnicode_Decode(&buf[end], next - end, encoding, NULL); - } - if (chunk == NULL) { - goto bail; - } -#else /* PY_MAJOR_VERSION >= 3 */ strchunk = PyString_FromStringAndSize(&buf[end], next - end); if (strchunk == NULL) { goto bail; @@ -959,7 +909,6 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_s else { chunk = strchunk; } -#endif /* PY_MAJOR_VERSION < 3 */ } next++; if (c == '"') { @@ -1017,7 +966,7 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_s goto bail; } } -#if (PY_MAJOR_VERSION >= 3 || defined(Py_UNICODE_WIDE)) +#if defined(Py_UNICODE_WIDE) /* Surrogate pair */ if ((c & 0xfc00) == 0xd800) { if (end + 6 < len && buf[next] == '\\' && buf[next+1] == 'u') { @@ -1052,20 +1001,14 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_s } } } -#endif /* PY_MAJOR_VERSION >= 3 || Py_UNICODE_WIDE */ +#endif /* Py_UNICODE_WIDE */ } if (c > 0x7f) { has_unicode = 1; } APPEND_OLD_CHUNK -#if PY_MAJOR_VERSION >= 3 - chunk = JSON_UnicodeFromChar(c); - if (chunk == NULL) { - goto bail; - } -#else /* PY_MAJOR_VERSION >= 3 */ if (has_unicode) { - chunk = JSON_UnicodeFromChar(c); + chunk = PyUnicode_FromOrdinal(c); if (chunk == NULL) { goto bail; } @@ -1077,14 +1020,15 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_s goto bail; } } -#endif } if (chunks == NULL) { if (chunk != NULL) rval = chunk; - else - rval = JSON_NewEmptyUnicode(); + else { + rval = JSON_EmptyUnicode; + Py_INCREF(rval); + } } else { APPEND_OLD_CHUNK @@ -1120,7 +1064,7 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next Py_ssize_t begin = end - 1; Py_ssize_t next = begin; PY2_UNUSED int kind = PyUnicode_KIND(pystr); - Py_ssize_t len = PyUnicode_GetLength(pystr); + Py_ssize_t len = PyUnicode_GET_LENGTH(pystr); void *buf = PyUnicode_DATA(pystr); PyObject *chunks = NULL; PyObject *chunk = NULL; @@ -1258,7 +1202,7 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next #endif } APPEND_OLD_CHUNK - chunk = JSON_UnicodeFromChar(c); + chunk = PyUnicode_FromOrdinal(c); if (chunk == NULL) { goto bail; } @@ -1267,8 +1211,10 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next if (chunks == NULL) { if (chunk != NULL) rval = chunk; - else - rval = JSON_NewEmptyUnicode(); + else { + rval = JSON_EmptyUnicode; + Py_INCREF(rval); + } } else { APPEND_OLD_CHUNK @@ -1316,6 +1262,8 @@ py_scanstring(PyObject* self UNUSED, PyObject *args) encoding = DEFAULT_ENCODING; } if (PyUnicode_Check(pystr)) { + if (PyUnicode_READY(pystr)) + return NULL; rval = scanstring_unicode(pystr, end, strict, &next_end); } #if PY_MAJOR_VERSION < 3 @@ -1345,10 +1293,12 @@ py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr) { /* Return an ASCII-only JSON representation of a Python string */ /* METH_O */ - if (PyString_Check(pystr)) { + if (PyBytes_Check(pystr)) { return ascii_escape_str(pystr); } else if (PyUnicode_Check(pystr)) { + if (PyUnicode_READY(pystr)) + return NULL; return ascii_escape_unicode(pystr); } else { @@ -1421,7 +1371,7 @@ _parse_object_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ PyObject *item; PyObject *key = NULL; PyObject *val = NULL; - char *encoding = JSON_ASCII_AS_STRING(s->encoding); + char *encoding = PyString_AS_STRING(s->encoding); int has_pairs_hook = (s->pairs_hook != Py_None); int did_parse = 0; Py_ssize_t next_idx; @@ -1575,7 +1525,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss Returns a new PyObject (usually a dict, but object_hook can change that) */ void *str = PyUnicode_DATA(pystr); - Py_ssize_t end_idx = PyUnicode_GetLength(pystr) - 1; + Py_ssize_t end_idx = PyUnicode_GET_LENGTH(pystr) - 1; PY2_UNUSED int kind = PyUnicode_KIND(pystr); PyObject *rval = NULL; PyObject *pairs = NULL; @@ -1820,7 +1770,7 @@ _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssi */ PY2_UNUSED int kind = PyUnicode_KIND(pystr); void *str = PyUnicode_DATA(pystr); - Py_ssize_t end_idx = PyUnicode_GetLength(pystr) - 1; + Py_ssize_t end_idx = PyUnicode_GET_LENGTH(pystr) - 1; PyObject *val = NULL; PyObject *rval = PyList_New(0); Py_ssize_t next_idx; @@ -1889,10 +1839,10 @@ bail: } static PyObject * -_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) +_parse_constant(PyScannerObject *s, PyObject *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { /* Read a JSON constant from PyString pystr. - constant is the constant string that was found + constant is the Python string that was found ("NaN", "Infinity", "-Infinity"). idx is the index of the first character of the constant *next_idx_ptr is a return-by-reference index to the first character after @@ -1900,17 +1850,11 @@ _parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t * Returns the result of parse_constant */ - PyObject *cstr; PyObject *rval; - /* constant is "NaN", "Infinity", or "-Infinity" */ - cstr = JSON_InternFromString(constant); - if (cstr == NULL) - return NULL; /* rval = parse_constant(constant) */ - rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL); - idx += JSON_Intern_GET_SIZE(cstr); - Py_DECREF(cstr); + rval = PyObject_CallFunctionObjArgs(s->parse_constant, constant, NULL); + idx += PyString_GET_SIZE(constant); *next_idx_ptr = idx; return rval; } @@ -2035,7 +1979,7 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ */ PY2_UNUSED int kind = PyUnicode_KIND(pystr); void *str = PyUnicode_DATA(pystr); - Py_ssize_t end_idx = PyUnicode_GetLength(pystr) - 1; + Py_ssize_t end_idx = PyUnicode_GET_LENGTH(pystr) - 1; Py_ssize_t idx = start; int is_float = 0; JSON_UNICHR c; @@ -2155,7 +2099,7 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n case '"': /* string */ rval = scanstring_str(pystr, idx + 1, - JSON_ASCII_AS_STRING(s->encoding), + PyString_AS_STRING(s->encoding), s->strict, next_idx_ptr); break; @@ -2208,7 +2152,7 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n case 'N': /* NaN */ if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') { - rval = _parse_constant(s, "NaN", idx, next_idx_ptr); + rval = _parse_constant(s, JSON_NaN, idx, next_idx_ptr); } else fallthrough = 1; @@ -2216,7 +2160,7 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n case 'I': /* Infinity */ if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') { - rval = _parse_constant(s, "Infinity", idx, next_idx_ptr); + rval = _parse_constant(s, JSON_Infinity, idx, next_idx_ptr); } else fallthrough = 1; @@ -2224,7 +2168,7 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n case '-': /* -Infinity */ if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') { - rval = _parse_constant(s, "-Infinity", idx, next_idx_ptr); + rval = _parse_constant(s, JSON_NegInfinity, idx, next_idx_ptr); } else fallthrough = 1; @@ -2252,7 +2196,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ */ PY2_UNUSED int kind = PyUnicode_KIND(pystr); void *str = PyUnicode_DATA(pystr); - Py_ssize_t length = PyUnicode_GetLength(pystr); + Py_ssize_t length = PyUnicode_GET_LENGTH(pystr); PyObject *rval = NULL; int fallthrough = 0; if (idx < 0 || idx >= length) { @@ -2327,7 +2271,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' && PyUnicode_READ(kind, str, idx + 2) == 'N') { - rval = _parse_constant(s, "NaN", idx, next_idx_ptr); + rval = _parse_constant(s, JSON_NaN, idx, next_idx_ptr); } else fallthrough = 1; @@ -2342,7 +2286,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ PyUnicode_READ(kind, str, idx + 5) == 'i' && PyUnicode_READ(kind, str, idx + 6) == 't' && PyUnicode_READ(kind, str, idx + 7) == 'y') { - rval = _parse_constant(s, "Infinity", idx, next_idx_ptr); + rval = _parse_constant(s, JSON_Infinity, idx, next_idx_ptr); } else fallthrough = 1; @@ -2358,7 +2302,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ PyUnicode_READ(kind, str, idx + 6) == 'i' && PyUnicode_READ(kind, str, idx + 7) == 't' && PyUnicode_READ(kind, str, idx + 8) == 'y') { - rval = _parse_constant(s, "-Infinity", idx, next_idx_ptr); + rval = _parse_constant(s, JSON_NegInfinity, idx, next_idx_ptr); } else fallthrough = 1; @@ -2388,6 +2332,8 @@ scanner_call(PyObject *self, PyObject *args, PyObject *kwds) return NULL; if (PyUnicode_Check(pystr)) { + if (PyUnicode_READY(pystr)) + return NULL; rval = scan_once_unicode(s, pystr, idx, &next_idx); } #if PY_MAJOR_VERSION < 3 @@ -2408,18 +2354,24 @@ scanner_call(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * JSON_ParseEncoding(PyObject *encoding) { - if (encoding == NULL) - return NULL; if (encoding == Py_None) return JSON_InternFromString(DEFAULT_ENCODING); -#if PY_MAJOR_VERSION < 3 - if (PyUnicode_Check(encoding)) - return PyUnicode_AsEncodedString(encoding, NULL, NULL); -#endif - if (JSON_ASCII_Check(encoding)) { +#if PY_MAJOR_VERSION >= 3 + if (PyUnicode_Check(encoding)) { + if (PyUnicode_AsUTF8(encoding) == NULL) { + return NULL; + } + Py_INCREF(encoding); + return encoding; + } +#else /* PY_MAJOR_VERSION >= 3 */ + if (PyString_Check(encoding)) { Py_INCREF(encoding); return encoding; } + if (PyUnicode_Check(encoding)) + return PyUnicode_AsEncodedString(encoding, NULL, NULL); +#endif /* PY_MAJOR_VERSION >= 3 */ PyErr_SetString(PyExc_TypeError, "encoding must be a string"); return NULL; } @@ -2446,8 +2398,9 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto bail; } - /* JSON_ASCII_AS_STRING is used on encoding */ encoding = PyObject_GetAttrString(ctx, "encoding"); + if (encoding == NULL) + goto bail; s->encoding = JSON_ParseEncoding(encoding); Py_XDECREF(encoding); if (s->encoding == NULL) @@ -2590,8 +2543,6 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) s->encoding = JSON_ParseEncoding(encoding); if (s->encoding == NULL) goto bail; - if (JSON_ASCII_AS_STRING(s->encoding) == NULL) - goto bail; } Py_INCREF(indent); s->indent = indent; @@ -2778,28 +2729,16 @@ encoder_encode_float(PyEncoderObject *s, PyObject *obj) } /* JSON_ALLOW_NAN is set */ else if (i > 0) { - static PyObject *sInfinity = NULL; - if (sInfinity == NULL) - sInfinity = JSON_InternFromString("Infinity"); - if (sInfinity) - Py_INCREF(sInfinity); - return sInfinity; + Py_INCREF(JSON_Infinity); + return JSON_Infinity; } else if (i < 0) { - static PyObject *sNegInfinity = NULL; - if (sNegInfinity == NULL) - sNegInfinity = JSON_InternFromString("-Infinity"); - if (sNegInfinity) - Py_INCREF(sNegInfinity); - return sNegInfinity; + Py_INCREF(JSON_NegInfinity); + return JSON_NegInfinity; } else { - static PyObject *sNaN = NULL; - if (sNaN == NULL) - sNaN = JSON_InternFromString("NaN"); - if (sNaN) - Py_INCREF(sNaN); - return sNaN; + Py_INCREF(JSON_NaN); + return JSON_NaN; } } /* Use a better float format here? */ @@ -2831,7 +2770,7 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) encoded = PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); if (encoded != NULL && #if PY_MAJOR_VERSION < 3 - !JSON_ASCII_Check(encoded) && + !PyString_Check(encoded) && #endif /* PY_MAJOR_VERSION < 3 */ !PyUnicode_Check(encoded)) { @@ -2864,7 +2803,7 @@ encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ss if (cstr != NULL) rv = _steal_accumulate(rval, cstr); } - else if ((PyString_Check(obj) && s->encoding != NULL) || + else if ((PyBytes_Check(obj) && s->encoding != NULL) || PyUnicode_Check(obj)) { PyObject *encoded = encoder_encode_string(s, obj); @@ -3377,6 +3316,29 @@ import_dependency(char *module_name, char *attr_name) return rval; } +static int +init_constants(void) +{ + JSON_NaN = JSON_InternFromString("NaN"); + if (JSON_NaN == NULL) + return 0; + JSON_Infinity = JSON_InternFromString("Infinity"); + if (JSON_Infinity == NULL) + return 0; + JSON_NegInfinity = JSON_InternFromString("-Infinity"); + if (JSON_NegInfinity == NULL) + return 0; +#if PY_MAJOR_VERSION >= 3 + JSON_EmptyUnicode = PyUnicode_New(0, 127); +#else /* PY_MAJOR_VERSION >= 3 */ + JSON_EmptyUnicode = PyUnicode_FromUnicode(NULL, 0); +#endif /* PY_MAJOR_VERSION >= 3 */ + if (JSON_EmptyUnicode == NULL) + return 0; + + return 1; +} + static PyObject * moduleinit(void) { @@ -3385,6 +3347,8 @@ moduleinit(void) return NULL; if (PyType_Ready(&PyEncoderType) < 0) return NULL; + if (!init_constants()) + return NULL; #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); |