mirror of
https://github.com/python/cpython.git
synced 2025-12-09 10:37:17 +00:00
gh-111928: make "memo" dict local to scan_once call (gh-112005)
Co-authored-by: Sam Gross <colesbury@gmail.com>
This commit is contained in:
parent
9a2f25d374
commit
d0058cbd1c
1 changed files with 19 additions and 23 deletions
|
|
@ -24,7 +24,6 @@ typedef struct _PyScannerObject {
|
||||||
PyObject *parse_float;
|
PyObject *parse_float;
|
||||||
PyObject *parse_int;
|
PyObject *parse_int;
|
||||||
PyObject *parse_constant;
|
PyObject *parse_constant;
|
||||||
PyObject *memo;
|
|
||||||
} PyScannerObject;
|
} PyScannerObject;
|
||||||
|
|
||||||
static PyMemberDef scanner_members[] = {
|
static PyMemberDef scanner_members[] = {
|
||||||
|
|
@ -70,7 +69,7 @@ ascii_escape_unicode(PyObject *pystr);
|
||||||
static PyObject *
|
static PyObject *
|
||||||
py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr);
|
py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr);
|
||||||
static PyObject *
|
static PyObject *
|
||||||
scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
|
scan_once_unicode(PyScannerObject *s, PyObject *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
|
_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
@ -631,7 +630,6 @@ scanner_traverse(PyScannerObject *self, visitproc visit, void *arg)
|
||||||
Py_VISIT(self->parse_float);
|
Py_VISIT(self->parse_float);
|
||||||
Py_VISIT(self->parse_int);
|
Py_VISIT(self->parse_int);
|
||||||
Py_VISIT(self->parse_constant);
|
Py_VISIT(self->parse_constant);
|
||||||
Py_VISIT(self->memo);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -643,12 +641,11 @@ scanner_clear(PyScannerObject *self)
|
||||||
Py_CLEAR(self->parse_float);
|
Py_CLEAR(self->parse_float);
|
||||||
Py_CLEAR(self->parse_int);
|
Py_CLEAR(self->parse_int);
|
||||||
Py_CLEAR(self->parse_constant);
|
Py_CLEAR(self->parse_constant);
|
||||||
Py_CLEAR(self->memo);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
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 *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
|
||||||
{
|
{
|
||||||
/* Read a JSON object from PyUnicode pystr.
|
/* Read a JSON object from PyUnicode pystr.
|
||||||
idx is the index of the first character after the opening curly brace.
|
idx is the index of the first character after the opening curly brace.
|
||||||
|
|
@ -693,7 +690,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
|
||||||
key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
|
key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
goto bail;
|
goto bail;
|
||||||
memokey = PyDict_SetDefault(s->memo, key, key);
|
memokey = PyDict_SetDefault(memo, key, key);
|
||||||
if (memokey == NULL) {
|
if (memokey == NULL) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
@ -710,7 +707,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
|
||||||
while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
|
while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
|
||||||
|
|
||||||
/* read any JSON term */
|
/* read any JSON term */
|
||||||
val = scan_once_unicode(s, pystr, idx, &next_idx);
|
val = scan_once_unicode(s, memo, pystr, idx, &next_idx);
|
||||||
if (val == NULL)
|
if (val == NULL)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
|
@ -774,7 +771,7 @@ bail:
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
|
_parse_array_unicode(PyScannerObject *s, PyObject *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
|
||||||
/* Read a JSON array from PyUnicode pystr.
|
/* Read a JSON array from PyUnicode pystr.
|
||||||
idx is the index of the first character after the opening brace.
|
idx is the index of the first character after the opening brace.
|
||||||
*next_idx_ptr is a return-by-reference index to the first character after
|
*next_idx_ptr is a return-by-reference index to the first character after
|
||||||
|
|
@ -805,7 +802,7 @@ _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssi
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* read any JSON term */
|
/* read any JSON term */
|
||||||
val = scan_once_unicode(s, pystr, idx, &next_idx);
|
val = scan_once_unicode(s, memo, pystr, idx, &next_idx);
|
||||||
if (val == NULL)
|
if (val == NULL)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
|
@ -986,7 +983,7 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
|
scan_once_unicode(PyScannerObject *s, PyObject *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
|
||||||
{
|
{
|
||||||
/* Read one JSON term (of any kind) from PyUnicode pystr.
|
/* Read one JSON term (of any kind) from PyUnicode pystr.
|
||||||
idx is the index of the first character of the term
|
idx is the index of the first character of the term
|
||||||
|
|
@ -1022,7 +1019,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_
|
||||||
if (_Py_EnterRecursiveCall(" while decoding a JSON object "
|
if (_Py_EnterRecursiveCall(" while decoding a JSON object "
|
||||||
"from a unicode string"))
|
"from a unicode string"))
|
||||||
return NULL;
|
return NULL;
|
||||||
res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
|
res = _parse_object_unicode(s, memo, pystr, idx + 1, next_idx_ptr);
|
||||||
_Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
return res;
|
return res;
|
||||||
case '[':
|
case '[':
|
||||||
|
|
@ -1030,7 +1027,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_
|
||||||
if (_Py_EnterRecursiveCall(" while decoding a JSON array "
|
if (_Py_EnterRecursiveCall(" while decoding a JSON array "
|
||||||
"from a unicode string"))
|
"from a unicode string"))
|
||||||
return NULL;
|
return NULL;
|
||||||
res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
|
res = _parse_array_unicode(s, memo, pystr, idx + 1, next_idx_ptr);
|
||||||
_Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
return res;
|
return res;
|
||||||
case 'n':
|
case 'n':
|
||||||
|
|
@ -1106,16 +1103,19 @@ scanner_call(PyScannerObject *self, PyObject *args, PyObject *kwds)
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx))
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (PyUnicode_Check(pystr)) {
|
if (!PyUnicode_Check(pystr)) {
|
||||||
rval = scan_once_unicode(self, pystr, idx, &next_idx);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"first argument must be a string, not %.80s",
|
"first argument must be a string, not %.80s",
|
||||||
Py_TYPE(pystr)->tp_name);
|
Py_TYPE(pystr)->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyDict_Clear(self->memo);
|
|
||||||
|
PyObject *memo = PyDict_New();
|
||||||
|
if (memo == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rval = scan_once_unicode(self, memo, pystr, idx, &next_idx);
|
||||||
|
Py_DECREF(memo);
|
||||||
if (rval == NULL)
|
if (rval == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return _build_rval_index_tuple(rval, next_idx);
|
return _build_rval_index_tuple(rval, next_idx);
|
||||||
|
|
@ -1137,10 +1137,6 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->memo = PyDict_New();
|
|
||||||
if (s->memo == NULL)
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
/* All of these will fail "gracefully" so we don't need to verify them */
|
/* All of these will fail "gracefully" so we don't need to verify them */
|
||||||
strict = PyObject_GetAttrString(ctx, "strict");
|
strict = PyObject_GetAttrString(ctx, "strict");
|
||||||
if (strict == NULL)
|
if (strict == NULL)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue