Permalink
Browse files

Merge remote-tracking branch 'main/0.17' into bugs

  • Loading branch information...
2 parents 402dc50 + a1d5c02 commit 15dce27569dd7624671964ad37d46810f3444ee7 @robertwb robertwb committed Nov 9, 2012
@@ -3117,11 +3117,30 @@ def visit_IfStatNode(self, node):
break
else:
assert condition_result == False
+ # prevent killing generators, but simplify them as much as possible
+ yield_expr = self._find_genexpr_yield(if_clause.body)
+ if yield_expr is not None:
+ if_clause.condition = ExprNodes.BoolNode(if_clause.condition.pos, value=False)
+ yield_expr.arg = ExprNodes.NoneNode(yield_expr.arg.pos)
+ if_clauses.append(if_clause)
+ else:
+ # False clauses outside of generators can safely be deleted
+ pass
if not if_clauses:
return node.else_clause
node.if_clauses = if_clauses
return node
+ def _find_genexpr_yield(self, node):
+ body_node_types = (Nodes.ForInStatNode, Nodes.IfStatNode)
+ while isinstance(node, body_node_types):
+ node = node.body
+ if isinstance(node, Nodes.ExprStatNode):
+ node = node.expr
+ if isinstance(node, ExprNodes.YieldExprNode):
+ return node
+ return None
+
# in the future, other nodes can have their own handler method here
# that can replace them with a constant result node
@@ -1569,7 +1569,7 @@ def declare_var(self, name, type, pos,
type = outer_entry.type # may still be 'unspecified_type' !
# the parent scope needs to generate code for the variable, but
# this scope must hold its name exclusively
- cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name))
+ cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name or self.next_id()))
entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1
self.var_entries.append(entry)
@@ -21,6 +21,16 @@ def genexpr_if():
assert x == 'abc' # don't leak
return result
+def genexpr_if_false():
+ """
+ >>> genexpr_if_false()
+ []
+ """
+ x = 'abc'
+ result = list( x*2 for x in range(5) if False )
+ assert x == 'abc' # don't leak
+ return result
+
def genexpr_with_lambda():
"""
>>> genexpr_with_lambda()
@@ -0,0 +1,74 @@
+# mode: run
+# cython: language_level=3
+
+"""
+Adapted from CPython's test_grammar.py
+"""
+
+def genexpr_simple():
+ """
+ >>> sum([ x**2 for x in range(10) ])
+ 285
+ >>> sum(genexpr_simple())
+ 285
+ """
+ return (x**2 for x in range(10))
+
+def genexpr_conditional():
+ """
+ >>> sum([ x*x for x in range(10) if x%2 ])
+ 165
+ >>> sum(genexpr_conditional())
+ 165
+ """
+ return (x*x for x in range(10) if x%2)
+
+def genexpr_nested2():
+ """
+ >>> sum([x for x in range(10)])
+ 45
+ >>> sum(genexpr_nested2())
+ 45
+ """
+ return (x for x in (y for y in range(10)))
+
+def genexpr_nested3():
+ """
+ >>> sum([x for x in range(10)])
+ 45
+ >>> sum(genexpr_nested3())
+ 45
+ """
+ return (x for x in (y for y in (z for z in range(10))))
+
+def genexpr_nested_listcomp():
+ """
+ >>> sum([x for x in range(10)])
+ 45
+ >>> sum(genexpr_nested_listcomp())
+ 45
+ """
+ return (x for x in [y for y in (z for z in range(10))])
+
+def genexpr_nested_conditional():
+ """
+ >>> sum([ x for x in [y for y in [z for z in range(10) if True]] if True ])
+ 45
+ >>> sum(genexpr_nested_conditional())
+ 45
+ """
+ return (x for x in (y for y in (z for z in range(10) if True)) if True)
+
+def genexpr_nested2_conditional_empty():
+ """
+ >>> sum(genexpr_nested2_conditional_empty())
+ 0
+ """
+ return (y for y in (z for z in range(10) if True) if False)
+
+def genexpr_nested3_conditional_empty():
+ """
+ >>> sum(genexpr_nested3_conditional_empty())
+ 0
+ """
+ return (x for x in (y for y in (z for z in range(10) if True) if False) if True)

0 comments on commit 15dce27

Please sign in to comment.