]> granicus.if.org Git - python/commitdiff
Fix AST compiler bug #1501934: incorrect LOAD/STORE_GLOBAL generation.
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>
Sun, 9 Jul 2006 16:16:34 +0000 (16:16 +0000)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>
Sun, 9 Jul 2006 16:16:34 +0000 (16:16 +0000)
Lib/test/test_ast.py
Lib/test/test_scope.py
Misc/NEWS
Python/ast.c
Python/compile.c

index c64ad2856fe8d56a8df04ee7b7528ac703b6cb0f..14fc01026fd1654e4bb9e9ead0b28dca2efd9003 100644 (file)
@@ -160,7 +160,7 @@ exec_results = [
 ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [])]),
 ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
 ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]),
-('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Load',)), ('Add',), ('Num', (1, 5), 1))]),
+('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Num', (1, 5), 1))]),
 ('Module', [('Print', (1, 0), ('Name', (1, 8), 'f', ('Load',)), [('Num', (1, 11), 1)], False)]),
 ('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]),
 ('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
index f37254c9df9533a29a35ae8310b2ebaf794a8011..239745c613fe3e80f9a2c17c3084f9d02940d08a 100644 (file)
@@ -299,6 +299,17 @@ except NameError:
 else:
     raise TestFailed
 
+# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
+global_x = 1
+def f():
+    global_x += 1
+try:
+    f()
+except UnboundLocalError:
+    pass
+else:
+    raise TestFailed, 'scope of global_x not correctly determined'
+
 print "14. complex definitions"
 
 def makeReturner(*lst):
index b31023d12ddf672fd70f69a5fdb278d2c1a06798..f01aff2207e58d1bed04bd66f354615f5c174816 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.5 beta 2?
 Core and builtins
 -----------------
 
+- Bug #1501934: The scope of global variables that are locally assigned
+  using augmented assignment is now correctly determined.
+
 - Bug #927248: Recursive method-wrapper objects can now safely
   be released.
 
index 4c78b004f3e804d0e737bbe1b91e0ac32a0de32f..6fd1ebe2c9994f8d275e0d22e83688df7673525e 100644 (file)
@@ -339,7 +339,7 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n)
     /* The ast defines augmented store and load contexts, but the
        implementation here doesn't actually use them.  The code may be
        a little more complex than necessary as a result.  It also means
-       that expressions in an augmented assignment have no context.
+       that expressions in an augmented assignment have a Store context.
        Consider restructuring so that augmented assignment uses
        set_context(), too.
     */
@@ -1901,7 +1901,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
 
         if (!expr1)
             return NULL;
-        /* TODO(jhylton): Figure out why set_context() can't be used here. */
+        /* TODO(nas): Remove duplicated error checks (set_context does it) */
         switch (expr1->kind) {
             case GeneratorExp_kind:
                 ast_error(ch, "augmented assignment to generator "
@@ -1923,6 +1923,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
                           "assignment");
                 return NULL;
         }
+       set_context(expr1, Store, ch);
 
        ch = CHILD(n, 2);
        if (TYPE(ch) == testlist)
index 5bda62edeabe21d65d4300eaa36f4e8a36e258ad..3ddb0677d0b3509e55cd17a608ad128e79400de4 100644 (file)
@@ -3688,7 +3688,8 @@ compiler_augassign(struct compiler *c, stmt_ty s)
                VISIT(c, expr, auge);
                break;
        case Name_kind:
-               VISIT(c, expr, s->v.AugAssign.target);
+               if (!compiler_nameop(c, e->v.Name.id, Load))
+                   return 0;
                VISIT(c, expr, s->v.AugAssign.value);
                ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
                return compiler_nameop(c, e->v.Name.id, Store);