Commit 469db401 authored by Stefan Behnel's avatar Stefan Behnel

strip down for-in-loops with empty iterables

parent 4cfaa9f6
......@@ -3235,8 +3235,15 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
def visit_ForInStatNode(self, node):
self.visitchildren(node)
# iterating over a list literal? => tuples are more efficient
sequence = node.iterator.sequence
if isinstance(sequence, ExprNodes.SequenceNode):
if not sequence.args:
if node.else_clause:
return node.else_clause
else:
# don't break list comprehensions
return Nodes.StatListNode(node.pos, stats=[])
# iterating over a list literal? => tuples are more efficient
if isinstance(sequence, ExprNodes.ListNode):
node.iterator.sequence = sequence.as_tuple()
return node
......
......@@ -185,3 +185,71 @@ def while_true():
return True
else:
print("FAIL")
@cython.test_fail_if_path_exists(
"//ForInStatNode",
)
def for_in_empty():
"""
>>> for_in_empty()
"""
for i in []:
print("LOOP")
@cython.test_fail_if_path_exists(
"//ForInStatNode",
)
def for_in_empty_else():
"""
>>> for_in_empty_else()
True
"""
for i in []:
print("LOOP")
else:
return True
@cython.test_fail_if_path_exists(
"//ForInStatNode",
)
@cython.test_assert_path_exists(
"//ComprehensionNode",
)
def for_in_empty_listcomp():
"""
>>> for_in_empty_listcomp()
[]
"""
return [i for i in []]
@cython.test_fail_if_path_exists(
"//ForInStatNode",
)
@cython.test_assert_path_exists(
"//ComprehensionNode",
)
def for_in_empty_nested_listcomp():
"""
>>> for_in_empty_nested_listcomp()
[]
"""
return [x for _ in [] for x in [1, 2, 3]]
@cython.test_fail_if_path_exists(
"//ForInStatNode//ForInStatNode",
)
@cython.test_assert_path_exists(
"//ForInStatNode",
"//ComprehensionNode",
)
def for_in_nested_listcomp():
"""
>>> for_in_nested_listcomp()
[]
"""
return [x for x in [1, 2, 3] for _ in []]
......@@ -80,3 +80,20 @@ def unicode_slicing_safe_surrogates2():
"""
ustring = u'abc\U00010000def'[:2]
return ustring
@cython.test_fail_if_path_exists(
"//ForInStatNode",
)
@cython.test_assert_path_exists(
"//ComprehensionNode",
)
def for_in_empty_setcomp():
"""
>>> s = for_in_empty_setcomp()
>>> isinstance(s, set)
True
>>> len(s)
0
"""
return {i for i in []}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment