summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-09-30 07:07:26 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-09-30 07:07:26 (GMT)
commit00a0fc1144d928515ff8abd0de7bb6ad072fcbdb (patch)
treec556e0e9d15dea2648f7b62dcea717cb67653a40 /Objects
parent55f3ae68bb5b3d17719f9c2b85913c9a3f38adbb (diff)
downloadcpython-00a0fc1144d928515ff8abd0de7bb6ad072fcbdb.zip
cpython-00a0fc1144d928515ff8abd0de7bb6ad072fcbdb.tar.gz
cpython-00a0fc1144d928515ff8abd0de7bb6ad072fcbdb.tar.bz2
Issue #27942: String constants now interned recursively in tuples and frozensets.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/codeobject.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 6c0e5bf..e50f730 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -46,6 +46,50 @@ intern_strings(PyObject *tuple)
}
}
+/* Intern selected string constants */
+static int
+intern_string_constants(PyObject *tuple)
+{
+ int modified = 0;
+ Py_ssize_t i;
+
+ for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
+ PyObject *v = PyTuple_GET_ITEM(tuple, i);
+ if (PyUnicode_CheckExact(v)) {
+ if (all_name_chars(v)) {
+ PyObject *w = v;
+ PyUnicode_InternInPlace(&v);
+ if (w != v) {
+ PyTuple_SET_ITEM(tuple, i, v);
+ modified = 1;
+ }
+ }
+ }
+ else if (PyTuple_CheckExact(v)) {
+ intern_string_constants(v);
+ }
+ else if (PyFrozenSet_CheckExact(v)) {
+ PyObject *tmp = PySequence_Tuple(v);
+ if (tmp == NULL) {
+ PyErr_Clear();
+ continue;
+ }
+ if (intern_string_constants(tmp)) {
+ v = PyFrozenSet_New(tmp);
+ if (v == NULL) {
+ PyErr_Clear();
+ }
+ else {
+ PyTuple_SET_ITEM(tuple, i, v);
+ modified = 1;
+ }
+ }
+ Py_DECREF(tmp);
+ }
+ }
+ return modified;
+}
+
PyCodeObject *
PyCode_New(int argcount, int kwonlyargcount,
@@ -84,13 +128,7 @@ PyCode_New(int argcount, int kwonlyargcount,
intern_strings(varnames);
intern_strings(freevars);
intern_strings(cellvars);
- /* Intern selected string constants */
- for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) {
- PyObject *v = PyTuple_GetItem(consts, i);
- if (!all_name_chars(v))
- continue;
- PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
- }
+ intern_string_constants(consts);
/* Create mapping between cells and arguments if needed. */
if (n_cellvars) {
Py_ssize_t total_args = argcount + kwonlyargcount +