[pypy-commit] pypy default: Fix issue 793 (thanks mistuhiko). Generally allow visit_sequence()
arigo
noreply at buildbot.pypy.org
Sun Jul 24 13:56:02 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r45934:4d416d3a6e38
Date: 2011-07-24 13:56 +0200
http://bitbucket.org/pypy/pypy/changeset/4d416d3a6e38/
Log: Fix issue 793 (thanks mistuhiko). Generally allow visit_sequence()
to be called on None.
diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -2541,6 +2541,7 @@
class ASTVisitor(object):
def visit_sequence(self, seq):
+ if seq is not None:
for node in seq:
node.walkabout(self)
@@ -2673,33 +2674,25 @@
class GenericASTVisitor(ASTVisitor):
def visit_Module(self, node):
- if node.body:
self.visit_sequence(node.body)
def visit_Interactive(self, node):
- if node.body:
self.visit_sequence(node.body)
def visit_Expression(self, node):
node.body.walkabout(self)
def visit_Suite(self, node):
- if node.body:
self.visit_sequence(node.body)
def visit_FunctionDef(self, node):
node.args.walkabout(self)
- if node.body:
self.visit_sequence(node.body)
- if node.decorator_list:
self.visit_sequence(node.decorator_list)
def visit_ClassDef(self, node):
- if node.bases:
self.visit_sequence(node.bases)
- if node.body:
self.visit_sequence(node.body)
- if node.decorator_list:
self.visit_sequence(node.decorator_list)
def visit_Return(self, node):
@@ -2707,11 +2700,9 @@
node.value.walkabout(self)
def visit_Delete(self, node):
- if node.targets:
self.visit_sequence(node.targets)
def visit_Assign(self, node):
- if node.targets:
self.visit_sequence(node.targets)
node.value.walkabout(self)
@@ -2722,36 +2713,28 @@
def visit_Print(self, node):
if node.dest:
node.dest.walkabout(self)
- if node.values:
self.visit_sequence(node.values)
def visit_For(self, node):
node.target.walkabout(self)
node.iter.walkabout(self)
- if node.body:
self.visit_sequence(node.body)
- if node.orelse:
self.visit_sequence(node.orelse)
def visit_While(self, node):
node.test.walkabout(self)
- if node.body:
self.visit_sequence(node.body)
- if node.orelse:
self.visit_sequence(node.orelse)
def visit_If(self, node):
node.test.walkabout(self)
- if node.body:
self.visit_sequence(node.body)
- if node.orelse:
self.visit_sequence(node.orelse)
def visit_With(self, node):
node.context_expr.walkabout(self)
if node.optional_vars:
node.optional_vars.walkabout(self)
- if node.body:
self.visit_sequence(node.body)
def visit_Raise(self, node):
@@ -2763,17 +2746,12 @@
node.tback.walkabout(self)
def visit_TryExcept(self, node):
- if node.body:
self.visit_sequence(node.body)
- if node.handlers:
self.visit_sequence(node.handlers)
- if node.orelse:
self.visit_sequence(node.orelse)
def visit_TryFinally(self, node):
- if node.body:
self.visit_sequence(node.body)
- if node.finalbody:
self.visit_sequence(node.finalbody)
def visit_Assert(self, node):
@@ -2782,11 +2760,9 @@
node.msg.walkabout(self)
def visit_Import(self, node):
- if node.names:
self.visit_sequence(node.names)
def visit_ImportFrom(self, node):
- if node.names:
self.visit_sequence(node.names)
def visit_Exec(self, node):
@@ -2812,7 +2788,6 @@
pass
def visit_BoolOp(self, node):
- if node.values:
self.visit_sequence(node.values)
def visit_BinOp(self, node):
@@ -2832,34 +2807,27 @@
node.orelse.walkabout(self)
def visit_Dict(self, node):
- if node.keys:
self.visit_sequence(node.keys)
- if node.values:
self.visit_sequence(node.values)
def visit_Set(self, node):
- if node.elts:
self.visit_sequence(node.elts)
def visit_ListComp(self, node):
node.elt.walkabout(self)
- if node.generators:
self.visit_sequence(node.generators)
def visit_SetComp(self, node):
node.elt.walkabout(self)
- if node.generators:
self.visit_sequence(node.generators)
def visit_DictComp(self, node):
node.key.walkabout(self)
node.value.walkabout(self)
- if node.generators:
self.visit_sequence(node.generators)
def visit_GeneratorExp(self, node):
node.elt.walkabout(self)
- if node.generators:
self.visit_sequence(node.generators)
def visit_Yield(self, node):
@@ -2868,14 +2836,11 @@
def visit_Compare(self, node):
node.left.walkabout(self)
- if node.comparators:
self.visit_sequence(node.comparators)
def visit_Call(self, node):
node.func.walkabout(self)
- if node.args:
self.visit_sequence(node.args)
- if node.keywords:
self.visit_sequence(node.keywords)
if node.starargs:
node.starargs.walkabout(self)
@@ -2902,11 +2867,9 @@
pass
def visit_List(self, node):
- if node.elts:
self.visit_sequence(node.elts)
def visit_Tuple(self, node):
- if node.elts:
self.visit_sequence(node.elts)
def visit_Const(self, node):
@@ -2924,7 +2887,6 @@
node.step.walkabout(self)
def visit_ExtSlice(self, node):
- if node.dims:
self.visit_sequence(node.dims)
def visit_Index(self, node):
@@ -2933,7 +2895,6 @@
def visit_comprehension(self, node):
node.target.walkabout(self)
node.iter.walkabout(self)
- if node.ifs:
self.visit_sequence(node.ifs)
def visit_ExceptHandler(self, node):
@@ -2941,13 +2902,10 @@
node.type.walkabout(self)
if node.name:
node.name.walkabout(self)
- if node.body:
self.visit_sequence(node.body)
def visit_arguments(self, node):
- if node.args:
self.visit_sequence(node.args)
- if node.defaults:
self.visit_sequence(node.defaults)
def visit_keyword(self, node):
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -295,15 +295,11 @@
def visit_FunctionDef(self, func):
self.update_position(func.lineno, True)
# Load decorators first, but apply them after the function is created.
- if func.decorator_list:
self.visit_sequence(func.decorator_list)
args = func.args
assert isinstance(args, ast.arguments)
- if args.defaults:
self.visit_sequence(args.defaults)
- num_defaults = len(args.defaults)
- else:
- num_defaults = 0
+ num_defaults = len(args.defaults) if args.defaults is not None else 0
code = self.sub_scope(FunctionCodeGenerator, func.name, func,
func.lineno)
self._make_function(code, num_defaults)
@@ -317,24 +313,17 @@
self.update_position(lam.lineno)
args = lam.args
assert isinstance(args, ast.arguments)
- if args.defaults:
self.visit_sequence(args.defaults)
- default_count = len(args.defaults)
- else:
- default_count = 0
+ default_count = len(args.defaults) if args.defaults is not None else 0
code = self.sub_scope(LambdaCodeGenerator, "<lambda>", lam, lam.lineno)
self._make_function(code, default_count)
def visit_ClassDef(self, cls):
self.update_position(cls.lineno, True)
- if cls.decorator_list:
self.visit_sequence(cls.decorator_list)
self.load_const(self.space.wrap(cls.name))
- if cls.bases:
- bases_count = len(cls.bases)
self.visit_sequence(cls.bases)
- else:
- bases_count = 0
+ bases_count = len(cls.bases) if cls.bases is not None else 0
self.emit_op_arg(ops.BUILD_TUPLE, bases_count)
code = self.sub_scope(ClassCodeGenerator, cls.name, cls, cls.lineno)
self._make_function(code, 0)
@@ -446,7 +435,6 @@
end = self.new_block()
test_constant = if_.test.as_constant_truth(self.space)
if test_constant == optimize.CONST_FALSE:
- if if_.orelse:
self.visit_sequence(if_.orelse)
elif test_constant == optimize.CONST_TRUE:
self.visit_sequence(if_.body)
@@ -515,7 +503,6 @@
self.use_next_block(cleanup)
self.emit_op(ops.POP_BLOCK)
self.pop_frame_block(F_BLOCK_LOOP, start)
- if fr.orelse:
self.visit_sequence(fr.orelse)
self.use_next_block(end)
@@ -523,7 +510,6 @@
self.update_position(wh.lineno, True)
test_constant = wh.test.as_constant_truth(self.space)
if test_constant == optimize.CONST_FALSE:
- if wh.orelse:
self.visit_sequence(wh.orelse)
else:
end = self.new_block()
@@ -544,7 +530,6 @@
self.use_next_block(anchor)
self.emit_op(ops.POP_BLOCK)
self.pop_frame_block(F_BLOCK_LOOP, loop)
- if wh.orelse:
self.visit_sequence(wh.orelse)
self.use_next_block(end)
@@ -581,7 +566,6 @@
self.use_next_block(next_except)
self.emit_op(ops.END_FINALLY)
self.use_next_block(otherwise)
- if te.orelse:
self.visit_sequence(te.orelse)
self.use_next_block(end)
@@ -893,26 +877,18 @@
def visit_Tuple(self, tup):
self.update_position(tup.lineno)
- if tup.elts:
- elt_count = len(tup.elts)
- else:
- elt_count = 0
+ elt_count = len(tup.elts) if tup.elts is not None else 0
if tup.ctx == ast.Store:
self.emit_op_arg(ops.UNPACK_SEQUENCE, elt_count)
- if elt_count:
self.visit_sequence(tup.elts)
if tup.ctx == ast.Load:
self.emit_op_arg(ops.BUILD_TUPLE, elt_count)
def visit_List(self, l):
self.update_position(l.lineno)
- if l.elts:
- elt_count = len(l.elts)
- else:
- elt_count = 0
+ elt_count = len(l.elts) if l.elts is not None else 0
if l.ctx == ast.Store:
self.emit_op_arg(ops.UNPACK_SEQUENCE, elt_count)
- if elt_count:
self.visit_sequence(l.elts)
if l.ctx == ast.Load:
self.emit_op_arg(ops.BUILD_LIST, elt_count)
@@ -944,10 +920,8 @@
if self._optimize_method_call(call):
return
call.func.walkabout(self)
- arg = 0
+ arg = len(call.args) if call.args is not None else 0
call_type = 0
- if call.args:
- arg = len(call.args)
self.visit_sequence(call.args)
if call.keywords:
self.visit_sequence(call.keywords)
@@ -984,16 +958,10 @@
assert isinstance(attr_lookup, ast.Attribute)
attr_lookup.value.walkabout(self)
self.emit_op_name(ops.LOOKUP_METHOD, self.names, attr_lookup.attr)
- if call.args:
self.visit_sequence(call.args)
- arg_count = len(call.args)
- else:
- arg_count = 0
- if call.keywords:
+ arg_count = len(call.args) if call.args is not None else 0
self.visit_sequence(call.keywords)
- kwarg_count = len(call.keywords)
- else:
- kwarg_count = 0
+ kwarg_count = len(call.keywords) if call.keywords is not None else 0
self.emit_op_arg(ops.CALL_METHOD, (kwarg_count << 8) | arg_count)
return True
diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -356,16 +356,11 @@
# Function defaults and decorators happen in the outer scope.
args = func.args
assert isinstance(args, ast.arguments)
- if args.defaults:
self.visit_sequence(args.defaults)
- if func.decorator_list:
self.visit_sequence(func.decorator_list)
new_scope = FunctionScope(func.name, func.lineno, func.col_offset)
self.push_scope(new_scope, func)
func.args.walkabout(self)
- # func.body should never be empty (or else it contains one Pass)
- # but it can be if we make an ast.FunctionDef() from app-level.
- if func.body:
self.visit_sequence(func.body)
self.pop_scope()
@@ -375,9 +370,7 @@
def visit_ClassDef(self, clsdef):
self.note_symbol(clsdef.name, SYM_ASSIGNED)
- if clsdef.bases:
self.visit_sequence(clsdef.bases)
- if clsdef.decorator_list:
self.visit_sequence(clsdef.decorator_list)
self.push_scope(ClassScope(clsdef), clsdef)
self.visit_sequence(clsdef.body)
@@ -434,7 +427,6 @@
def visit_Lambda(self, lamb):
args = lamb.args
assert isinstance(args, ast.arguments)
- if args.defaults:
self.visit_sequence(args.defaults)
new_scope = FunctionScope("lambda", lamb.lineno, lamb.col_offset)
self.push_scope(new_scope, lamb)
@@ -450,7 +442,6 @@
self.push_scope(new_scope, node)
self.implicit_arg(0)
outer.target.walkabout(self)
- if outer.ifs:
self.visit_sequence(outer.ifs)
self.visit_sequence(comps[1:])
for item in list(consider):
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -221,8 +221,9 @@
self.emit("class ASTVisitor(object):")
self.emit("")
self.emit("def visit_sequence(self, seq):", 1)
- self.emit("for node in seq:", 2)
- self.emit("node.walkabout(self)", 3)
+ self.emit("if seq is not None:", 2)
+ self.emit("for node in seq:", 3)
+ self.emit("node.walkabout(self)", 4)
self.emit("")
self.emit("def default_visitor(self, node):", 1)
self.emit("raise NodeVisitorNotImplemented", 2)
@@ -280,15 +281,13 @@
def visitField(self, field):
if field.type.value not in asdl.builtin_types and \
field.type.value not in self.data.simple_types:
- if field.seq or field.opt:
+ level = 2
+ template = "node.%s.walkabout(self)"
+ if field.seq:
+ template = "self.visit_sequence(node.%s)"
+ elif field.opt:
self.emit("if node.%s:" % (field.name,), 2)
level = 3
- else:
- level = 2
- if field.seq:
- template = "self.visit_sequence(node.%s)"
- else:
- template = "node.%s.walkabout(self)"
self.emit(template % (field.name,), level)
return True
return False
diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py
--- a/pypy/module/_ast/test/test_ast.py
+++ b/pypy/module/_ast/test/test_ast.py
@@ -274,3 +274,14 @@
n.name = "foo"
n.name = "foo"
assert n.name == "foo"
+
+ def test_issue793(self):
+ import _ast as ast
+ body = ast.Module([
+ ast.TryExcept([ast.Pass(lineno=2, col_offset=4)],
+ [ast.ExceptHandler(ast.Name('Exception', ast.Load(),
+ lineno=3, col_offset=0),
+ None, [], lineno=4, col_offset=0)],
+ [], lineno=1, col_offset=0)
+ ])
+ exec compile(body, '<string>', 'exec')
More information about the pypy-commit
mailing list