summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--simplejson/_speedups.c246
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);