https://github.com/python/cpython/commit/da699ed7e546ec106609a3858dd529335facaa4d
commit: da699ed7e546ec106609a3858dd529335facaa4d
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-07-13T21:09:42+03:00
summary:

gh-121914: Change the names of the symbol tables for lambda and genexpr 
(GH-135288)

Change the names of the symbol tables for lambda expressions and generator
expressions to "<lambda>" and "<genexpr>" respectively to avoid conflicts
with user-defined names.

files:
A Misc/NEWS.d/next/Library/2025-06-09-10-16-55.gh-issue-121914.G6Avkq.rst
M Include/internal/pycore_global_objects_fini_generated.h
M Include/internal/pycore_global_strings.h
M Include/internal/pycore_runtime_init_generated.h
M Include/internal/pycore_unicodeobject_generated.h
M Lib/symtable.py
M Lib/test/test_symtable.py
M Python/symtable.c

diff --git a/Include/internal/pycore_global_objects_fini_generated.h 
b/Include/internal/pycore_global_objects_fini_generated.h
index c461bc1786ddf4..493377b4c25040 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -904,7 +904,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(deterministic));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(device));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dict));
-    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dictcomp));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(difference_update));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digest));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digest_size));
@@ -979,7 +978,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(func));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(future));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(generation));
-    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(genexpr));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_debug));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_event_loop));
@@ -1055,7 +1053,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw2));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kwdefaults));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(label));
-    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lambda));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_exc));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_node));
@@ -1071,7 +1068,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(line));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(line_buffering));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lineno));
-    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(listcomp));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(little));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lo));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(locale));
@@ -1218,7 +1214,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(server_hostname));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(server_side));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(session));
-    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setcomp));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setpgroup));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsid));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsigdef));
diff --git a/Include/internal/pycore_global_strings.h 
b/Include/internal/pycore_global_strings.h
index 72c2051bd97660..5dfea2f479d5fe 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -395,7 +395,6 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(deterministic)
         STRUCT_FOR_ID(device)
         STRUCT_FOR_ID(dict)
-        STRUCT_FOR_ID(dictcomp)
         STRUCT_FOR_ID(difference_update)
         STRUCT_FOR_ID(digest)
         STRUCT_FOR_ID(digest_size)
@@ -470,7 +469,6 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(func)
         STRUCT_FOR_ID(future)
         STRUCT_FOR_ID(generation)
-        STRUCT_FOR_ID(genexpr)
         STRUCT_FOR_ID(get)
         STRUCT_FOR_ID(get_debug)
         STRUCT_FOR_ID(get_event_loop)
@@ -546,7 +544,6 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(kw2)
         STRUCT_FOR_ID(kwdefaults)
         STRUCT_FOR_ID(label)
-        STRUCT_FOR_ID(lambda)
         STRUCT_FOR_ID(last)
         STRUCT_FOR_ID(last_exc)
         STRUCT_FOR_ID(last_node)
@@ -562,7 +559,6 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(line)
         STRUCT_FOR_ID(line_buffering)
         STRUCT_FOR_ID(lineno)
-        STRUCT_FOR_ID(listcomp)
         STRUCT_FOR_ID(little)
         STRUCT_FOR_ID(lo)
         STRUCT_FOR_ID(locale)
@@ -709,7 +705,6 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(server_hostname)
         STRUCT_FOR_ID(server_side)
         STRUCT_FOR_ID(session)
-        STRUCT_FOR_ID(setcomp)
         STRUCT_FOR_ID(setpgroup)
         STRUCT_FOR_ID(setsid)
         STRUCT_FOR_ID(setsigdef)
