coverage 7.11.1__cp314-cp314-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.
Files changed (59) hide show
  1. coverage/__init__.py +40 -0
  2. coverage/__main__.py +12 -0
  3. coverage/annotate.py +114 -0
  4. coverage/bytecode.py +196 -0
  5. coverage/cmdline.py +1184 -0
  6. coverage/collector.py +486 -0
  7. coverage/config.py +731 -0
  8. coverage/context.py +74 -0
  9. coverage/control.py +1481 -0
  10. coverage/core.py +139 -0
  11. coverage/data.py +227 -0
  12. coverage/debug.py +669 -0
  13. coverage/disposition.py +59 -0
  14. coverage/env.py +135 -0
  15. coverage/exceptions.py +91 -0
  16. coverage/execfile.py +329 -0
  17. coverage/files.py +553 -0
  18. coverage/html.py +856 -0
  19. coverage/htmlfiles/coverage_html.js +733 -0
  20. coverage/htmlfiles/favicon_32.png +0 -0
  21. coverage/htmlfiles/index.html +164 -0
  22. coverage/htmlfiles/keybd_closed.png +0 -0
  23. coverage/htmlfiles/pyfile.html +149 -0
  24. coverage/htmlfiles/style.css +377 -0
  25. coverage/htmlfiles/style.scss +824 -0
  26. coverage/inorout.py +614 -0
  27. coverage/jsonreport.py +188 -0
  28. coverage/lcovreport.py +219 -0
  29. coverage/misc.py +373 -0
  30. coverage/multiproc.py +120 -0
  31. coverage/numbits.py +146 -0
  32. coverage/parser.py +1213 -0
  33. coverage/patch.py +166 -0
  34. coverage/phystokens.py +197 -0
  35. coverage/plugin.py +617 -0
  36. coverage/plugin_support.py +299 -0
  37. coverage/py.typed +1 -0
  38. coverage/python.py +269 -0
  39. coverage/pytracer.py +369 -0
  40. coverage/regions.py +127 -0
  41. coverage/report.py +298 -0
  42. coverage/report_core.py +117 -0
  43. coverage/results.py +471 -0
  44. coverage/sqldata.py +1153 -0
  45. coverage/sqlitedb.py +239 -0
  46. coverage/sysmon.py +474 -0
  47. coverage/templite.py +306 -0
  48. coverage/tomlconfig.py +210 -0
  49. coverage/tracer.cpython-314-aarch64-linux-musl.so +0 -0
  50. coverage/tracer.pyi +43 -0
  51. coverage/types.py +206 -0
  52. coverage/version.py +35 -0
  53. coverage/xmlreport.py +264 -0
  54. coverage-7.11.1.dist-info/METADATA +221 -0
  55. coverage-7.11.1.dist-info/RECORD +59 -0
  56. coverage-7.11.1.dist-info/WHEEL +5 -0
  57. coverage-7.11.1.dist-info/entry_points.txt +4 -0
  58. coverage-7.11.1.dist-info/licenses/LICENSE.txt +177 -0
  59. coverage-7.11.1.dist-info/top_level.txt +1 -0
