Skip to content

Commit 6177af0

Browse files
emerybergerclaude
andcommitted
Fix --omit not working with --source (Issue #74)
The _add_unseen_source_files() method was adding all .py files from --source directories without checking --omit patterns. This caused files like __init__.py to appear in coverage reports even when --omit */__init__.py was specified. Fix: - Add omit parameter to Slipcover.__init__() - Check omit patterns in _add_unseen_source_files() before adding files - Pass omit patterns from __main__.py to Slipcover Fixes #74 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 03f0468 commit 6177af0

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

src/slipcover/__main__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,10 @@ def main():
226226
file_matcher.addOmit(o)
227227

228228

229+
omit_list = args.omit.split(',') if args.omit else None
229230
sci = sc.Slipcover(immediate=args.immediate,
230231
d_miss_threshold=args.threshold, branch=args.branch,
231-
disassemble=args.dis, source=args.source)
232+
disassemble=args.dis, source=args.source, omit=omit_list)
232233

233234

234235
if not args.dont_wrap_pytest:

src/slipcover/slipcover.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,14 @@ def both(f, field):
303303
class Slipcover:
304304
def __init__(self, immediate: bool = False,
305305
d_miss_threshold: int = 50, branch: bool = False,
306-
disassemble: bool = False, source: Optional[List[str]] = None):
306+
disassemble: bool = False, source: Optional[List[str]] = None,
307+
omit: Optional[List[str]] = None):
307308
self.immediate = immediate
308309
self.d_miss_threshold = d_miss_threshold
309310
self.branch = branch
310311
self.disassemble = disassemble
311312
self.source = source
313+
self.omit = omit
312314

313315
# mutex protecting this state
314316
self.lock = threading.RLock()
@@ -590,6 +592,23 @@ def deinstrument(self, co, lines: set) -> types.CodeType:
590592

591593
def _add_unseen_source_files(self, source: List[str]):
592594
import ast
595+
from fnmatch import fnmatch
596+
597+
# Prepare omit patterns (same logic as FileMatcher.addOmit)
598+
omit_patterns = []
599+
if self.omit:
600+
cwd = Path.cwd()
601+
for o in self.omit:
602+
if o.startswith('*'):
603+
omit_patterns.append(o)
604+
else:
605+
omit_patterns.append(str((cwd / o).resolve()))
606+
607+
def is_omitted(filepath: Path) -> bool:
608+
if not omit_patterns:
609+
return False
610+
filepath_str = str(filepath)
611+
return any(fnmatch(filepath_str, p) for p in omit_patterns)
593612

594613
dirs = [Path(d).resolve() for d in source]
595614

@@ -601,6 +620,8 @@ def _add_unseen_source_files(self, source: List[str]):
601620

602621
elif file.is_file() and file.suffix.lower() == '.py':
603622
file = file.absolute()
623+
if is_omitted(file):
624+
continue
604625
filename = str(file)
605626
try:
606627
if filename not in self.code_lines:

0 commit comments

Comments
 (0)