diff --git a/Include/internal/pycore_runtime_init_generated.h 
b/Include/internal/pycore_runtime_init_generated.h
index d378fcae26cf35..85ced09d29d338 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -902,7 +902,6 @@ extern "C" {
     INIT_ID(deterministic), \
     INIT_ID(device), \
     INIT_ID(dict), \
-    INIT_ID(dictcomp), \
     INIT_ID(difference_update), \
     INIT_ID(digest), \
     INIT_ID(digest_size), \
@@ -977,7 +976,6 @@ extern "C" {
     INIT_ID(func), \
     INIT_ID(future), \
     INIT_ID(generation), \
-    INIT_ID(genexpr), \
     INIT_ID(get), \
     INIT_ID(get_debug), \
     INIT_ID(get_event_loop), \
@@ -1053,7 +1051,6 @@ extern "C" {
     INIT_ID(kw2), \
     INIT_ID(kwdefaults), \
     INIT_ID(label), \
-    INIT_ID(lambda), \
     INIT_ID(last), \
     INIT_ID(last_exc), \
     INIT_ID(last_node), \
@@ -1069,7 +1066,6 @@ extern "C" {
     INIT_ID(line), \
     INIT_ID(line_buffering), \
     INIT_ID(lineno), \
-    INIT_ID(listcomp), \
     INIT_ID(little), \
     INIT_ID(lo), \
     INIT_ID(locale), \
@@ -1216,7 +1212,6 @@ extern "C" {
     INIT_ID(server_hostname), \
     INIT_ID(server_side), \
     INIT_ID(session), \
-    INIT_ID(setcomp), \
     INIT_ID(setpgroup), \
     INIT_ID(setsid), \
     INIT_ID(setsigdef), \
diff --git a/Include/internal/pycore_unicodeobject_generated.h 
b/Include/internal/pycore_unicodeobject_generated.h
index e516211f6c6cbc..6018d98d156a65 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -1368,10 +1368,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) 
{
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
-    string = &_Py_ID(dictcomp);
-    _PyUnicode_InternStatic(interp, &string);
-    assert(_PyUnicode_CheckConsistency(string, 1));
-    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(difference_update);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1668,10 +1664,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) 
{
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
-    string = &_Py_ID(genexpr);
-    _PyUnicode_InternStatic(interp, &string);
-    assert(_PyUnicode_CheckConsistency(string, 1));
-    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(get);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1972,10 +1964,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) 
{
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
-    string = &_Py_ID(lambda);
-    _PyUnicode_InternStatic(interp, &string);
-    assert(_PyUnicode_CheckConsistency(string, 1));
-    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(last);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2036,10 +2024,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) 
{
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
-    string = &_Py_ID(listcomp);
-    _PyUnicode_InternStatic(interp, &string);
-    assert(_PyUnicode_CheckConsistency(string, 1));
-    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(little);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2624,10 +2608,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) 
{
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
-    string = &_Py_ID(setcomp);
-    _PyUnicode_InternStatic(interp, &string);
-    assert(_PyUnicode_CheckConsistency(string, 1));
-    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(setpgroup);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
diff --git a/Lib/symtable.py b/Lib/symtable.py
index 7a30e1ac4ca378..77475c3ffd9224 100644
--- a/Lib/symtable.py
+++ b/Lib/symtable.py
@@ -255,11 +255,6 @@ def is_local_symbol(ident):
                 if is_local_symbol(st.name):
                     match st.type:
                         case _symtable.TYPE_FUNCTION:
-                            # generators are of type TYPE_FUNCTION with a ".0"
-                            # parameter as a first parameter (which makes them
-                            # distinguishable from a function named 'genexpr')
-                            if st.name == 'genexpr' and '.0' in st.varnames:
-                                continue
                             d[st.name] = 1
                         case _symtable.TYPE_TYPE_PARAMETERS:
                             # Get the function-def block in the annotation
@@ -267,13 +262,6 @@ def is_local_symbol(ident):
                             scope_name = st.name
                             for c in st.children:
                                 if c.name == scope_name and c.type == 
_symtable.TYPE_FUNCTION:
-                                    # A generic generator of type TYPE_FUNCTION
-                                    # cannot be a direct child of 'st' (but it
-                                    # can be a descendant), e.g.:
-                                    #
-                                    # class A:
-                                    #   type genexpr[genexpr] = (x for x in [])
-                                    assert scope_name != 'genexpr' or '.0' not 
in c.varnames
                                     d[scope_name] = 1
                                     break
             self.__methods = tuple(d)
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
index 24d89b09d946ad..26c75fcbc2bd7f 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -527,6 +527,58 @@ def test_symtable_entry_repr(self):
         expected = f"<symtable entry top({self.top.get_id()}), line 
{self.top.get_lineno()}>"
         self.assertEqual(repr(self.top._table), expected)
 
+    def test_lambda(self):
+        st = symtable.symtable("lambda x: x", "?", "exec")
+        self.assertEqual(len(st.get_children()), 1)
+        st = st.get_children()[0]
+        self.assertIs(st.get_type(), symtable.SymbolTableType.FUNCTION)
+        self.assertEqual(st.get_name(), "<lambda>")
+        self.assertFalse(st.is_nested())
+        self.assertEqual(sorted(st.get_identifiers()), ["x"])
+        self.assertEqual(st.get_children(), [])
+
+    def test_nested_lambda(self):
+        st = symtable.symtable("lambda x: lambda y=x: y", "?", "exec")
+        self.assertEqual(len(st.get_children()), 1)
+        st = st.get_children()[0]
+        self.assertIs(st.get_type(), symtable.SymbolTableType.FUNCTION)
+        self.assertEqual(st.get_name(), "<lambda>")
+        self.assertFalse(st.is_nested())
+        self.assertEqual(sorted(st.get_identifiers()), ["x"])
+        self.assertEqual(len(st.get_children()), 1)
+        st = st.get_children()[0]
+        self.assertIs(st.get_type(), symtable.SymbolTableType.FUNCTION)
+        self.assertEqual(st.get_name(), "<lambda>")
+        self.assertTrue(st.is_nested())
+        self.assertEqual(sorted(st.get_identifiers()), ["y"])
+        self.assertEqual(st.get_children(), [])
+
+    def test_genexpr(self):
+        st = symtable.symtable("(x for x in a)", "?", "exec")
+        self.assertEqual(len(st.get_children()), 1)
+        st = st.get_children()[0]
+        self.assertIs(st.get_type(), symtable.SymbolTableType.FUNCTION)
+        self.assertEqual(st.get_name(), "<genexpr>")
+        self.assertFalse(st.is_nested())
+        self.assertEqual(sorted(st.get_identifiers()), [".0", "x"])
+        self.assertEqual(st.get_children(), [])
+
+    def test_nested_genexpr(self):
+        st = symtable.symtable("((y for y in x) for x in a)", "?", "exec")
+        self.assertEqual(len(st.get_children()), 1)
+        st = st.get_children()[0]
+        self.assertIs(st.get_type(), symtable.SymbolTableType.FUNCTION)
+        self.assertEqual(st.get_name(), "<genexpr>")
+        self.assertFalse(st.is_nested())
+        self.assertEqual(sorted(st.get_identifiers()), [".0", "x"])
+        self.assertEqual(len(st.get_children()), 1)
+        st = st.get_children()[0]
+        self.assertIs(st.get_type(), symtable.SymbolTableType.FUNCTION)
+        self.assertEqual(st.get_name(), "<genexpr>")
+        self.assertTrue(st.is_nested())
+        self.assertEqual(sorted(st.get_identifiers()), [".0", "y"])
+        self.assertEqual(st.get_children(), [])
+
 
 class ComprehensionTests(unittest.TestCase):
     def get_identifiers_recursive(self, st, res):
diff --git 
a/Misc/NEWS.d/next/Library/2025-06-09-10-16-55.gh-issue-121914.G6Avkq.rst 
b/Misc/NEWS.d/next/Library/2025-06-09-10-16-55.gh-issue-121914.G6Avkq.rst
new file mode 100644
index 00000000000000..a1314a9cb7f943
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-06-09-10-16-55.gh-issue-121914.G6Avkq.rst
@@ -0,0 +1,3 @@
+Changed the names of the symbol tables for lambda expressions and generator
+expressions to "<lambda>" and "<genexpr>" respectively to avoid conflicts
+with user-defined names.
diff --git a/Python/symtable.c b/Python/symtable.c
index a3d0fff80d24a1..bcd7365f8e1f14 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -2413,7 +2413,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
             VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
         if (e->v.Lambda.args->kw_defaults)
             VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults);
-        if (!symtable_enter_block(st, &_Py_ID(lambda),
+        if (!symtable_enter_block(st, &_Py_STR(anon_lambda),
                                   FunctionBlock, (void *)e, LOCATION(e))) {
             return 0;
         }
@@ -3055,7 +3055,7 @@ symtable_handle_comprehension(struct symtable *st, 
expr_ty e,
 static int
 symtable_visit_genexp(struct symtable *st, expr_ty e)
 {
-    return symtable_handle_comprehension(st, e, &_Py_ID(genexpr),
+    return symtable_handle_comprehension(st, e, &_Py_STR(anon_genexpr),
                                          e->v.GeneratorExp.generators,
                                          e->v.GeneratorExp.elt, NULL);
 }
@@ -3063,7 +3063,7 @@ symtable_visit_genexp(struct symtable *st, expr_ty e)
 static int
 symtable_visit_listcomp(struct symtable *st, expr_ty e)
 {
-    return symtable_handle_comprehension(st, e, &_Py_ID(listcomp),
+    return symtable_handle_comprehension(st, e, &_Py_STR(anon_listcomp),
                                          e->v.ListComp.generators,
                                          e->v.ListComp.elt, NULL);
 }
@@ -3071,7 +3071,7 @@ symtable_visit_listcomp(struct symtable *st, expr_ty e)
 static int
 symtable_visit_setcomp(struct symtable *st, expr_ty e)
 {
-    return symtable_handle_comprehension(st, e, &_Py_ID(setcomp),
+    return symtable_handle_comprehension(st, e, &_Py_STR(anon_setcomp),
                                          e->v.SetComp.generators,
                                          e->v.SetComp.elt, NULL);
 }
@@ -3079,7 +3079,7 @@ symtable_visit_setcomp(struct symtable *st, expr_ty e)
 static int
 symtable_visit_dictcomp(struct symtable *st, expr_ty e)
 {
-    return symtable_handle_comprehension(st, e, &_Py_ID(dictcomp),
+    return symtable_handle_comprehension(st, e, &_Py_STR(anon_dictcomp),
                                          e->v.DictComp.generators,
                                          e->v.DictComp.key,
                                          e->v.DictComp.value);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to