coverage/sqlitedb.py ADDED
@@ -0,0 +1,239 @@
1
+ # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2
+ # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
3
+
4
+ """SQLite abstraction for coverage.py"""
5
+
6
+ from __future__ import annotations
7
+
8
+ import contextlib
9
+ import re
10
+ import sqlite3
11
+ from collections.abc import Iterable, Iterator
12
+ from typing import Any, cast
13
+
14
+ from coverage.debug import auto_repr, clipped_repr, exc_one_line
15
+ from coverage.exceptions import DataError
16
+ from coverage.types import TDebugCtl
17
+
18
+
19
+ class SqliteDb:
20
+ """A simple abstraction over a SQLite database.
21
+
22
+ Use as a context manager, then you can use it like a
23
+ :class:`python:sqlite3.Connection` object::
24
+
25
+ with SqliteDb(filename, debug_control) as db:
26
+ with db.execute("select a, b from some_table") as cur:
27
+ for a, b in cur:
28
+ etc(a, b)
29
+
30
+ """
31
+
32
+ def __init__(self, filename: str, debug: TDebugCtl, no_disk: bool = False) -> None:
33
+ self.debug = debug
34
+ self.filename = filename
35
+ self.no_disk = no_disk
36
+ self.nest = 0
37
+ self.con: sqlite3.Connection | None = None
38
+
39
+ __repr__ = auto_repr
40
+
41
+ def _connect(self) -> None:
42
+ """Connect to the db and do universal initialization."""
43
+ if self.con is not None:
44
+ return
45
+
46
+ # It can happen that Python switches threads while the tracer writes
47
+ # data. The second thread will also try to write to the data,
48
+ # effectively causing a nested context. However, given the idempotent
49
+ # nature of the tracer operations, sharing a connection among threads
50
+ # is not a problem.
51
+ if self.debug.should("sql"):
52
+ self.debug.write(f"Connecting to {self.filename!r}")
53
+ try:
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)
59
+ except sqlite3.Error as exc:
60
+ raise DataError(f"Couldn't use data file {self.filename!r}: {exc}") from exc
61
+
62
+ if self.debug.should("sql"):
63
+ self.debug.write(f"Connected to {self.filename!r} as {self.con!r}")
64
+
65
+ self.con.create_function("REGEXP", 2, lambda txt, pat: re.search(txt, pat) is not None)
66
+
67
+ # Turning off journal_mode can speed up writing. It can't always be
68
+ # disabled, so we have to be prepared for *-journal files elsewhere.
69
+ # In Python 3.12+, we can change the config to allow journal_mode=off.
70
+ if hasattr(sqlite3, "SQLITE_DBCONFIG_DEFENSIVE"):
71
+ # Turn off defensive mode, so that journal_mode=off can succeed.
72
+ self.con.setconfig( # type: ignore[attr-defined, unused-ignore]
73
+ sqlite3.SQLITE_DBCONFIG_DEFENSIVE,
74
+ False,
75
+ )
76
+
77
+ # This pragma makes writing faster. It disables rollbacks, but we never need them.
78
+ self.execute_void("pragma journal_mode=off")
79
+
80
+ # This pragma makes writing faster. It can fail in unusual situations
81
+ # (https://github.com/nedbat/coveragepy/issues/1646), so use fail_ok=True
82
+ # to keep things going.
83
+ self.execute_void("pragma synchronous=off", fail_ok=True)
84
+
85
+ def close(self, force: bool = False) -> None:
86
+ """If needed, close the connection."""
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
93
+
94
+ def __enter__(self) -> SqliteDb:
95
+ if self.nest == 0:
96
+ self._connect()
97
+ assert self.con is not None
98
+ self.con.__enter__()
99
+ self.nest += 1
100
+ return self
101
+
102
+ def __exit__(self, exc_type, exc_value, traceback) -> None: # type: ignore[no-untyped-def]
103
+ self.nest -= 1
104
+ if self.nest == 0:
105
+ try:
106
+ assert self.con is not None
107
+ self.con.__exit__(exc_type, exc_value, traceback)
108
+ self.close()
109
+ except Exception as exc:
110
+ if self.debug.should("sql"):
111
+ self.debug.write(f"EXCEPTION from __exit__: {exc_one_line(exc)}")
112
+ raise DataError(f"Couldn't end data file {self.filename!r}: {exc}") from exc
113
+
114
+ def _execute(self, sql: str, parameters: Iterable[Any]) -> sqlite3.Cursor:
115
+ """Same as :meth:`python:sqlite3.Connection.execute`."""
116
+ if self.debug.should("sql"):
117
+ tail = f" with {parameters!r}" if parameters else ""
118
+ self.debug.write(f"Executing {sql!r}{tail}")
119
+ try:
120
+ assert self.con is not None
121
+ try:
122
+ return self.con.execute(sql, parameters) # type: ignore[arg-type]
123
+ except Exception:
124
+ # In some cases, an error might happen that isn't really an
125
+ # error. Try again immediately.
126
+ # https://github.com/nedbat/coveragepy/issues/1010
127
+ return self.con.execute(sql, parameters) # type: ignore[arg-type]
128
+ except sqlite3.Error as exc:
129
+ msg = str(exc)
130
+ if not self.no_disk:
131
+ try:
132
+ # `execute` is the first thing we do with the database, so try
133
+ # hard to provide useful hints if something goes wrong now.
134
+ with open(self.filename, "rb") as bad_file:
135
+ cov4_sig = b"!coverage.py: This is a private format"
136
+ if bad_file.read(len(cov4_sig)) == cov4_sig:
137
+ msg = (
138
+ "Looks like a coverage 4.x data file. "
139
+ + "Are you mixing versions of coverage?"
140
+ )
141
+ except Exception:
142
+ pass
143
+ if self.debug.should("sql"):
144
+ self.debug.write(f"EXCEPTION from execute: {exc_one_line(exc)}")
145
+ raise DataError(f"Couldn't use data file {self.filename!r}: {msg}") from exc
146
+
147
+ @contextlib.contextmanager
148
+ def execute(
149
+ self,
150
+ sql: str,
151
+ parameters: Iterable[Any] = (),
152
+ ) -> Iterator[sqlite3.Cursor]:
153
+ """Context managed :meth:`python:sqlite3.Connection.execute`.
154
+
155
+ Use with a ``with`` statement to auto-close the returned cursor.
156
+ """
157
+ cur = self._execute(sql, parameters)
158
+ try:
159
+ yield cur
160
+ finally:
161
+ cur.close()
162
+
163
+ def execute_void(self, sql: str, parameters: Iterable[Any] = (), fail_ok: bool = False) -> None:
164
+ """Same as :meth:`python:sqlite3.Connection.execute` when you don't need the cursor.
165
+
166
+ If `fail_ok` is True, then SQLite errors are ignored.
167
+ """
168
+ try:
169
+ # PyPy needs the .close() calls here, or sqlite gets twisted up:
170
+ # https://bitbucket.org/pypy/pypy/issues/2872/default-isolation-mode-is-different-on
171
+ self._execute(sql, parameters).close()
172
+ except DataError:
173
+ if not fail_ok:
174
+ raise
175
+
176
+ def execute_for_rowid(self, sql: str, parameters: Iterable[Any] = ()) -> int:
177
+ """Like execute, but returns the lastrowid."""
178
+ with self.execute(sql, parameters) as cur:
179
+ assert cur.lastrowid is not None
180
+ rowid: int = cur.lastrowid
181
+ if self.debug.should("sqldata"):
182
+ self.debug.write(f"Row id result: {rowid!r}")
183
+ return rowid
184
+
185
+ def execute_one(self, sql: str, parameters: Iterable[Any] = ()) -> tuple[Any, ...] | None:
186
+ """Execute a statement and return the one row that results.
187
+
188
+ This is like execute(sql, parameters).fetchone(), except it is
189
+ correct in reading the entire result set. This will raise an
190
+ exception if more than one row results.
191
+
192
+ Returns a row, or None if there were no rows.
193
+ """
194
+ with self.execute(sql, parameters) as cur:
195
+ rows = list(cur)
196
+ if len(rows) == 0:
197
+ return None
198
+ elif len(rows) == 1:
199
+ return cast(tuple[Any, ...], rows[0])
200
+ else:
201
+ raise AssertionError(f"SQL {sql!r} shouldn't return {len(rows)} rows")
202
+
203
+ def _executemany(self, sql: str, data: list[Any]) -> sqlite3.Cursor:
204
+ """Same as :meth:`python:sqlite3.Connection.executemany`."""
205
+ if self.debug.should("sql"):
206
+ final = ":" if self.debug.should("sqldata") else ""
207
+ self.debug.write(f"Executing many {sql!r} with {len(data)} rows{final}")
208
+ if self.debug.should("sqldata"):
209
+ for i, row in enumerate(data):
210
+ self.debug.write(f"{i:4d}: {row!r}")
211
+ assert self.con is not None
212
+ try:
213
+ return self.con.executemany(sql, data)
214
+ except Exception:
215
+ # In some cases, an error might happen that isn't really an
216
+ # error. Try again immediately.
217
+ # https://github.com/nedbat/coveragepy/issues/1010
218
+ return self.con.executemany(sql, data)
219
+
220
+ def executemany_void(self, sql: str, data: list[Any]) -> None:
221
+ """Same as :meth:`python:sqlite3.Connection.executemany` when you don't need the cursor."""
222
+ self._executemany(sql, data).close()
223
+
224
+ def executescript(self, script: str) -> None:
225
+ """Same as :meth:`python:sqlite3.Connection.executescript`."""
226
+ if self.debug.should("sql"):
227
+ self.debug.write(
228
+ "Executing script with {} chars: {}".format(
229
+ len(script),
230
+ clipped_repr(script, 100),
231
+ )
232
+ )
233
+ assert self.con is not None
234
+ self.con.executescript(script).close()
235
+
236
+ def dump(self) -> str:
237
+ """Return a multi-line string, the SQL dump of the database."""
238
+ assert self.con is not None
239
+ return "\n".join(self.con.iterdump())