[Python-checkins] cpython (2.7): Issue #27942: String constants now interned recursively in tuples and
serhiy.storchaka
python-checkins at python.org
Fri Sep 30 03:40:00 EDT 2016
https://hg.python.org/cpython/rev/7cea3bf44acb
changeset: 104178:7cea3bf44acb
branch: 2.7
parent: 104171:5f788ad057ca
user: Serhiy Storchaka <storchaka at gmail.com>
date: Fri Sep 30 10:38:08 2016 +0300
summary:
Issue #27942: String constants now interned recursively in tuples and frozensets.
files:
Lib/test/test_code.py | 33 ++++++++++++++++++-
Misc/NEWS | 2 +
Objects/codeobject.c | 54 +++++++++++++++++++++++++-----
3 files changed, 79 insertions(+), 10 deletions(-)
diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py
--- a/Lib/test/test_code.py
+++ b/Lib/test/test_code.py
@@ -112,6 +112,37 @@
self.assertEqual(co.co_name, "funcname")
self.assertEqual(co.co_firstlineno, 15)
+class CodeConstsTest(unittest.TestCase):
+
+ def find_const(self, consts, value):
+ for v in consts:
+ if v == value:
+ return v
+ self.assertIn(value, consts) # rises an exception
+ self.fail('Should be never reached')
+
+ def assertIsInterned(self, s):
+ if s is not intern(s):
+ self.fail('String %r is not interned' % (s,))
+
+ @cpython_only
+ def test_interned_string(self):
+ co = compile('res = "str_value"', '?', 'exec')
+ v = self.find_const(co.co_consts, 'str_value')
+ self.assertIsInterned(v)
+
+ @cpython_only
+ def test_interned_string_in_tuple(self):
+ co = compile('res = ("str_value",)', '?', 'exec')
+ v = self.find_const(co.co_consts, ('str_value',))
+ self.assertIsInterned(v[0])
+
+ @cpython_only
+ def test_interned_string_default(self):
+ def f(a='str_value'):
+ return a
+ self.assertIsInterned(f())
+
class CodeWeakRefTest(unittest.TestCase):
@@ -141,7 +172,7 @@
def test_main(verbose=None):
from test import test_code
run_doctest(test_code, verbose)
- run_unittest(CodeTest, CodeWeakRefTest)
+ run_unittest(CodeTest, CodeConstsTest, CodeWeakRefTest)
if __name__ == "__main__":
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
Core and Builtins
-----------------
+- Issue #27942: String constants now interned recursively in tuples and frozensets.
+
- Issue #15578: Correctly incref the parent module while importing.
- Issue #26307: The profile-opt build now applys PGO to the built-in modules.
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -39,6 +39,50 @@
}
}
+/* 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 (PyString_CheckExact(v)) {
+ if (all_name_chars((unsigned char *)PyString_AS_STRING(v))) {
+ PyObject *w = v;
+ PyString_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 nlocals, int stacksize, int flags,
@@ -68,15 +112,7 @@
intern_strings(varnames);
intern_strings(freevars);
intern_strings(cellvars);
- /* Intern selected string constants */
- for (i = PyTuple_Size(consts); --i >= 0; ) {
- PyObject *v = PyTuple_GetItem(consts, i);
- if (!PyString_Check(v))
- continue;
- if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
- continue;
- PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
- }
+ intern_string_constants(consts);
co = PyObject_NEW(PyCodeObject, &PyCode_Type);
if (co != NULL) {
co->co_argcount = argcount;
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list