mirror of https://github.com/python/cpython
Fix AST compiler bug #1501934: incorrect LOAD/STORE_GLOBAL generation.
This commit is contained in:
parent
63597f129d
commit
0e07b60a4e
|
@ -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))], [])]),
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue