@@ -62,7 +62,7 @@ def get_cython_build_rules():
6262
6363
6464@cache
65- def parse_all_cfile_lines ():
65+ def parse_all_cfile_lines (exclude_patterns = None ):
6666 """Parse all generated C files from the build directory."""
6767 #
6868 # Each .c file can include code generated from multiple Cython files (e.g.
@@ -80,7 +80,7 @@ def parse_all_cfile_lines():
8080
8181 for c_file , _ in get_cython_build_rules ():
8282
83- cfile_lines = parse_cfile_lines (c_file )
83+ cfile_lines = parse_cfile_lines (c_file , exclude_patterns = exclude_patterns )
8484
8585 for cython_file , line_map in cfile_lines .items ():
8686 if cython_file == '(tree fragment)' :
@@ -94,15 +94,22 @@ def parse_all_cfile_lines():
9494 return all_code_lines
9595
9696
97- def parse_cfile_lines (c_file ):
97+ def parse_cfile_lines (c_file , exclude_patterns = None ):
9898 """Use Cython's coverage plugin to parse the C code."""
9999 from Cython .Coverage import Plugin
100- return Plugin ()._parse_cfile_lines (c_file )
100+ p = Plugin ()
101+ p ._excluded_line_patterns = list (exclude_patterns )
102+ return p ._parse_cfile_lines (c_file )
101103
102104
103105class Plugin (CoveragePlugin ):
104106 """A coverage plugin for a spin/meson project with Cython code."""
105107
108+ def configure (self , config ):
109+ # Entry point for coverage "configurer".
110+ # Read the regular expressions from the coverage config that match lines to be excluded from coverage.
111+ self .exclude_patterns = tuple (config .get_option ("report:exclude_lines" ))
112+
106113 def file_tracer (self , filename ):
107114 """Find a tracer for filename to handle trace events."""
108115 path = Path (filename )
@@ -121,7 +128,7 @@ def file_tracer(self, filename):
121128 def file_reporter (self , filename ):
122129 """Return a file reporter for filename."""
123130 srcfile = Path (filename ).relative_to (src_dir )
124- return CyFileReporter (srcfile )
131+ return CyFileReporter (srcfile , exclude_patterns = self . exclude_patterns )
125132
126133
127134class CyFileTracer (FileTracer ):
@@ -157,14 +164,15 @@ def get_source_filename(filename):
157164class CyFileReporter (FileReporter ):
158165 """File reporter for Cython or Python files (.pyx,.pxd,.py)."""
159166
160- def __init__ (self , srcpath ):
167+ def __init__ (self , srcpath , exclude_patterns ):
161168 abspath = (src_dir / srcpath )
162169 assert abspath .exists ()
163170
164171 # filepath here needs to match dynamic_source_filename
165172 super ().__init__ (str (abspath ))
166173
167174 self .srcpath = srcpath
175+ self .exclude_patterns = exclude_patterns
168176
169177 def relative_filename (self ):
170178 """Path displayed in the coverage reports."""
@@ -173,7 +181,7 @@ def relative_filename(self):
173181 def lines (self ):
174182 """Set of line numbers for possibly traceable lines."""
175183 srcpath = str (self .srcpath )
176- all_line_maps = parse_all_cfile_lines ()
184+ all_line_maps = parse_all_cfile_lines (exclude_patterns = self . exclude_patterns )
177185 line_map = all_line_maps [srcpath ]
178186 return set (line_map )
179187
0 commit comments