0
# Data Storage and Retrieval
1
2
Coverage data storage, querying, and manipulation through the CoverageData class. Handles persistence of execution data, context information, and provides query interfaces for analysis and reporting.
3
4
## Capabilities
5
6
### CoverageData Class Constructor
7
8
Creates a CoverageData instance for managing coverage data storage and retrieval.
9
10
```python { .api }
11
class CoverageData:
12
def __init__(
13
self,
14
basename=None, # Base name for data file
15
suffix=None, # Suffix for data file name
16
warn=None, # Warning function
17
debug=None, # Debug control function
18
no_disk=False # Operate entirely in memory
19
):
20
"""
21
Create a CoverageData instance for data storage and retrieval.
22
23
Parameters:
24
- basename (str | None): Base name for the data file, default '.coverage'
25
- suffix (str | bool | None): Suffix for parallel data files
26
- warn (callable | None): Function to call with warning messages
27
- debug (callable | None): Function for debugging output
28
- no_disk (bool): If True, operate entirely in memory without file I/O
29
"""
30
```
31
32
Usage example:
33
34
```python
35
from coverage.data import CoverageData
36
37
# Basic usage
38
data = CoverageData()
39
40
# Custom configuration
41
data = CoverageData(
42
basename='my_coverage',
43
suffix='worker_1',
44
no_disk=False
45
)
46
47
# In-memory only
48
memory_data = CoverageData(no_disk=True)
49
```
50
51
### Data Access Methods
52
53
Query coverage data for files, lines, arcs, and context information.
54
55
```python { .api }
56
def measured_files(self) -> set[str]:
57
"""
58
Get the set of files that have been measured.
59
60
Returns:
61
set[str]: Set of absolute file paths that have coverage data
62
"""
63
64
def lines(self, filename: str) -> list[int] | None:
65
"""
66
Get executed line numbers for a specific file.
67
68
Parameters:
69
- filename (str): Path to the file
70
71
Returns:
72
list[int] | None: List of executed line numbers, or None if file not measured
73
"""
74
75
def arcs(self, filename: str) -> list[tuple[int, int]] | None:
76
"""
77
Get executed arcs (branch pairs) for a specific file.
78
79
Parameters:
80
- filename (str): Path to the file
81
82
Returns:
83
list[tuple[int, int]] | None: List of (from_line, to_line) arcs, or None if file not measured
84
"""
85
86
def contexts_by_lineno(self, filename: str) -> dict[int, list[str]]:
87
"""
88
Get context labels for each line number in a file.
89
90
Parameters:
91
- filename (str): Path to the file
92
93
Returns:
94
dict[int, list[str]]: Mapping of line numbers to context label lists
95
"""
96
97
def file_tracer(self, filename: str) -> str | None:
98
"""
99
Get the file tracer name used for a specific file.
100
101
Parameters:
102
- filename (str): Path to the file
103
104
Returns:
105
str | None: File tracer name, or None if no tracer used
106
"""
107
108
def has_arcs(self) -> bool:
109
"""
110
Check if the data includes branch coverage information.
111
112
Returns:
113
bool: True if branch coverage data is present
114
"""
115
```
116
117
Usage example:
118
119
```python
120
from coverage.data import CoverageData
121
122
data = CoverageData()
123
data.read() # Load from file
124
125
# Query measured files
126
files = data.measured_files()
127
print(f"Measured {len(files)} files")
128
129
# Get line coverage for a file
130
lines = data.lines('src/my_module.py')
131
if lines:
132
print(f"Executed lines: {sorted(lines)}")
133
134
# Check for branch coverage
135
if data.has_arcs():
136
arcs = data.arcs('src/my_module.py')
137
print(f"Executed arcs: {arcs}")
138
139
# Get context information
140
contexts = data.contexts_by_lineno('src/my_module.py')
141
for line, ctx_list in contexts.items():
142
print(f"Line {line}: contexts {ctx_list}")
143
```
144
145
### Data Persistence Methods
146
147
Read, write, and manage coverage data files.
148
149
```python { .api }
150
def read(self) -> None:
151
"""
152
Read coverage data from the data file.
153
154
Loads data from the file specified during construction.
155
"""
156
157
def write(self) -> None:
158
"""
159
Write coverage data to the data file.
160
161
Saves current data to the file specified during construction.
162
"""
163
164
def erase(self, parallel: bool = False) -> None:
165
"""
166
Delete the data file.
167
168
Parameters:
169
- parallel (bool): If True, also erase parallel data files
170
"""
171
```
172
173
Usage example:
174
175
```python
176
from coverage.data import CoverageData
177
178
# Create and populate data
179
data = CoverageData()
180
181
# Load existing data
182
data.read()
183
184
# Make modifications...
185
# data.update(other_data)
186
187
# Save changes
188
data.write()
189
190
# Clean up
191
data.erase()
192
```
193
194
### Data Modification Methods
195
196
Update and modify coverage data programmatically.
197
198
```python { .api }
199
def update(
200
self,
201
other_data,
202
map_path=None
203
) -> None:
204
"""
205
Merge coverage data from another CoverageData instance.
206
207
Parameters:
208
- other_data (CoverageData): Another CoverageData instance to merge
209
- map_path (callable | None): Function to map file paths during merge
210
"""
211
212
def touch_files(
213
self,
214
filenames,
215
plugin_name: str = ""
216
) -> None:
217
"""
218
Mark files as measured without adding execution data.
219
220
Parameters:
221
- filenames (Iterable[str]): Files to mark as measured
222
- plugin_name (str): Name of plugin that measured the files
223
"""
224
```
225
226
Usage example:
227
228
```python
229
from coverage.data import CoverageData
230
231
# Combine data from multiple sources
232
main_data = CoverageData('main.coverage')
233
main_data.read()
234
235
worker_data = CoverageData('worker.coverage')
236
worker_data.read()
237
238
# Merge worker data into main data
239
main_data.update(worker_data)
240
241
# Mark additional files as measured
242
main_data.touch_files(['src/config.py', 'src/utils.py'])
243
244
# Save combined data
245
main_data.write()
246
```
247
248
### Query Control Methods
249
250
Control how data queries are filtered and processed.
251
252
```python { .api }
253
def set_query_contexts(self, contexts: list[str] | None) -> None:
254
"""
255
Set context filter for subsequent data queries.
256
257
Parameters:
258
- contexts (list[str] | None): Context labels to filter by, or None for no filter
259
"""
260
```
261
262
Usage example:
263
264
```python
265
from coverage.data import CoverageData
266
267
data = CoverageData()
268
data.read()
269
270
# Filter queries to specific contexts
271
data.set_query_contexts(['test_module_a', 'test_module_b'])
272
273
# Now queries only return data from those contexts
274
lines = data.lines('src/my_module.py') # Only lines from specified contexts
275
276
# Remove filter
277
data.set_query_contexts(None)
278
```
279
280
### Debugging Methods
281
282
Debug and inspect coverage data for troubleshooting.
283
284
```python { .api }
285
@classmethod
286
def sys_info(cls) -> list[tuple[str, Any]]:
287
"""
288
Return system information about the data storage.
289
290
Returns:
291
list[tuple[str, Any]]: System information key-value pairs
292
"""
293
```
294
295
Usage example:
296
297
```python
298
from coverage.data import CoverageData
299
300
# Get system information
301
info = CoverageData.sys_info()
302
for key, value in info:
303
print(f"{key}: {value}")
304
```
305
306
## Utility Functions
307
308
Module-level utility functions for working with coverage data.
309
310
```python { .api }
311
def line_counts(data: CoverageData, fullpath: bool = False) -> dict[str, int]:
312
"""
313
Get a summary of line counts from coverage data.
314
315
Parameters:
316
- data (CoverageData): Coverage data instance
317
- fullpath (bool): If True, use full paths as keys; otherwise use basenames
318
319
Returns:
320
dict[str, int]: Mapping of filenames to executed line counts
321
"""
322
323
def add_data_to_hash(data: CoverageData, filename: str, hasher) -> None:
324
"""
325
Add file coverage data to a hash for fingerprinting.
326
327
Parameters:
328
- data (CoverageData): Coverage data instance
329
- filename (str): File to add to hash
330
- hasher: Hash object with update() method
331
"""
332
333
def combinable_files(data_file: str, data_paths=None) -> list[str]:
334
"""
335
List data files that can be combined with a main data file.
336
337
Parameters:
338
- data_file (str): Path to main data file
339
- data_paths (list[str] | None): Additional paths to search
340
341
Returns:
342
list[str]: List of combinable data file paths
343
"""
344
345
def combine_parallel_data(
346
data: CoverageData,
347
aliases=None,
348
data_paths=None,
349
strict: bool = False,
350
keep: bool = False,
351
message=None
352
) -> None:
353
"""
354
Combine multiple parallel coverage data files.
355
356
Parameters:
357
- data (CoverageData): Main data instance to combine into
358
- aliases: Path aliases for file mapping
359
- data_paths (list[str] | None): Paths to search for data files
360
- strict (bool): Raise error if no data files found
361
- keep (bool): Keep original data files after combining
362
- message (callable | None): Function to display progress messages
363
"""
364
```
365
366
Usage example:
367
368
```python
369
from coverage.data import CoverageData, line_counts, combine_parallel_data
370
371
# Get line count summary
372
data = CoverageData()
373
data.read()
374
375
counts = line_counts(data, fullpath=True)
376
for filename, count in counts.items():
377
print(f"{filename}: {count} lines executed")
378
379
# Combine parallel data files
380
main_data = CoverageData()
381
combine_parallel_data(
382
main_data,
383
data_paths=['worker1/', 'worker2/'],
384
strict=True,
385
keep=False
386
)
387
main_data.write()
388
```