Skip to content

Commit 8208a37

Browse files
authored
Merge pull request #5361 from asottile/backport_5360
[4.6] Fix all() unroll for non-generators/non-list comprehensions (#5360)
2 parents dba62f8 + f078984 commit 8208a37

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

changelog/5358.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix assertion rewriting of ``all()`` calls to deal with non-generators.

src/_pytest/assertion/rewrite.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -949,11 +949,21 @@ def visit_BinOp(self, binop):
949949
res = self.assign(ast.BinOp(left_expr, binop.op, right_expr))
950950
return res, explanation
951951

952+
@staticmethod
953+
def _is_any_call_with_generator_or_list_comprehension(call):
954+
"""Return True if the Call node is an 'any' call with a generator or list comprehension"""
955+
return (
956+
isinstance(call.func, ast.Name)
957+
and call.func.id == "all"
958+
and len(call.args) == 1
959+
and isinstance(call.args[0], (ast.GeneratorExp, ast.ListComp))
960+
)
961+
952962
def visit_Call_35(self, call):
953963
"""
954964
visit `ast.Call` nodes on Python3.5 and after
955965
"""
956-
if isinstance(call.func, ast.Name) and call.func.id == "all":
966+
if self._is_any_call_with_generator_or_list_comprehension(call):
957967
return self._visit_all(call)
958968
new_func, func_expl = self.visit(call.func)
959969
arg_expls = []
@@ -980,8 +990,6 @@ def visit_Call_35(self, call):
980990

981991
def _visit_all(self, call):
982992
"""Special rewrite for the builtin all function, see #5062"""
983-
if not isinstance(call.args[0], (ast.GeneratorExp, ast.ListComp)):
984-
return
985993
gen_exp = call.args[0]
986994
assertion_module = ast.Module(
987995
body=[ast.Assert(test=gen_exp.elt, lineno=1, msg="", col_offset=1)]
@@ -1009,7 +1017,7 @@ def visit_Call_legacy(self, call):
10091017
"""
10101018
visit `ast.Call nodes on 3.4 and below`
10111019
"""
1012-
if isinstance(call.func, ast.Name) and call.func.id == "all":
1020+
if self._is_any_call_with_generator_or_list_comprehension(call):
10131021
return self._visit_all(call)
10141022
new_func, func_expl = self.visit(call.func)
10151023
arg_expls = []

testing/test_assertrewrite.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ def __repr__(self):
677677
assert "UnicodeDecodeError" not in msg
678678
assert "UnicodeEncodeError" not in msg
679679

680-
def test_unroll_generator(self, testdir):
680+
def test_unroll_all_generator(self, testdir):
681681
testdir.makepyfile(
682682
"""
683683
def check_even(num):
@@ -692,7 +692,7 @@ def test_generator():
692692
result = testdir.runpytest()
693693
result.stdout.fnmatch_lines(["*assert False*", "*where False = check_even(1)*"])
694694

695-
def test_unroll_list_comprehension(self, testdir):
695+
def test_unroll_all_list_comprehension(self, testdir):
696696
testdir.makepyfile(
697697
"""
698698
def check_even(num):
@@ -707,6 +707,31 @@ def test_list_comprehension():
707707
result = testdir.runpytest()
708708
result.stdout.fnmatch_lines(["*assert False*", "*where False = check_even(1)*"])
709709

710+
def test_unroll_all_object(self, testdir):
711+
"""all() for non generators/non list-comprehensions (#5358)"""
712+
testdir.makepyfile(
713+
"""
714+
def test():
715+
assert all((1, 0))
716+
"""
717+
)
718+
result = testdir.runpytest()
719+
result.stdout.fnmatch_lines(["*assert False*", "*where False = all((1, 0))*"])
720+
721+
def test_unroll_all_starred(self, testdir):
722+
"""all() for non generators/non list-comprehensions (#5358)"""
723+
testdir.makepyfile(
724+
"""
725+
def test():
726+
x = ((1, 0),)
727+
assert all(*x)
728+
"""
729+
)
730+
result = testdir.runpytest()
731+
result.stdout.fnmatch_lines(
732+
["*assert False*", "*where False = all(*((1, 0),))*"]
733+
)
734+
710735
def test_for_loop(self, testdir):
711736
testdir.makepyfile(
712737
"""

0 commit comments

Comments
 (0)