_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));
_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));
_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));
_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));
_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));
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)
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)
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)
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)
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)
INIT_ID(deterministic), \
INIT_ID(device), \
INIT_ID(dict), \
- INIT_ID(dictcomp), \
INIT_ID(difference_update), \
INIT_ID(digest), \
INIT_ID(digest_size), \
INIT_ID(func), \
INIT_ID(future), \
INIT_ID(generation), \
- INIT_ID(genexpr), \
INIT_ID(get), \
INIT_ID(get_debug), \
INIT_ID(get_event_loop), \
INIT_ID(kw2), \
INIT_ID(kwdefaults), \
INIT_ID(label), \
- INIT_ID(lambda), \
INIT_ID(last), \
INIT_ID(last_exc), \
INIT_ID(last_node), \
INIT_ID(line), \
INIT_ID(line_buffering), \
INIT_ID(lineno), \
- INIT_ID(listcomp), \
INIT_ID(little), \
INIT_ID(lo), \
INIT_ID(locale), \
INIT_ID(server_hostname), \
INIT_ID(server_side), \
INIT_ID(session), \
- INIT_ID(setcomp), \
INIT_ID(setpgroup), \
INIT_ID(setsid), \
INIT_ID(setsigdef), \
_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));
_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));
_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));
_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));
_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));
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
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)
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):
--- /dev/null
+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.
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;
}
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);
}
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);
}
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);
}
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);