Skip to content

Commit

Permalink
fix: sysmon should ignore GeneratorExit
Browse files Browse the repository at this point in the history
Also, don't use dis in production, it's changed often.
  • Loading branch information
nedbat committed Jan 12, 2024
1 parent 159f67f commit 58586e5
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 16 deletions.
23 changes: 12 additions & 11 deletions coverage/sysmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from __future__ import annotations

import dataclasses
import dis
import functools
import inspect
import os
Expand Down Expand Up @@ -168,12 +167,10 @@ class CodeInfo:
def bytes_to_lines(code: CodeType) -> Dict[int, int]:
"""Make a dict mapping byte code offsets to line numbers."""
b2l = {}
cur_line = 0
for inst in dis.get_instructions(code):
if inst.starts_line is not None:
cur_line = inst.starts_line
b2l[inst.offset] = cur_line
log(f" --> bytes_to_lines: {b2l!r}")
for bstart, bend, lineno in code.co_lines():
if lineno is not None:
for boffset in range(bstart, bend, 2):
b2l[boffset] = lineno
return b2l


Expand Down Expand Up @@ -379,26 +376,30 @@ def sysmon_py_return_arcs(
last_line = self.last_lines.get(frame)
if last_line is not None:
arc = (last_line, -code.co_firstlineno)
# log(f"adding {arc=}")
cast(Set[TArc], code_info.file_data).add(arc)

# Leaving this function, no need for the frame any more.
self.last_lines.pop(frame, None)

@panopticon("code", "@", None)
@panopticon("code", "@", "exc")
def sysmon_py_unwind_arcs(
self, code: CodeType, instruction_offset: int, exception: BaseException
) -> MonitorReturn:
"""Handle sys.monitoring.events.PY_UNWIND events for branch coverage."""
frame = self.callers_frame()
# Leaving this function.
last_line = self.last_lines.pop(frame, None)
if isinstance(exception, GeneratorExit):
# We don't want to count generator exits as arcs.
return
code_info = self.code_infos.get(id(code))
if code_info is not None and code_info.file_data is not None:
last_line = self.last_lines.get(frame)
if last_line is not None:
arc = (last_line, -code.co_firstlineno)
# log(f"adding {arc=}")
cast(Set[TArc], code_info.file_data).add(arc)

# Leaving this function.
self.last_lines.pop(frame, None)

@panopticon("code", "line")
def sysmon_line_lines(self, code: CodeType, line_number: int) -> MonitorReturn:
Expand Down
3 changes: 0 additions & 3 deletions tests/test_arcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import pytest

from tests import testenv
from tests.coveragetest import CoverageTest
from tests.helpers import assert_count_equal, xfail_pypy38

Expand Down Expand Up @@ -1308,7 +1307,6 @@ def gen(inp):
arcz=".1 19 9. .2 23 34 45 56 63 37 7.",
)

@pytest.mark.xfail(testenv.SYS_MON, reason="TODO: fix this for sys.monitoring")
def test_abandoned_yield(self) -> None:
# https://github.com/nedbat/coveragepy/issues/440
self.check_coverage("""\
Expand Down Expand Up @@ -1651,7 +1649,6 @@ def test_pathologically_long_code_object(self, n: int) -> None:
self.check_coverage(code, arcs=[(-1, 1), (1, 2*n+4), (2*n+4, -1)])
assert self.stdout() == f"{n}\n"

@pytest.mark.xfail(testenv.SYS_MON, reason="TODO: fix this for sys.monitoring")
def test_partial_generators(self) -> None:
# https://github.com/nedbat/coveragepy/issues/475
# Line 2 is executed completely.
Expand Down
2 changes: 0 additions & 2 deletions tests/test_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from coverage import env
from coverage.exceptions import NoDataError

from tests import testenv
from tests.coveragetest import CoverageTest


Expand Down Expand Up @@ -1407,7 +1406,6 @@ def test_excluding_try_except_stranded_else(self) -> None:
arcz_missing=arcz_missing,
)

@pytest.mark.xfail(testenv.SYS_MON, reason="TODO: fix this for sys.monitoring")
def test_excluded_comprehension_branches(self) -> None:
# https://github.com/nedbat/coveragepy/issues/1271
self.check_coverage("""\
Expand Down

0 comments on commit 58586e5

Please sign in to comment.