coverage 7.6.10__cp312-cp312-musllinux_1_2_aarch64.whl → 7.12.0__cp312-cp312-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coverage/__init__.py +3 -1
- coverage/__main__.py +3 -1
- coverage/annotate.py +2 -3
- coverage/bytecode.py +178 -4
- coverage/cmdline.py +330 -155
- coverage/collector.py +32 -43
- coverage/config.py +167 -63
- coverage/context.py +5 -6
- coverage/control.py +165 -86
- coverage/core.py +71 -34
- coverage/data.py +4 -5
- coverage/debug.py +113 -57
- coverage/disposition.py +2 -1
- coverage/env.py +29 -78
- coverage/exceptions.py +29 -7
- coverage/execfile.py +19 -14
- coverage/files.py +24 -19
- coverage/html.py +118 -75
- coverage/htmlfiles/coverage_html.js +12 -10
- coverage/htmlfiles/index.html +45 -10
- coverage/htmlfiles/pyfile.html +2 -2
- coverage/htmlfiles/style.css +54 -6
- coverage/htmlfiles/style.scss +85 -3
- coverage/inorout.py +62 -45
- coverage/jsonreport.py +22 -9
- coverage/lcovreport.py +16 -18
- coverage/misc.py +51 -47
- coverage/multiproc.py +12 -7
- coverage/numbits.py +4 -5
- coverage/parser.py +150 -251
- coverage/patch.py +166 -0
- coverage/phystokens.py +25 -26
- coverage/plugin.py +14 -14
- coverage/plugin_support.py +37 -36
- coverage/python.py +13 -14
- coverage/pytracer.py +31 -33
- coverage/regions.py +3 -2
- coverage/report.py +60 -44
- coverage/report_core.py +7 -10
- coverage/results.py +152 -68
- coverage/sqldata.py +261 -211
- coverage/sqlitedb.py +37 -29
- coverage/sysmon.py +237 -162
- coverage/templite.py +19 -7
- coverage/tomlconfig.py +13 -13
- coverage/tracer.cpython-312-aarch64-linux-musl.so +0 -0
- coverage/tracer.pyi +3 -1
- coverage/types.py +26 -23
- coverage/version.py +4 -19
- coverage/xmlreport.py +17 -14
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/METADATA +50 -28
- coverage-7.12.0.dist-info/RECORD +59 -0
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/WHEEL +1 -1
- coverage-7.6.10.dist-info/RECORD +0 -58
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/entry_points.txt +0 -0
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info/licenses}/LICENSE.txt +0 -0
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/top_level.txt +0 -0
coverage/sqlitedb.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
|
2
|
-
# For details: https://github.com/
|
|
2
|
+
# For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
|
|
3
3
|
|
|
4
4
|
"""SQLite abstraction for coverage.py"""
|
|
5
5
|
|
|
@@ -8,9 +8,8 @@ from __future__ import annotations
|
|
|
8
8
|
import contextlib
|
|
9
9
|
import re
|
|
10
10
|
import sqlite3
|
|
11
|
-
|
|
12
|
-
from typing import cast, Any
|
|
13
11
|
from collections.abc import Iterable, Iterator
|
|
12
|
+
from typing import Any, cast
|
|
14
13
|
|
|
15
14
|
from coverage.debug import auto_repr, clipped_repr, exc_one_line
|
|
16
15
|
from coverage.exceptions import DataError
|
|
@@ -29,9 +28,11 @@ class SqliteDb:
|
|
|
29
28
|
etc(a, b)
|
|
30
29
|
|
|
31
30
|
"""
|
|
32
|
-
|
|
31
|
+
|
|
32
|
+
def __init__(self, filename: str, debug: TDebugCtl, no_disk: bool = False) -> None:
|
|
33
33
|
self.debug = debug
|
|
34
34
|
self.filename = filename
|
|
35
|
+
self.no_disk = no_disk
|
|
35
36
|
self.nest = 0
|
|
36
37
|
self.con: sqlite3.Connection | None = None
|
|
37
38
|
|
|
@@ -50,7 +51,11 @@ class SqliteDb:
|
|
|
50
51
|
if self.debug.should("sql"):
|
|
51
52
|
self.debug.write(f"Connecting to {self.filename!r}")
|
|
52
53
|
try:
|
|
53
|
-
|
|
54
|
+
# Use uri=True when connecting to memory URIs
|
|
55
|
+
if self.filename.startswith("file:"):
|
|
56
|
+
self.con = sqlite3.connect(self.filename, check_same_thread=False, uri=True)
|
|
57
|
+
else:
|
|
58
|
+
self.con = sqlite3.connect(self.filename, check_same_thread=False)
|
|
54
59
|
except sqlite3.Error as exc:
|
|
55
60
|
raise DataError(f"Couldn't use data file {self.filename!r}: {exc}") from exc
|
|
56
61
|
|
|
@@ -64,25 +69,27 @@ class SqliteDb:
|
|
|
64
69
|
# In Python 3.12+, we can change the config to allow journal_mode=off.
|
|
65
70
|
if hasattr(sqlite3, "SQLITE_DBCONFIG_DEFENSIVE"):
|
|
66
71
|
# Turn off defensive mode, so that journal_mode=off can succeed.
|
|
67
|
-
self.con.setconfig(
|
|
68
|
-
sqlite3.SQLITE_DBCONFIG_DEFENSIVE,
|
|
72
|
+
self.con.setconfig( # type: ignore[attr-defined, unused-ignore]
|
|
73
|
+
sqlite3.SQLITE_DBCONFIG_DEFENSIVE,
|
|
74
|
+
False,
|
|
69
75
|
)
|
|
70
76
|
|
|
71
77
|
# This pragma makes writing faster. It disables rollbacks, but we never need them.
|
|
72
78
|
self.execute_void("pragma journal_mode=off")
|
|
73
79
|
|
|
74
80
|
# This pragma makes writing faster. It can fail in unusual situations
|
|
75
|
-
# (https://github.com/
|
|
81
|
+
# (https://github.com/coveragepy/coveragepy/issues/1646), so use fail_ok=True
|
|
76
82
|
# to keep things going.
|
|
77
83
|
self.execute_void("pragma synchronous=off", fail_ok=True)
|
|
78
84
|
|
|
79
|
-
def close(self) -> None:
|
|
85
|
+
def close(self, force: bool = False) -> None:
|
|
80
86
|
"""If needed, close the connection."""
|
|
81
|
-
if self.con is not None
|
|
82
|
-
if self.
|
|
83
|
-
self.debug.
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
if self.con is not None:
|
|
88
|
+
if force or not self.no_disk:
|
|
89
|
+
if self.debug.should("sql"):
|
|
90
|
+
self.debug.write(f"Closing {self.con!r} on {self.filename!r}")
|
|
91
|
+
self.con.close()
|
|
92
|
+
self.con = None
|
|
86
93
|
|
|
87
94
|
def __enter__(self) -> SqliteDb:
|
|
88
95
|
if self.nest == 0:
|
|
@@ -92,7 +99,7 @@ class SqliteDb:
|
|
|
92
99
|
self.nest += 1
|
|
93
100
|
return self
|
|
94
101
|
|
|
95
|
-
def __exit__(self, exc_type, exc_value, traceback) -> None:
|
|
102
|
+
def __exit__(self, exc_type, exc_value, traceback) -> None: # type: ignore[no-untyped-def]
|
|
96
103
|
self.nest -= 1
|
|
97
104
|
if self.nest == 0:
|
|
98
105
|
try:
|
|
@@ -112,15 +119,15 @@ class SqliteDb:
|
|
|
112
119
|
try:
|
|
113
120
|
assert self.con is not None
|
|
114
121
|
try:
|
|
115
|
-
return self.con.execute(sql, parameters)
|
|
122
|
+
return self.con.execute(sql, parameters) # type: ignore[arg-type]
|
|
116
123
|
except Exception:
|
|
117
124
|
# In some cases, an error might happen that isn't really an
|
|
118
125
|
# error. Try again immediately.
|
|
119
|
-
# https://github.com/
|
|
120
|
-
return self.con.execute(sql, parameters)
|
|
126
|
+
# https://github.com/coveragepy/coveragepy/issues/1010
|
|
127
|
+
return self.con.execute(sql, parameters) # type: ignore[arg-type]
|
|
121
128
|
except sqlite3.Error as exc:
|
|
122
129
|
msg = str(exc)
|
|
123
|
-
if self.
|
|
130
|
+
if not self.no_disk:
|
|
124
131
|
try:
|
|
125
132
|
# `execute` is the first thing we do with the database, so try
|
|
126
133
|
# hard to provide useful hints if something goes wrong now.
|
|
@@ -128,8 +135,8 @@ class SqliteDb:
|
|
|
128
135
|
cov4_sig = b"!coverage.py: This is a private format"
|
|
129
136
|
if bad_file.read(len(cov4_sig)) == cov4_sig:
|
|
130
137
|
msg = (
|
|
131
|
-
"Looks like a coverage 4.x data file. "
|
|
132
|
-
"Are you mixing versions of coverage?"
|
|
138
|
+
"Looks like a coverage 4.x data file. "
|
|
139
|
+
+ "Are you mixing versions of coverage?"
|
|
133
140
|
)
|
|
134
141
|
except Exception:
|
|
135
142
|
pass
|
|
@@ -207,21 +214,22 @@ class SqliteDb:
|
|
|
207
214
|
except Exception:
|
|
208
215
|
# In some cases, an error might happen that isn't really an
|
|
209
216
|
# error. Try again immediately.
|
|
210
|
-
# https://github.com/
|
|
217
|
+
# https://github.com/coveragepy/coveragepy/issues/1010
|
|
211
218
|
return self.con.executemany(sql, data)
|
|
212
219
|
|
|
213
|
-
def executemany_void(self, sql: str, data:
|
|
220
|
+
def executemany_void(self, sql: str, data: list[Any]) -> None:
|
|
214
221
|
"""Same as :meth:`python:sqlite3.Connection.executemany` when you don't need the cursor."""
|
|
215
|
-
|
|
216
|
-
if data:
|
|
217
|
-
self._executemany(sql, data).close()
|
|
222
|
+
self._executemany(sql, data).close()
|
|
218
223
|
|
|
219
224
|
def executescript(self, script: str) -> None:
|
|
220
225
|
"""Same as :meth:`python:sqlite3.Connection.executescript`."""
|
|
221
226
|
if self.debug.should("sql"):
|
|
222
|
-
self.debug.write(
|
|
223
|
-
|
|
224
|
-
|
|
227
|
+
self.debug.write(
|
|
228
|
+
"Executing script with {} chars: {}".format(
|
|
229
|
+
len(script),
|
|
230
|
+
clipped_repr(script, 100),
|
|
231
|
+
)
|
|
232
|
+
)
|
|
225
233
|
assert self.con is not None
|
|
226
234
|
self.con.executescript(script).close()
|
|
227
235
|
|