diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index e118b86db50754..4387eddec98512 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)); @@ -1217,7 +1213,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 36f3d23d095d59..d917b574afa77d 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) @@ -708,7 +704,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 d172cc1485d426..e3963dde56c8af 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), \ @@ -1215,7 +1211,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 0a9be4e41ace89..191e54925ff3bd 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)); @@ -2620,10 +2604,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"" 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(), "") + 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(), "") + 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(), "") + 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(), "") + 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(), "") + 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(), "") + 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 "" and "" 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);