diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2017-10-10 21:38:44 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2017-10-10 21:42:12 +0200 |
commit | 2ad640d157e35c1c4cee567a805fc6cc268640bd (patch) | |
tree | 1b1e6643887aa5f6c928bc601ee9011f622f3d3a | |
parent | 14971192192279eafea138465b48b4272158529f (diff) | |
download | cython-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.py | 1 | ||||
-rw-r--r-- | tests/run/listcomp.pyx | 51 |
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") |