summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2017-10-10 21:38:44 +0200
committerStefan Behnel <stefan_ml@behnel.de>2017-10-10 21:42:12 +0200
commit2ad640d157e35c1c4cee567a805fc6cc268640bd (patch)
tree1b1e6643887aa5f6c928bc601ee9011f622f3d3a
parent14971192192279eafea138465b48b4272158529f (diff)
downloadcython-2ad640d157e35c1c4cee567a805fc6cc268640bd.tar.gz
Remove overambitious constant folding of comprehensions when they occur in a boolean context. Never assume that they are empty, since the iteration might already have required side-effects.
Closes #1920.
-rw-r--r--Cython/Compiler/ExprNodes.py1
-rw-r--r--tests/run/listcomp.pyx51
2 files changed, 52 insertions, 0 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index 07060b309..cb3d3ab78 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -7983,6 +7983,7 @@ class ComprehensionNode(ScopedExprNode):
child_attrs = ["loop"]
is_temp = True
+ constant_result = not_a_constant
def infer_type(self, env):
return self.type
diff --git a/tests/run/listcomp.pyx b/tests/run/listcomp.pyx
index f301709fa..a143855bb 100644
--- a/tests/run/listcomp.pyx
+++ b/tests/run/listcomp.pyx
@@ -150,6 +150,57 @@ def listcomp_const_condition_false():
return [x*2 for x in range(3) if False]
+@cython.test_fail_if_path_exists("//IfStatNode",
+ "//ComprehensionAppendNode")
+@cython.test_assert_path_exists("//ComprehensionNode")
+def listcomp_const_condition_false_bool_test():
+ """
+ >>> listcomp_const_condition_false_bool_test()
+ True
+ """
+ return not [l for l in [1] if False]
+
+
+@cython.test_fail_if_path_exists("//IfStatNode",
+ "//ComprehensionAppendNode")
+@cython.test_assert_path_exists("//ComprehensionNode")
+def listcomp_const_condition_false_assert():
+ """
+ >>> listcomp_const_condition_false_assert()
+ """
+ assert not [l for l in [1] if False]
+
+
+@cython.test_fail_if_path_exists("//ComprehensionNode//IfStatNode",
+ "//ComprehensionAppendNode")
+@cython.test_assert_path_exists("//ComprehensionNode",
+ "//IfStatNode")
+def listcomp_const_condition_false_if():
+ """
+ >>> listcomp_const_condition_false_if()
+ True
+ """
+ if not [l for l in [1] if False]:
+ return True
+ return False
+
+
+@cython.test_fail_if_path_exists("//ComprehensionNode//IfStatNode",
+ "//ComprehensionAppendNode")
+@cython.test_assert_path_exists("//ComprehensionNode",
+ "//IfStatNode")
+def listcomp_const_condition_false_typed_error():
+ """
+ >>> listcomp_const_condition_false_typed_error() # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ TypeError: ...
+ """
+ cdef str l
+ if not [l for l in [1] if False]:
+ return True
+ return False
+
+
@cython.test_fail_if_path_exists("//IfStatNode")
@cython.test_assert_path_exists("//ComprehensionNode",
"//ComprehensionAppendNode")