Add global statements even for read of globals

This commit is contained in:
rocky 2017-12-02 19:13:11 -05:00
parent ec9d00a34d
commit 5ae32de709
6 changed files with 32 additions and 7 deletions

View File

@ -8,6 +8,10 @@ b = [4, 5, 6]
del b[1]
del b[:]
# del_stmt ::= expr expr DELETE_SLICE+1
l = [None] * 10
del l[-2:]
c = [0,1,2,3,4]
del c[:1]
del c[2:3]
@ -22,8 +26,10 @@ def foo():
del e
def a():
b =1
del z
def b(y):
global z
# covers DELETE_FAST
del y
# LOAD_DEREF

View File

@ -10,6 +10,14 @@ typeset -i STOP_ONERROR=1
typeset -A SKIP_TESTS
case $PYVERSION in
2.4)
SKIP_TESTS=( [test_binop.py]=1 # need to fix tryelse
[test_bool.py]=1 # need to fix tryelse
[test_call.py]=1 # need to fix tryelse
[test_cgi.py]=1 # need to fix tryelse
[test_class.py]=1 # need to fix tryelse
)
;;
2.6)
SKIP_TESTS=( [test_array.py]=1 [test_asyncore.py]=1)
;;

View File

@ -83,6 +83,7 @@ class Python2Parser(PythonParser):
raise_stmt3 ::= expr expr expr RAISE_VARARGS_3
del_stmt ::= expr DELETE_SLICE+0
del_stmt ::= expr expr DELETE_SLICE+1
del_stmt ::= expr expr DELETE_SLICE+2
del_stmt ::= expr expr expr DELETE_SLICE+3
del_stmt ::= delete_subscr

View File

@ -101,7 +101,6 @@ class Python27Parser(Python2Parser):
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1
for_block ::= return_stmts _come_from
del_stmt ::= expr expr DELETE_SLICE+1
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH

View File

@ -19,20 +19,28 @@ else:
from uncompyle6.show import maybe_show_ast_param_default
def find_all_globals(node, globs):
"""Find globals in this statement."""
"""Find globals including LOAD_GLOBALs in this AST node."""
for n in node:
if isinstance(n, AST):
globs = find_all_globals(n, globs)
elif n.kind in ('STORE_GLOBAL', 'DELETE_GLOBAL', 'LOAD_GLOBAL'):
elif n.kind in frozenset(('STORE_GLOBAL', 'DELETE_GLOBAL', 'LOAD_GLOBAL')):
globs.add(n.pattr)
return globs
def find_globals(node, globs):
mkfunc_globals = frozenset(('STORE_GLOBAL', 'DELETE_GLOBAL', 'LOAD_GLOBAL'))
mklambda_globals = frozenset(('STORE_GLOBAL', 'DELETE_GLOBAL'))
def find_globals(node, globs, global_ops=mkfunc_globals):
"""Find globals in this statement."""
for n in node:
# print("XXX", n.kind, global_ops)
if isinstance(n, AST):
globs = find_globals(n, globs)
elif n.kind in ('STORE_GLOBAL', 'DELETE_GLOBAL'):
# FIXME: do I need a caser for n.kind="mkfunc"?
if n.kind in ("conditional_lambda", "return_lambda"):
globs = find_globals(n, globs, mklambda_globals)
else:
globs = find_globals(n, globs, global_ops)
elif n.kind in frozenset(global_ops):
globs.add(n.pattr)
return globs

View File

@ -124,7 +124,8 @@ from spark_parser import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DE
from uncompyle6.scanner import Code, get_scanner
import uncompyle6.parser as python_parser
from uncompyle6.semantics.make_function import (
make_function2, make_function3, make_function3_annotate, find_globals)
make_function2, make_function3, make_function3_annotate,
find_globals)
from uncompyle6.semantics.parser_error import ParserError
from uncompyle6.semantics.check_ast import checker
from uncompyle6.semantics.helper import print_docstring
@ -2183,6 +2184,8 @@ class SourceWalker(GenericASTTraversal, object):
# else:
# print ast[-1][-1]
# Add "global" declaration statements at the top
# of the function
for g in find_globals(ast, set()):
self.println(indent, 'global ', g)