Skip to content

Commit af70eb9

Browse files
committed
Adjust test expectations for lcov reports generated under PyPy 3.8.
There is a bug somewhere, in which if we collect data in --branch mode under PyPy 3.8, regions for top-level functions come out of the analysis engine with empty lines arrays. The previous commit prevented this from crashing the lcov reporter; this commit adjusts the tests of the lcov reporter so that we expect the function records affected by the bug to be missing. I don’t think it’s worth trying to pin down the cause of the bug, since Python 3.8 is approaching end-of-life for both CPython and PyPy.
1 parent 347bf16 commit af70eb9

File tree

2 files changed

+129
-78
lines changed

2 files changed

+129
-78
lines changed

coverage/lcovreport.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ def lcov_functions(
6363
# We continue to generate the old format because we don't know what
6464
# version of the lcov tools will be used to read this report.
6565

66+
# "and region.lines" below avoids a crash due to a bug in PyPy 3.8
67+
# where, for whatever reason, when collecting data in --branch mode,
68+
# top-level functions have an empty lines array. Instead we just don't
69+
# emit function records for those.
70+
6671
# suppressions because of https://github.com/pylint-dev/pylint/issues/9923
6772
functions = [
6873
(min(region.start, min(region.lines)), #pylint: disable=nested-min-max

tests/test_lcov.py

Lines changed: 124 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@
1111
from tests.coveragetest import CoverageTest
1212

1313
import coverage
14+
from coverage import env
15+
16+
17+
def fn_coverage_missing_in_pypy_38(
18+
line_records: str,
19+
fn_records: str,
20+
arc_records: str,
21+
) -> str:
22+
"""
23+
Helper for tests that trip a bug in PyPy 3.8 that prevent us from
24+
generating function coverage records for top-level functions when
25+
coverage data was collected in --branch mode. See lcov_functions
26+
in lcovreport.py for more detail.
27+
"""
28+
if env.PYPY and env.PYVERSION[:2] == (3, 8):
29+
return line_records + arc_records
30+
else:
31+
return line_records + fn_records + arc_records
1432

1533

1634
class LcovTest(CoverageTest):
@@ -174,24 +192,30 @@ def is_it_x(x):
174192
pct = cov.lcov_report()
175193
assert math.isclose(pct, 16.666666666666668)
176194
self.assert_exists("coverage.lcov")
177-
expected_result = textwrap.dedent("""\
178-
SF:main_file.py
179-
DA:1,1
180-
DA:2,0
181-
DA:3,0
182-
DA:5,0
183-
LF:4
184-
LH:1
185-
FN:1,5,is_it_x
186-
FNDA:0,is_it_x
187-
FNF:1
188-
FNH:0
189-
BRDA:2,0,to line 3,-
190-
BRDA:2,0,to line 5,-
191-
BRF:2
192-
BRH:0
193-
end_of_record
194-
""")
195+
expected_result = fn_coverage_missing_in_pypy_38(
196+
textwrap.dedent("""\
197+
SF:main_file.py
198+
DA:1,1
199+
DA:2,0
200+
DA:3,0
201+
DA:5,0
202+
LF:4
203+
LH:1
204+
"""),
205+
textwrap.dedent("""\
206+
FN:1,5,is_it_x
207+
FNDA:0,is_it_x
208+
FNF:1
209+
FNH:0
210+
"""),
211+
textwrap.dedent("""\
212+
BRDA:2,0,to line 3,-
213+
BRDA:2,0,to line 5,-
214+
BRF:2
215+
BRH:0
216+
end_of_record
217+
""")
218+
)
195219
actual_result = self.get_lcov_report_content()
196220
assert expected_result == actual_result
197221

@@ -221,23 +245,33 @@ def test_is_it_x(self):
221245
pct = cov.lcov_report()
222246
assert math.isclose(pct, 41.666666666666664)
223247
self.assert_exists("coverage.lcov")
224-
expected_result = textwrap.dedent("""\
225-
SF:main_file.py
226-
DA:1,1
227-
DA:2,0
228-
DA:3,0
229-
DA:5,0
230-
LF:4
231-
LH:1
232-
FN:1,5,is_it_x
233-
FNDA:0,is_it_x
234-
FNF:1
235-
FNH:0
236-
BRDA:2,0,to line 3,-
237-
BRDA:2,0,to line 5,-
238-
BRF:2
239-
BRH:0
240-
end_of_record
248+
# The pypy 3.8 bug that prevents us from generating function coverage
249+
# records only applies to top-level functions, not to member functions.
250+
expected_result = fn_coverage_missing_in_pypy_38(
251+
textwrap.dedent("""\
252+
SF:main_file.py
253+
DA:1,1
254+
DA:2,0
255+
DA:3,0
256+
DA:5,0
257+
LF:4
258+
LH:1
259+
"""),
260+
textwrap.dedent("""\
261+
FN:1,5,is_it_x
262+
FNDA:0,is_it_x
263+
FNF:1
264+
FNH:0
265+
"""),
266+
textwrap.dedent("""\
267+
BRDA:2,0,to line 3,-
268+
BRDA:2,0,to line 5,-
269+
BRF:2
270+
BRH:0
271+
end_of_record
272+
""")
273+
)
274+
expected_result += textwrap.dedent("""\
241275
SF:test_file.py
242276
DA:1,1
243277
DA:2,1
@@ -371,27 +405,33 @@ def foo(a):
371405
cov = coverage.Coverage(source=".", branch=True)
372406
self.start_import_stop(cov, "runme")
373407
cov.lcov_report()
374-
expected_result = textwrap.dedent("""\
375-
SF:runme.py
376-
DA:1,1
377-
DA:2,1
378-
DA:3,1
379-
DA:4,1
380-
DA:5,1
381-
DA:6,1
382-
DA:7,1
383-
LF:7
384-
LH:7
385-
FN:1,3,foo
386-
FNDA:1,foo
387-
FNF:1
388-
FNH:1
389-
BRDA:2,0,to line 3,1
390-
BRDA:2,0,to exit,1
391-
BRF:2
392-
BRH:2
393-
end_of_record
394-
""")
408+
expected_result = fn_coverage_missing_in_pypy_38(
409+
textwrap.dedent("""\
410+
SF:runme.py
411+
DA:1,1
412+
DA:2,1
413+
DA:3,1
414+
DA:4,1
415+
DA:5,1
416+
DA:6,1
417+
DA:7,1
418+
LF:7
419+
LH:7
420+
"""),
421+
textwrap.dedent("""\
422+
FN:1,3,foo
423+
FNDA:1,foo
424+
FNF:1
425+
FNH:1
426+
"""),
427+
textwrap.dedent("""\
428+
BRDA:2,0,to line 3,1
429+
BRDA:2,0,to exit,1
430+
BRF:2
431+
BRH:2
432+
end_of_record
433+
"""),
434+
)
395435
actual_result = self.get_lcov_report_content()
396436
assert expected_result == actual_result
397437

@@ -408,27 +448,33 @@ def foo(a):
408448
cov = coverage.Coverage(source=".", branch=True)
409449
self.start_import_stop(cov, "runme")
410450
cov.lcov_report()
411-
expected_result = textwrap.dedent("""\
412-
SF:runme.py
413-
DA:1,1
414-
DA:2,1
415-
DA:3,1
416-
DA:4,1
417-
DA:5,1
418-
DA:6,1
419-
DA:7,1
420-
LF:7
421-
LH:7
422-
FN:1,3,foo
423-
FNDA:1,foo
424-
FNF:1
425-
FNH:1
426-
BRDA:2,0,to line 3,1
427-
BRDA:2,0,to exit 1,1
428-
BRDA:2,0,to exit 2,1
429-
BRF:2
430-
BRH:2
431-
end_of_record
432-
""")
451+
expected_result = fn_coverage_missing_in_pypy_38(
452+
textwrap.dedent("""\
453+
SF:runme.py
454+
DA:1,1
455+
DA:2,1
456+
DA:3,1
457+
DA:4,1
458+
DA:5,1
459+
DA:6,1
460+
DA:7,1
461+
LF:7
462+
LH:7
463+
"""),
464+
textwrap.dedent("""\
465+
FN:1,3,foo
466+
FNDA:1,foo
467+
FNF:1
468+
FNH:1
469+
"""),
470+
textwrap.dedent("""\
471+
BRDA:2,0,to line 3,1
472+
BRDA:2,0,to exit 1,1
473+
BRDA:2,0,to exit 2,1
474+
BRF:2
475+
BRH:2
476+
end_of_record
477+
"""),
478+
)
433479
actual_result = self.get_lcov_report_content()
434480
assert expected_result == actual_result

0 commit comments

Comments
 (0)