coveragepy: coverage of multiline generator/set/dict comprehensions is wrong when run with pytest's assertion rewriting
Originally reported by Andy Freeland (Bitbucket: rouge8, GitHub: rouge8)
Code/config to reproduce available as a gist. Fails on Python 2.7 but not Python 3.5.
Essentially, given this test:
def test_foo():
# covered!
assert {i for i in range(10)} == {i for i in range(10)}
# "didn't finish the set comprehension"
assert {i for i in range(10)} == {
i for i in range(10)
}
# covered!
assert True
When run under pytest with assertion rewriting (the default), the multiline set comprehension is reported as partially covered, even though the comprehension on oneline is fully covered. I think this is a bug in coverage, not pytest’s assertion rewriting, because this code passes:
import ast
from _pytest.assertion.rewrite import rewrite_asserts
oneline = """assert {i for i in range(10)} == {i for i in range(10)}"""
multiline = """assert {i for i in range(10)} == {
i for i in range(10)
}"""
# Parse the expressions
oneline_tree = ast.parse(oneline)
multiline_tree = ast.parse(multiline)
# Dump the pre-assertion rewrite ASTs
multiline_dump_prerewrite = ast.dump(multiline_tree)
oneline_dump_prerewrite = ast.dump(oneline_tree)
# The ASTs should be the same
assert multiline_dump_prerewrite == oneline_dump_prerewrite
# Rewrite the asserts
rewrite_asserts(oneline_tree)
rewrite_asserts(multiline_tree)
# Dump the rewritten ASTs
oneline_dump_rewrite = ast.dump(oneline_tree)
multiline_dump_rewrite = ast.dump(multiline_tree)
# The ASTs should be the same
assert oneline_dump_rewrite == multiline_dump_rewrite
About this issue
- Original URL
- State: open
- Created 8 years ago
- Comments: 26 (24 by maintainers)
We are about to revert the unroll functionality for
all()
as we have found a bunch of corner cases. We should release 4.6.2 later today.