summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-05-28 12:31:49 (GMT)
committerGitHub <noreply@github.com>2017-05-28 12:31:49 (GMT)
commitac5bbd43bc7b769c13ae0412cb28a3521f4d4ff1 (patch)
tree7f75690d054fb8619b9ac33ad7dcae989617c4fd /Modules
parent4a8bcdf79cdb3684743fe1268de62ee88bada439 (diff)
downloadcpython-ac5bbd43bc7b769c13ae0412cb28a3521f4d4ff1.zip
cpython-ac5bbd43bc7b769c13ae0412cb28a3521f4d4ff1.tar.gz
cpython-ac5bbd43bc7b769c13ae0412cb28a3521f4d4ff1.tar.bz2
bpo-30248: Convert boolean arguments only once in _json. (#1423)
Rather than saving the Python object and calling PyObject_IsTrue() every time when the boolean argument is used, call it only once and save C boolean value.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_json.c64
1 files changed, 24 insertions, 40 deletions
diff --git a/Modules/_json.c b/Modules/_json.c
index e78e371..f574004 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -18,7 +18,7 @@ static PyTypeObject PyEncoderType;
typedef struct _PyScannerObject {
PyObject_HEAD
- PyObject *strict;
+ char strict;
PyObject *object_hook;
PyObject *object_pairs_hook;
PyObject *parse_float;
@@ -28,7 +28,7 @@ typedef struct _PyScannerObject {
} PyScannerObject;
static PyMemberDef scanner_members[] = {
- {"strict", T_OBJECT, offsetof(PyScannerObject, strict), READONLY, "strict"},
+ {"strict", T_BOOL, offsetof(PyScannerObject, strict), READONLY, "strict"},
{"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"},
{"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), READONLY},
{"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"},
@@ -45,10 +45,10 @@ typedef struct _PyEncoderObject {
PyObject *indent;
PyObject *key_separator;
PyObject *item_separator;
- PyObject *sort_keys;
- PyObject *skipkeys;
- PyCFunction fast_encode;
+ char sort_keys;
+ char skipkeys;
int allow_nan;
+ PyCFunction fast_encode;
} PyEncoderObject;
static PyMemberDef encoder_members[] = {
@@ -58,8 +58,8 @@ static PyMemberDef encoder_members[] = {
{"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"},
{"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"},
{"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"},
- {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"},
- {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"},
+ {"sort_keys", T_BOOL, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"},
+ {"skipkeys", T_BOOL, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"},
{NULL}
};
@@ -666,7 +666,6 @@ scanner_traverse(PyObject *self, visitproc visit, void *arg)
PyScannerObject *s;
assert(PyScanner_Check(self));
s = (PyScannerObject *)self;
- Py_VISIT(s->strict);
Py_VISIT(s->object_hook);
Py_VISIT(s->object_pairs_hook);
Py_VISIT(s->parse_float);
@@ -681,7 +680,6 @@ scanner_clear(PyObject *self)
PyScannerObject *s;
assert(PyScanner_Check(self));
s = (PyScannerObject *)self;
- Py_CLEAR(s->strict);
Py_CLEAR(s->object_hook);
Py_CLEAR(s->object_pairs_hook);
Py_CLEAR(s->parse_float);
@@ -692,7 +690,8 @@ scanner_clear(PyObject *self)
}
static PyObject *
-_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
+_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
+{
/* Read a JSON object from PyUnicode pystr.
idx is the index of the first character after the opening curly brace.
*next_idx_ptr is a return-by-reference index to the first character after
@@ -706,13 +705,9 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
PyObject *val = NULL;
PyObject *rval = NULL;
PyObject *key = NULL;
- int strict = PyObject_IsTrue(s->strict);
int has_pairs_hook = (s->object_pairs_hook != Py_None);
Py_ssize_t next_idx;
- if (strict < 0)
- return NULL;
-
if (PyUnicode_READY(pystr) == -1)
return NULL;
@@ -740,7 +735,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx);
goto bail;
}
- key = scanstring_unicode(pystr, idx + 1, strict, &next_idx);
+ key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
if (key == NULL)
goto bail;
memokey = PyDict_GetItem(s->memo, key);
@@ -1060,7 +1055,6 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_
void *str;
int kind;
Py_ssize_t length;
- int strict;
if (PyUnicode_READY(pystr) == -1)
return NULL;
@@ -1081,10 +1075,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_
switch (PyUnicode_READ(kind, str, idx)) {
case '"':
/* string */
- strict = PyObject_IsTrue(s->strict);
- if (strict < 0)
- return NULL;
- return scanstring_unicode(pystr, idx + 1, strict, next_idx_ptr);
+ return scanstring_unicode(pystr, idx + 1, s->strict, next_idx_ptr);
case '{':
/* object */
if (Py_EnterRecursiveCall(" while decoding a JSON object "
@@ -1197,6 +1188,7 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyScannerObject *s;
PyObject *ctx;
+ PyObject *strict;
static char *kwlist[] = {"context", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
@@ -1212,8 +1204,12 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
goto bail;
/* All of these will fail "gracefully" so we don't need to verify them */
- s->strict = PyObject_GetAttrString(ctx, "strict");
- if (s->strict == NULL)
+ strict = PyObject_GetAttrString(ctx, "strict");
+ if (strict == NULL)
+ goto bail;
+ s->strict = PyObject_IsTrue(strict);
+ Py_DECREF(strict);
+ if (s->strict < 0)
goto bail;
s->object_hook = PyObject_GetAttrString(ctx, "object_hook");
if (s->object_hook == NULL)
@@ -1290,10 +1286,10 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyEncoderObject *s;
PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
- PyObject *item_separator, *sort_keys, *skipkeys;
- int allow_nan;
+ PyObject *item_separator;
+ int sort_keys, skipkeys, allow_nan;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUOOp:make_encoder", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUppp:make_encoder", kwlist,
&markers, &defaultfn, &encoder, &indent,
&key_separator, &item_separator,
&sort_keys, &skipkeys, &allow_nan))
@@ -1318,6 +1314,7 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
s->item_separator = item_separator;
s->sort_keys = sort_keys;
s->skipkeys = skipkeys;
+ s->allow_nan = allow_nan;
s->fast_encode = NULL;
if (PyCFunction_Check(s->encoder)) {
PyCFunction f = PyCFunction_GetFunction(s->encoder);
@@ -1326,7 +1323,6 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
s->fast_encode = f;
}
}
- s->allow_nan = allow_nan;
Py_INCREF(s->markers);
Py_INCREF(s->defaultfn);
@@ -1334,8 +1330,6 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Py_INCREF(s->indent);
Py_INCREF(s->key_separator);
Py_INCREF(s->item_separator);
- Py_INCREF(s->sort_keys);
- Py_INCREF(s->skipkeys);
return (PyObject *)s;
}
@@ -1551,8 +1545,6 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
PyObject *it = NULL;
PyObject *items;
PyObject *item = NULL;
- int skipkeys;
- int sortkeys;
Py_ssize_t idx;
if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
@@ -1597,16 +1589,12 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
items = PyMapping_Items(dct);
if (items == NULL)
goto bail;
- sortkeys = PyObject_IsTrue(s->sort_keys);
- if (sortkeys < 0 || (sortkeys && PyList_Sort(items) < 0))
+ if (s->sort_keys && PyList_Sort(items) < 0)
goto bail;
it = PyObject_GetIter(items);
Py_DECREF(items);
if (it == NULL)
goto bail;
- skipkeys = PyObject_IsTrue(s->skipkeys);
- if (skipkeys < 0)
- goto bail;
idx = 0;
while ((item = PyIter_Next(it)) != NULL) {
PyObject *encoded, *key, *value;
@@ -1637,7 +1625,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
goto bail;
}
}
- else if (skipkeys) {
+ else if (s->skipkeys) {
Py_DECREF(item);
continue;
}
@@ -1805,8 +1793,6 @@ encoder_traverse(PyObject *self, visitproc visit, void *arg)
Py_VISIT(s->indent);
Py_VISIT(s->key_separator);
Py_VISIT(s->item_separator);
- Py_VISIT(s->sort_keys);
- Py_VISIT(s->skipkeys);
return 0;
}
@@ -1823,8 +1809,6 @@ encoder_clear(PyObject *self)
Py_CLEAR(s->indent);
Py_CLEAR(s->key_separator);
Py_CLEAR(s->item_separator);
- Py_CLEAR(s->sort_keys);
- Py_CLEAR(s->skipkeys);
return 0;
}