]> granicus.if.org Git - python/commitdiff
Fix for SF [ 734869 ] Lambda functions in list comprehensions
authorJeremy Hylton <jeremy@alum.mit.edu>
Wed, 21 May 2003 17:34:50 +0000 (17:34 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Wed, 21 May 2003 17:34:50 +0000 (17:34 +0000)
The compiler was reseting the list comprehension tmpname counter for each function, but the symtable was using the same counter for the entire module.  Repair by move tmpname into the symtable entry.

Bugfix candidate.

Include/symtable.h
Lib/test/output/test_grammar
Lib/test/test_grammar.py
Python/compile.c
Python/symtable.c

index 301bd3075fbc2eab9cdc9adf89a6b13fdbd34527..d2438921b0424c25727dcd240157082d33719ae1 100644 (file)
@@ -28,7 +28,6 @@ struct symtable {
        int st_nscopes;          /* number of scopes */
        int st_errors;           /* number of errors */
        char *st_private;        /* name of current class or NULL */
-       int st_tmpname;          /* temporary name counter */
        PyFutureFeatures *st_future; /* module's future features */
 };
 
@@ -47,6 +46,7 @@ typedef struct _symtable_entry {
                                    including free refs to globals */
        int ste_generator;       /* true if namespace is a generator */
        int ste_opt_lineno;      /* lineno of last exec or import * */
+       int ste_tmpname;          /* temporary name counter */
        struct symtable *ste_table;
 } PySymtableEntryObject;
 
index 6cf5862f6e16560c916028c80b36fbe28d8fe18e..00fab49a6dcf3c16c047f4bbc72ed663ada26ca5 100644 (file)
@@ -60,6 +60,7 @@ classdef
 [3, 4, 5]
 [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]
 [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')]
+[[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]
 [False, False, False]
 [[1, 2], [3, 4], [5, 6]]
 [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]
index ea0a88ceb921618d53df1cee60019b6543abd850..cb777279dfee01432b4bad695f32b4e9cd9b51a4 100644 (file)
@@ -701,6 +701,7 @@ print [3 * x for x in nums]
 print [x for x in nums if x > 2]
 print [(i, s) for i in nums for s in strs]
 print [(i, s) for i in nums for s in [f for f in strs if "n" in f]]
+print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)] 
 
 def test_in_func(l):
     return [None < x < 3 for x in l if x > 2]
index a98b905fd6e8450c99e560f3b221c8bba572bfd8..76a37115105c9c6178fcf967f311444362aba61c 100644 (file)
@@ -731,6 +731,7 @@ static void symtable_global(struct symtable *, node *);
 static void symtable_import(struct symtable *, node *);
 static void symtable_assign(struct symtable *, node *, int);
 static void symtable_list_comprehension(struct symtable *, node *);
+static void symtable_list_for(struct symtable *, node *);
 
 static int symtable_update_free_vars(struct symtable *);
 static int symtable_undo_free(struct symtable *, PyObject *, PyObject *);
@@ -1602,6 +1603,8 @@ com_list_comprehension(struct compiling *c, node *n)
 {
        /* listmaker: test list_for */
        char tmpname[30];
+
+       REQ(n, listmaker);
        PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->c_tmpname);
        com_addoparg(c, BUILD_LIST, 0);
        com_addbyte(c, DUP_TOP); /* leave the result on the stack */
@@ -4921,7 +4924,6 @@ symtable_init()
        st->st_cur = NULL;
        st->st_nscopes = 0;
        st->st_errors = 0;
-       st->st_tmpname = 0;
        st->st_private = NULL;
        return st;
  fail:
@@ -5123,9 +5125,6 @@ symtable_enter_scope(struct symtable *st, char *name, int type,
        if (st->st_cur) {
                prev = st->st_cur;
                if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) {
-                       /* Py_DECREF(st->st_cur); */
-                       /* I believe the previous line would lead to a
-                          double-DECREF when st is disposed - JRH */
                        st->st_errors++;
                        return;
                }
@@ -5395,12 +5394,12 @@ symtable_node(struct symtable *st, node *n)
                }
                goto loop;
        case list_iter:
+               /* only occurs when there are multiple for loops
+                  in a list comprehension */
                n = CHILD(n, 0);
-               if (TYPE(n) == list_for) {
-                       st->st_tmpname++;
-                       symtable_list_comprehension(st, n);
-                       st->st_tmpname--;
-               } else {
+               if (TYPE(n) == list_for)
+                       symtable_list_for(st, n);
+               else {
                        REQ(n, list_if);
                        symtable_node(st, CHILD(n, 1));
                        if (NCH(n) == 3) {
@@ -5428,10 +5427,7 @@ symtable_node(struct symtable *st, node *n)
                /* fall through */
        case listmaker:
                if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for) {
-                       st->st_tmpname++;
-                       symtable_list_comprehension(st, CHILD(n, 1));
-                       symtable_node(st, CHILD(n, 0));
-                       st->st_tmpname--;
+                       symtable_list_comprehension(st, n);
                        break;
                }
                /* fall through */
@@ -5629,10 +5625,23 @@ symtable_global(struct symtable *st, node *n)
 static void
 symtable_list_comprehension(struct symtable *st, node *n)
 {
+       /* listmaker: test list_for */
        char tmpname[30];
 
-       PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", st->st_tmpname);
+       REQ(n, listmaker);
+       PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", 
+                     ++st->st_cur->ste_tmpname);
        symtable_add_def(st, tmpname, DEF_LOCAL);
+       symtable_list_for(st, CHILD(n, 1));
+       symtable_node(st, CHILD(n, 0));
+       --st->st_cur->ste_tmpname;
+}
+
+static void
+symtable_list_for(struct symtable *st, node *n)
+{
+       REQ(n, list_for);
+       /* list_for: for v in expr [list_iter] */
        symtable_assign(st, CHILD(n, 1), 0);
        symtable_node(st, CHILD(n, 3));
        if (NCH(n) == 5)
index e48eaea1d547ca2e0815d7f7620fe4d4628417ee..f86fd2fbc802ba021cb308abd7fdeace43cefb5a 100644 (file)
@@ -61,6 +61,7 @@ PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno)
 
        ste->ste_optimized = 0;
        ste->ste_opt_lineno = 0;
+       ste->ste_tmpname = 0;
        ste->ste_lineno = lineno;
        switch (type) {
        case funcdef: