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.
Files changed (57) hide show
  1. coverage/__init__.py +3 -1
  2. coverage/__main__.py +3 -1
  3. coverage/annotate.py +2 -3
  4. coverage/bytecode.py +178 -4
  5. coverage/cmdline.py +330 -155
  6. coverage/collector.py +32 -43
  7. coverage/config.py +167 -63
  8. coverage/context.py +5 -6
  9. coverage/control.py +165 -86
  10. coverage/core.py +71 -34
  11. coverage/data.py +4 -5
  12. coverage/debug.py +113 -57
  13. coverage/disposition.py +2 -1
  14. coverage/env.py +29 -78
  15. coverage/exceptions.py +29 -7
  16. coverage/execfile.py +19 -14
  17. coverage/files.py +24 -19
  18. coverage/html.py +118 -75
  19. coverage/htmlfiles/coverage_html.js +12 -10
  20. coverage/htmlfiles/index.html +45 -10
  21. coverage/htmlfiles/pyfile.html +2 -2
  22. coverage/htmlfiles/style.css +54 -6
  23. coverage/htmlfiles/style.scss +85 -3
  24. coverage/inorout.py +62 -45
  25. coverage/jsonreport.py +22 -9
  26. coverage/lcovreport.py +16 -18
  27. coverage/misc.py +51 -47
  28. coverage/multiproc.py +12 -7
  29. coverage/numbits.py +4 -5
  30. coverage/parser.py +150 -251
  31. coverage/patch.py +166 -0
  32. coverage/phystokens.py +25 -26
  33. coverage/plugin.py +14 -14
  34. coverage/plugin_support.py +37 -36
  35. coverage/python.py +13 -14
  36. coverage/pytracer.py +31 -33
  37. coverage/regions.py +3 -2
  38. coverage/report.py +60 -44
  39. coverage/report_core.py +7 -10
  40. coverage/results.py +152 -68
  41. coverage/sqldata.py +261 -211
  42. coverage/sqlitedb.py +37 -29
  43. coverage/sysmon.py +237 -162
  44. coverage/templite.py +19 -7
  45. coverage/tomlconfig.py +13 -13
  46. coverage/tracer.cpython-312-aarch64-linux-musl.so +0 -0
  47. coverage/tracer.pyi +3 -1
  48. coverage/types.py +26 -23
  49. coverage/version.py +4 -19
  50. coverage/xmlreport.py +17 -14
  51. {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/METADATA +50 -28
  52. coverage-7.12.0.dist-info/RECORD +59 -0
  53. {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/WHEEL +1 -1
  54. coverage-7.6.10.dist-info/RECORD +0 -58
  55. {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/entry_points.txt +0 -0
  56. {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info/licenses}/LICENSE.txt +0 -0
  57. {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/top_level.txt +0 -0
coverage/misc.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/nedbat/coveragepy/blob/master/NOTICE.txt
2
+ # For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
3
3
 
4
4
  """Miscellaneous stuff for coverage.py."""
5
5
 
@@ -18,20 +18,16 @@ import os.path
18
18
  import re
19
19
  import sys
20
20
  import types
21
-
22
- from types import ModuleType
23
- from typing import (
24
- Any, NoReturn, TypeVar,
25
- )
26
21
  from collections.abc import Iterable, Iterator, Mapping, Sequence
27
-
28
- from coverage.exceptions import CoverageException
29
- from coverage.types import TArc
22
+ from types import ModuleType
23
+ from typing import Any, NoReturn, TypeVar
30
24
 
31
25
  # In 6.0, the exceptions moved from misc.py to exceptions.py. But a number of
32
26
  # other packages were importing the exceptions from misc, so import them here.
33
27
  # pylint: disable=unused-wildcard-import
34
- from coverage.exceptions import * # pylint: disable=wildcard-import
28
+ from coverage.exceptions import * # pylint: disable=wildcard-import
29
+ from coverage.exceptions import CoverageException
30
+ from coverage.types import TArc
35
31
 
36
32
  ISOLATED_MODULES: dict[ModuleType, ModuleType] = {}
37
33
 
@@ -54,11 +50,13 @@ def isolate_module(mod: ModuleType) -> ModuleType:
54
50
  setattr(new_mod, name, value)
55
51
  return ISOLATED_MODULES[mod]
56
52
 
53
+
57
54
  os = isolate_module(os)
58
55
 
59
56
 
60
57
  class SysModuleSaver:
61
58
  """Saves the contents of sys.modules, and removes new modules later."""
59
+
62
60
  def __init__(self) -> None:
63
61
  self.old_modules = set(sys.modules)
64
62
 
@@ -111,9 +109,9 @@ def nice_pair(pair: TArc) -> str:
111
109
  """
112
110
  start, end = pair
113
111
  if start == end:
114
- return "%d" % start
112
+ return f"{start}"
115
113
  else:
116
- return "%d-%d" % (start, end)
114
+ return f"{start}-{end}"
117
115
 
118
116
 
119
117
  def bool_or_none(b: Any) -> bool | None:
@@ -158,37 +156,39 @@ def ensure_dir_for_file(path: str) -> None:
158
156
 
159
157
  class Hasher:
160
158
  """Hashes Python data for fingerprinting."""
159
+
161
160
  def __init__(self) -> None:
162
161
  self.hash = hashlib.new("sha3_256", usedforsecurity=False)
163
162
 
164
163
  def update(self, v: Any) -> None:
165
164
  """Add `v` to the hash, recursively if needed."""
166
165
  self.hash.update(str(type(v)).encode("utf-8"))
167
- if isinstance(v, str):
168
- self.hash.update(v.encode("utf-8"))
169
- elif isinstance(v, bytes):
170
- self.hash.update(v)
171
- elif v is None:
172
- pass
173
- elif isinstance(v, (int, float)):
174
- self.hash.update(str(v).encode("utf-8"))
175
- elif isinstance(v, (tuple, list)):
176
- for e in v:
177
- self.update(e)
178
- elif isinstance(v, dict):
179
- keys = v.keys()
180
- for k in sorted(keys):
181
- self.update(k)
182
- self.update(v[k])
183
- else:
184
- for k in dir(v):
185
- if k.startswith("__"):
186
- continue
187
- a = getattr(v, k)
188
- if inspect.isroutine(a):
189
- continue
190
- self.update(k)
191
- self.update(a)
166
+ match v:
167
+ case None:
168
+ pass
169
+ case str():
170
+ self.hash.update(v.encode("utf-8"))
171
+ case bytes():
172
+ self.hash.update(v)
173
+ case int() | float():
174
+ self.hash.update(str(v).encode("utf-8"))
175
+ case tuple() | list():
176
+ for e in v:
177
+ self.update(e)
178
+ case dict():
179
+ keys = v.keys()
180
+ for k in sorted(keys):
181
+ self.update(k)
182
+ self.update(v[k])
183
+ case _:
184
+ for k in dir(v):
185
+ if k.startswith("__"):
186
+ continue
187
+ a = getattr(v, k)
188
+ if inspect.isroutine(a):
189
+ continue
190
+ self.update(k)
191
+ self.update(a)
192
192
  self.hash.update(b".")
193
193
 
194
194
  def hexdigest(self) -> str:
@@ -218,6 +218,7 @@ class DefaultValue:
218
218
  and Sphinx output.
219
219
 
220
220
  """
221
+
221
222
  def __init__(self, display_as: str) -> None:
222
223
  self.display_as = display_as
223
224
 
@@ -244,13 +245,13 @@ def substitute_variables(text: str, variables: Mapping[str, str]) -> str:
244
245
  dollar_pattern = r"""(?x) # Use extended regex syntax
245
246
  \$ # A dollar sign,
246
247
  (?: # then
247
- (?P<dollar>\$) | # a dollar sign, or
248
- (?P<word1>\w+) | # a plain word, or
249
- { # a {-wrapped
250
- (?P<word2>\w+) # word,
251
- (?:
252
- (?P<strict>\?) | # with a strict marker
253
- -(?P<defval>[^}]*) # or a default value
248
+ (?P<dollar> \$ ) | # a dollar sign, or
249
+ (?P<word1> \w+ ) | # a plain word, or
250
+ \{ # a {-wrapped
251
+ (?P<word2> \w+ ) # word,
252
+ (?: # either
253
+ (?P<strict> \? ) | # with a strict marker
254
+ -(?P<defval> [^}]* ) # or a default value
254
255
  )? # maybe.
255
256
  }
256
257
  )
@@ -261,7 +262,7 @@ def substitute_variables(text: str, variables: Mapping[str, str]) -> str:
261
262
  def dollar_replace(match: re.Match[str]) -> str:
262
263
  """Called for each $replacement."""
263
264
  # Only one of the dollar_groups will have matched, just get its text.
264
- word = next(g for g in match.group(*dollar_groups) if g) # pragma: always breaks
265
+ word = next(g for g in match.group(*dollar_groups) if g) # pragma: always breaks
265
266
  if word == "$":
266
267
  return "$"
267
268
  elif word in variables:
@@ -277,8 +278,7 @@ def substitute_variables(text: str, variables: Mapping[str, str]) -> str:
277
278
 
278
279
 
279
280
  def format_local_datetime(dt: datetime.datetime) -> str:
280
- """Return a string with local timezone representing the date.
281
- """
281
+ """Return a string with local timezone representing the date."""
282
282
  return dt.astimezone().strftime("%Y-%m-%d %H:%M %z")
283
283
 
284
284
 
@@ -311,6 +311,7 @@ def _human_key(s: str) -> tuple[list[str | int], str]:
311
311
  The original string is appended as a last value to ensure the
312
312
  key is unique enough so that "x1y" and "x001y" can be distinguished.
313
313
  """
314
+
314
315
  def tryint(s: str) -> str | int:
315
316
  """If `s` is a number, return an int, else `s` unchanged."""
316
317
  try:
@@ -320,6 +321,7 @@ def _human_key(s: str) -> tuple[list[str | int], str]:
320
321
 
321
322
  return ([tryint(c) for c in re.split(r"(\d+)", s)], s)
322
323
 
324
+
323
325
  def human_sorted(strings: Iterable[str]) -> list[str]:
324
326
  """Sort the given iterable of strings the way that humans expect.
325
327
 
@@ -330,8 +332,10 @@ def human_sorted(strings: Iterable[str]) -> list[str]:
330
332
  """
331
333
  return sorted(strings, key=_human_key)
332
334
 
335
+
333
336
  SortableItem = TypeVar("SortableItem", bound=Sequence[Any])
334
337
 
338
+
335
339
  def human_sorted_items(
336
340
  items: Iterable[SortableItem],
337
341
  reverse: bool = False,
coverage/multiproc.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/nedbat/coveragepy/blob/master/NOTICE.txt
2
+ # For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
3
3
 
4
4
  """Monkey-patching to add multiprocessing support for coverage.py"""
5
5
 
@@ -11,7 +11,6 @@ import os
11
11
  import os.path
12
12
  import sys
13
13
  import traceback
14
-
15
14
  from typing import Any
16
15
 
17
16
  from coverage.debug import DebugControl
@@ -22,16 +21,18 @@ PATCHED_MARKER = "_coverage$patched"
22
21
 
23
22
 
24
23
  OriginalProcess = multiprocessing.process.BaseProcess
25
- original_bootstrap = OriginalProcess._bootstrap # type: ignore[attr-defined]
24
+ original_bootstrap = OriginalProcess._bootstrap # type: ignore[attr-defined]
25
+
26
26
 
27
- class ProcessWithCoverage(OriginalProcess): # pylint: disable=abstract-method
27
+ class ProcessWithCoverage(OriginalProcess): # pylint: disable=abstract-method
28
28
  """A replacement for multiprocess.Process that starts coverage."""
29
29
 
30
- def _bootstrap(self, *args, **kwargs): # type: ignore[no-untyped-def]
30
+ def _bootstrap(self, *args, **kwargs): # type: ignore[no-untyped-def]
31
31
  """Wrapper around _bootstrap to start coverage."""
32
32
  debug: DebugControl | None = None
33
33
  try:
34
- from coverage import Coverage # avoid circular import
34
+ from coverage import Coverage # avoid circular import
35
+
35
36
  cov = Coverage(data_suffix=True, auto_data=True)
36
37
  cov._warn_preimported_source = False
37
38
  cov.start()
@@ -61,8 +62,10 @@ class ProcessWithCoverage(OriginalProcess): # pylint: disable=abstract-m
61
62
  if debug:
62
63
  debug.write("Saved multiprocessing data")
63
64
 
65
+
64
66
  class Stowaway:
65
67
  """An object to pickle, so when it is unpickled, it can apply the monkey-patch."""
68
+
66
69
  def __init__(self, rcfile: str) -> None:
67
70
  self.rcfile = rcfile
68
71
 
@@ -86,7 +89,7 @@ def patch_multiprocessing(rcfile: str) -> None:
86
89
  if hasattr(multiprocessing, PATCHED_MARKER):
87
90
  return
88
91
 
89
- OriginalProcess._bootstrap = ProcessWithCoverage._bootstrap # type: ignore[attr-defined]
92
+ OriginalProcess._bootstrap = ProcessWithCoverage._bootstrap # type: ignore[attr-defined]
90
93
 
91
94
  # Set the value in ProcessWithCoverage that will be pickled into the child
92
95
  # process.
@@ -100,10 +103,12 @@ def patch_multiprocessing(rcfile: str) -> None:
100
103
  # Windows only spawns, so this is needed to keep Windows working.
101
104
  try:
102
105
  from multiprocessing import spawn
106
+
103
107
  original_get_preparation_data = spawn.get_preparation_data
104
108
  except (ImportError, AttributeError):
105
109
  pass
106
110
  else:
111
+
107
112
  def get_preparation_data_with_stowaway(name: str) -> dict[str, Any]:
108
113
  """Get the original preparation data, and also insert our stowaway."""
109
114
  d = original_get_preparation_data(name)
coverage/numbits.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/nedbat/coveragepy/blob/master/NOTICE.txt
2
+ # For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
3
3
 
4
4
  """
5
5
  Functions to manipulate packed binary representations of number sets.
@@ -18,9 +18,8 @@ from __future__ import annotations
18
18
 
19
19
  import json
20
20
  import sqlite3
21
-
22
- from itertools import zip_longest
23
21
  from collections.abc import Iterable
22
+ from itertools import zip_longest
24
23
 
25
24
 
26
25
  def nums_to_numbits(nums: Iterable[int]) -> bytes:
@@ -39,7 +38,7 @@ def nums_to_numbits(nums: Iterable[int]) -> bytes:
39
38
  return b""
40
39
  b = bytearray(nbytes)
41
40
  for num in nums:
42
- b[num//8] |= 1 << num % 8
41
+ b[num // 8] |= 1 << num % 8
43
42
  return bytes(b)
44
43
 
45
44
 
@@ -59,7 +58,7 @@ def numbits_to_nums(numbits: bytes) -> list[int]:
59
58
  nums = []
60
59
  for byte_i, byte in enumerate(numbits):
61
60
  for bit_i in range(8):
62
- if (byte & (1 << bit_i)):
61
+ if byte & (1 << bit_i):
63
62
  nums.append(byte_i * 8 + bit_i)
64
63
  return nums
65
64