summaryrefslogtreecommitdiff
path: root/Python/symtable.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/symtable.c')
-rw-r--r--Python/symtable.c122
1 files changed, 82 insertions, 40 deletions
diff --git a/Python/symtable.c b/Python/symtable.c
index f30ba0f761..51b59f0310 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -32,7 +32,6 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
goto fail;
ste->ste_table = st;
ste->ste_id = k;
- ste->ste_tmpname = 0;
ste->ste_name = name;
Py_INCREF(name);
@@ -168,6 +167,8 @@ static int symtable_exit_block(struct symtable *st, void *ast);
static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
static int symtable_visit_expr(struct symtable *st, expr_ty s);
static int symtable_visit_genexp(struct symtable *st, expr_ty s);
+static int symtable_visit_setcomp(struct symtable *st, expr_ty e);
+static int symtable_visit_dictcomp(struct symtable *st, expr_ty e);
static int symtable_visit_arguments(struct symtable *st, arguments_ty);
static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
static int symtable_visit_alias(struct symtable *st, alias_ty);
@@ -179,7 +180,8 @@ static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args);
static int symtable_implicit_arg(struct symtable *st, int pos);
-static identifier top = NULL, lambda = NULL, genexpr = NULL;
+static identifier top = NULL, lambda = NULL, genexpr = NULL, setcomp = NULL,
+ dictcomp = NULL;
#define GET_IDENTIFIER(VAR) \
((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR)))
@@ -204,7 +206,6 @@ symtable_new(void)
if ((st->st_symbols = PyDict_New()) == NULL)
goto fail;
st->st_cur = NULL;
- st->st_tmpname = 0;
st->st_private = NULL;
return st;
fail:
@@ -495,7 +496,7 @@ check_unoptimized(const PySTEntryObject* ste) {
case OPT_IMPORT_STAR:
PyOS_snprintf(buf, sizeof(buf),
"import * is not allowed in function '%.100s' "
- "because it is %s",
+ "because it %s",
PyString_AS_STRING(ste->ste_name), trailer);
break;
case OPT_BARE_EXEC:
@@ -702,7 +703,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
ste->ste_child_free = 1;
}
- PyDict_Update(newfree, allfree);
+ if (PyDict_Update(newfree, allfree) < 0)
+ goto error;
if (ste->ste_type == FunctionBlock && !analyze_cells(scope, newfree))
goto error;
if (!update_symbols(ste->ste_symbols, scope, bound, newfree,
@@ -846,7 +848,7 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
st->st_cur = ste_new(st, name, block, ast, lineno);
if (st->st_cur == NULL)
return 0;
- if (name == GET_IDENTIFIER(top))
+ if (block == ModuleBlock)
st->st_global = st->st_cur->ste_symbols;
if (prev) {
if (PyList_Append(prev->ste_children,
@@ -994,23 +996,6 @@ error:
}
static int
-symtable_new_tmpname(struct symtable *st)
-{
- char tmpname[256];
- identifier tmp;
-
- PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
- ++st->st_cur->ste_tmpname);
- tmp = PyString_InternFromString(tmpname);
- if (!tmp)
- return 0;
- if (!symtable_add_def(st, tmp, DEF_LOCAL))
- return 0;
- Py_DECREF(tmp);
- return 1;
-}
-
-static int
symtable_visit_stmt(struct symtable *st, stmt_ty s)
{
switch (s->kind) {
@@ -1183,12 +1168,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
/* nothing to do here */
break;
case With_kind:
- if (!symtable_new_tmpname(st))
- return 0;
VISIT(st, expr, s->v.With.context_expr);
if (s->v.With.optional_vars) {
- if (!symtable_new_tmpname(st))
- return 0;
VISIT(st, expr, s->v.With.optional_vars);
}
VISIT_SEQ(st, stmt, s->v.With.body);
@@ -1212,8 +1193,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT(st, expr, e->v.UnaryOp.operand);
break;
case Lambda_kind: {
- if (!GET_IDENTIFIER(lambda) ||
- !symtable_add_def(st, lambda, DEF_LOCAL))
+ if (!GET_IDENTIFIER(lambda))
return 0;
if (e->v.Lambda.args->defaults)
VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
@@ -1235,9 +1215,10 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT_SEQ(st, expr, e->v.Dict.keys);
VISIT_SEQ(st, expr, e->v.Dict.values);
break;
+ case Set_kind:
+ VISIT_SEQ(st, expr, e->v.Set.elts);
+ break;
case ListComp_kind:
- if (!symtable_new_tmpname(st))
- return 0;
VISIT(st, expr, e->v.ListComp.elt);
VISIT_SEQ(st, comprehension, e->v.ListComp.generators);
break;
@@ -1245,6 +1226,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
if (!symtable_visit_genexp(st, e))
return 0;
break;
+ case SetComp_kind:
+ if (!symtable_visit_setcomp(st, e))
+ return 0;
+ break;
+ case DictComp_kind:
+ if (!symtable_visit_dictcomp(st, e))
+ return 0;
+ break;
case Yield_kind:
if (e->v.Yield.value)
VISIT(st, expr, e->v.Yield.value);
@@ -1407,7 +1396,7 @@ static int
symtable_visit_alias(struct symtable *st, alias_ty a)
{
/* Compute store_name, the name actually bound by the import
- operation. It is diferent than a->name when a->name is a
+ operation. It is different than a->name when a->name is a
dotted package name (e.g. spam.eggs)
*/
PyObject *store_name;
@@ -1486,27 +1475,80 @@ symtable_visit_slice(struct symtable *st, slice_ty s)
}
static int
-symtable_visit_genexp(struct symtable *st, expr_ty e)
+symtable_new_tmpname(struct symtable *st)
{
+ char tmpname[256];
+ identifier tmp;
+
+ PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
+ ++st->st_cur->ste_tmpname);
+ tmp = PyString_InternFromString(tmpname);
+ if (!tmp)
+ return 0;
+ if (!symtable_add_def(st, tmp, DEF_LOCAL))
+ return 0;
+ Py_DECREF(tmp);
+ return 1;
+}
+
+static int
+symtable_handle_comprehension(struct symtable *st, expr_ty e,
+ identifier scope_name, asdl_seq *generators,
+ expr_ty elt, expr_ty value)
+{
+ int is_generator = (e->kind == GeneratorExp_kind);
+ int needs_tmp = !is_generator;
comprehension_ty outermost = ((comprehension_ty)
- (asdl_seq_GET(e->v.GeneratorExp.generators, 0)));
+ asdl_seq_GET(generators, 0));
/* Outermost iterator is evaluated in current scope */
VISIT(st, expr, outermost->iter);
- /* Create generator scope for the rest */
- if (!GET_IDENTIFIER(genexpr) ||
- !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, e->lineno)) {
+ /* Create comprehension scope for the rest */
+ if (!scope_name ||
+ !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, 0)) {
return 0;
}
- st->st_cur->ste_generator = 1;
+ st->st_cur->ste_generator = is_generator;
/* Outermost iter is received as an argument */
if (!symtable_implicit_arg(st, 0)) {
symtable_exit_block(st, (void *)e);
return 0;
}
+ /* Allocate temporary name if needed */
+ if (needs_tmp && !symtable_new_tmpname(st)) {
+ symtable_exit_block(st, (void *)e);
+ return 0;
+ }
VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
- e->v.GeneratorExp.generators, 1, (void*)e);
- VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e);
+ generators, 1, (void*)e);
+ if (value)
+ VISIT_IN_BLOCK(st, expr, value, (void*)e);
+ VISIT_IN_BLOCK(st, expr, elt, (void*)e);
return symtable_exit_block(st, (void *)e);
}
+
+static int
+symtable_visit_genexp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr),
+ e->v.GeneratorExp.generators,
+ e->v.GeneratorExp.elt, NULL);
+}
+
+static int
+symtable_visit_setcomp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(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, GET_IDENTIFIER(dictcomp),
+ e->v.DictComp.generators,
+ e->v.DictComp.key,
+ e->v.DictComp.value);
+}