coverage 7.10.7__cp313-cp313-win_arm64.whl → 7.11.0__cp313-cp313-win_arm64.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.
Potentially problematic release.
This version of coverage might be problematic. Click here for more details.
- coverage/cmdline.py +2 -2
- coverage/collector.py +2 -2
- coverage/config.py +2 -2
- coverage/control.py +2 -2
- coverage/debug.py +9 -8
- coverage/env.py +1 -64
- coverage/exceptions.py +3 -9
- coverage/misc.py +26 -25
- coverage/parser.py +63 -206
- coverage/patch.py +11 -10
- coverage/phystokens.py +3 -6
- coverage/tracer.cp313-win_arm64.pyd +0 -0
- coverage/types.py +8 -12
- coverage/version.py +1 -1
- {coverage-7.10.7.dist-info → coverage-7.11.0.dist-info}/METADATA +13 -13
- {coverage-7.10.7.dist-info → coverage-7.11.0.dist-info}/RECORD +20 -20
- {coverage-7.10.7.dist-info → coverage-7.11.0.dist-info}/WHEEL +0 -0
- {coverage-7.10.7.dist-info → coverage-7.11.0.dist-info}/entry_points.txt +0 -0
- {coverage-7.10.7.dist-info → coverage-7.11.0.dist-info}/licenses/LICENSE.txt +0 -0
- {coverage-7.10.7.dist-info → coverage-7.11.0.dist-info}/top_level.txt +0 -0
coverage/cmdline.py
CHANGED
|
@@ -24,7 +24,7 @@ from coverage.control import DEFAULT_DATAFILE
|
|
|
24
24
|
from coverage.core import CTRACER_FILE
|
|
25
25
|
from coverage.data import combinable_files, debug_data_file
|
|
26
26
|
from coverage.debug import info_header, short_stack, write_formatted_info
|
|
27
|
-
from coverage.exceptions import NoSource,
|
|
27
|
+
from coverage.exceptions import NoSource, CoverageException, _ExceptionDuringRun
|
|
28
28
|
from coverage.execfile import PyRunner
|
|
29
29
|
from coverage.results import display_covered, should_fail_under
|
|
30
30
|
from coverage.version import __url__
|
|
@@ -1139,7 +1139,7 @@ def main(argv: list[str] | None = None) -> int | None:
|
|
|
1139
1139
|
# exception.
|
|
1140
1140
|
traceback.print_exception(*err.args) # pylint: disable=no-value-for-parameter
|
|
1141
1141
|
status = ERR
|
|
1142
|
-
except
|
|
1142
|
+
except CoverageException as err:
|
|
1143
1143
|
# A controlled error inside coverage.py: print the message to the user.
|
|
1144
1144
|
msg = err.args[0]
|
|
1145
1145
|
if err.slug:
|
coverage/collector.py
CHANGED
|
@@ -146,12 +146,12 @@ class Collector:
|
|
|
146
146
|
self.concur_id_func = greenlet.getcurrent
|
|
147
147
|
elif "eventlet" in concurrencies:
|
|
148
148
|
tried = "eventlet"
|
|
149
|
-
import eventlet.greenthread
|
|
149
|
+
import eventlet.greenthread
|
|
150
150
|
|
|
151
151
|
self.concur_id_func = eventlet.greenthread.getcurrent
|
|
152
152
|
elif "gevent" in concurrencies:
|
|
153
153
|
tried = "gevent"
|
|
154
|
-
import gevent
|
|
154
|
+
import gevent
|
|
155
155
|
|
|
156
156
|
self.concur_id_func = gevent.getcurrent
|
|
157
157
|
|
coverage/config.py
CHANGED
|
@@ -14,7 +14,7 @@ import os
|
|
|
14
14
|
import os.path
|
|
15
15
|
import re
|
|
16
16
|
from collections.abc import Iterable
|
|
17
|
-
from typing import Any, Callable, Final, Mapping
|
|
17
|
+
from typing import Any, Callable, Final, Mapping
|
|
18
18
|
|
|
19
19
|
from coverage.exceptions import ConfigError
|
|
20
20
|
from coverage.misc import human_sorted_items, isolate_module, substitute_variables
|
|
@@ -143,7 +143,7 @@ class HandyConfigParser(configparser.ConfigParser):
|
|
|
143
143
|
return process_regexlist(section, option, line_list.splitlines())
|
|
144
144
|
|
|
145
145
|
|
|
146
|
-
TConfigParser =
|
|
146
|
+
TConfigParser = HandyConfigParser | TomlConfigParser
|
|
147
147
|
|
|
148
148
|
|
|
149
149
|
# The default line exclusion regexes.
|
coverage/control.py
CHANGED
|
@@ -19,7 +19,7 @@ import time
|
|
|
19
19
|
import warnings
|
|
20
20
|
from collections.abc import Iterable, Iterator
|
|
21
21
|
from types import FrameType
|
|
22
|
-
from typing import IO, Any, Callable,
|
|
22
|
+
from typing import IO, Any, Callable, cast
|
|
23
23
|
|
|
24
24
|
from coverage import env
|
|
25
25
|
from coverage.annotate import AnnotateReporter
|
|
@@ -298,7 +298,7 @@ class Coverage(TConfigurable):
|
|
|
298
298
|
self._debug: DebugControl = NoDebugging()
|
|
299
299
|
self._inorout: InOrOut | None = None
|
|
300
300
|
self._plugins: Plugins = Plugins()
|
|
301
|
-
self._plugin_override = cast(
|
|
301
|
+
self._plugin_override = cast(Iterable[TCoverageInit] | None, plugins)
|
|
302
302
|
self._data: CoverageData | None = None
|
|
303
303
|
self._data_to_close: list[CoverageData] = []
|
|
304
304
|
self._core: Core | None = None
|
coverage/debug.py
CHANGED
|
@@ -155,14 +155,15 @@ def info_formatter(info: Iterable[tuple[str, Any]]) -> Iterator[str]:
|
|
|
155
155
|
if data == []:
|
|
156
156
|
data = "-none-"
|
|
157
157
|
prefix = f"{label:>{LABEL_LEN}}: "
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
158
|
+
match data:
|
|
159
|
+
case tuple() if len(str(data)) < 30:
|
|
160
|
+
yield f"{prefix}{data}"
|
|
161
|
+
case tuple() | list() | set():
|
|
162
|
+
for e in data:
|
|
163
|
+
yield f"{prefix}{e}"
|
|
164
|
+
prefix = " " * (LABEL_LEN + 2)
|
|
165
|
+
case _:
|
|
166
|
+
yield f"{prefix}{data}"
|
|
166
167
|
|
|
167
168
|
|
|
168
169
|
def write_formatted_info(
|
coverage/env.py
CHANGED
|
@@ -43,7 +43,7 @@ else:
|
|
|
43
43
|
GIL = getattr(sys, "_is_gil_enabled", lambda: True)()
|
|
44
44
|
|
|
45
45
|
# Do we ship compiled coveragepy wheels for this version?
|
|
46
|
-
SHIPPING_WHEELS = CPYTHON and PYVERSION[:2] <= (3,
|
|
46
|
+
SHIPPING_WHEELS = CPYTHON and PYVERSION[:2] <= (3, 14)
|
|
47
47
|
|
|
48
48
|
# Should we default to sys.monitoring?
|
|
49
49
|
SYSMON_DEFAULT = CPYTHON and PYVERSION >= (3, 14)
|
|
@@ -53,63 +53,6 @@ SYSMON_DEFAULT = CPYTHON and PYVERSION >= (3, 14)
|
|
|
53
53
|
class PYBEHAVIOR:
|
|
54
54
|
"""Flags indicating this Python's behavior."""
|
|
55
55
|
|
|
56
|
-
# Does Python conform to PEP626, Precise line numbers for debugging and other tools.
|
|
57
|
-
# https://www.python.org/dev/peps/pep-0626
|
|
58
|
-
pep626 = (PYVERSION > (3, 10, 0, "alpha", 4)) # fmt: skip
|
|
59
|
-
|
|
60
|
-
# Is "if __debug__" optimized away?
|
|
61
|
-
optimize_if_debug = not pep626
|
|
62
|
-
|
|
63
|
-
# Is "if not __debug__" optimized away? The exact details have changed
|
|
64
|
-
# across versions.
|
|
65
|
-
optimize_if_not_debug = 1 if pep626 else 2
|
|
66
|
-
|
|
67
|
-
# 3.7 changed how functions with only docstrings are numbered.
|
|
68
|
-
docstring_only_function = (not PYPY) and (PYVERSION <= (3, 10))
|
|
69
|
-
|
|
70
|
-
# Lines after break/continue/return/raise are no longer compiled into the
|
|
71
|
-
# bytecode. They used to be marked as missing, now they aren't executable.
|
|
72
|
-
omit_after_jump = pep626 or PYPY
|
|
73
|
-
|
|
74
|
-
# PyPy has always omitted statements after return.
|
|
75
|
-
omit_after_return = omit_after_jump or PYPY
|
|
76
|
-
|
|
77
|
-
# Optimize away unreachable try-else clauses.
|
|
78
|
-
optimize_unreachable_try_else = pep626
|
|
79
|
-
|
|
80
|
-
# Modules used to have firstlineno equal to the line number of the first
|
|
81
|
-
# real line of code. Now they always start at 1.
|
|
82
|
-
module_firstline_1 = pep626
|
|
83
|
-
|
|
84
|
-
# Are "if 0:" lines (and similar) kept in the compiled code?
|
|
85
|
-
keep_constant_test = pep626
|
|
86
|
-
|
|
87
|
-
# When leaving a with-block, do we visit the with-line again for the exit?
|
|
88
|
-
# For example, wwith.py:
|
|
89
|
-
#
|
|
90
|
-
# with open("/tmp/test", "w") as f1:
|
|
91
|
-
# a = 2
|
|
92
|
-
# with open("/tmp/test2", "w") as f3:
|
|
93
|
-
# print(4)
|
|
94
|
-
#
|
|
95
|
-
# % python3.9 -m trace -t wwith.py | grep wwith
|
|
96
|
-
# --- modulename: wwith, funcname: <module>
|
|
97
|
-
# wwith.py(1): with open("/tmp/test", "w") as f1:
|
|
98
|
-
# wwith.py(2): a = 2
|
|
99
|
-
# wwith.py(3): with open("/tmp/test2", "w") as f3:
|
|
100
|
-
# wwith.py(4): print(4)
|
|
101
|
-
#
|
|
102
|
-
# % python3.10 -m trace -t wwith.py | grep wwith
|
|
103
|
-
# --- modulename: wwith, funcname: <module>
|
|
104
|
-
# wwith.py(1): with open("/tmp/test", "w") as f1:
|
|
105
|
-
# wwith.py(2): a = 2
|
|
106
|
-
# wwith.py(3): with open("/tmp/test2", "w") as f3:
|
|
107
|
-
# wwith.py(4): print(4)
|
|
108
|
-
# wwith.py(3): with open("/tmp/test2", "w") as f3:
|
|
109
|
-
# wwith.py(1): with open("/tmp/test", "w") as f1:
|
|
110
|
-
#
|
|
111
|
-
exit_through_with = (PYVERSION >= (3, 10, 0, "beta")) # fmt: skip
|
|
112
|
-
|
|
113
56
|
# When leaving a with-block, do we visit the with-line exactly,
|
|
114
57
|
# or the context managers in inner-out order?
|
|
115
58
|
#
|
|
@@ -147,12 +90,6 @@ class PYBEHAVIOR:
|
|
|
147
90
|
|
|
148
91
|
exit_with_through_ctxmgr = (PYVERSION >= (3, 12, 6)) # fmt: skip
|
|
149
92
|
|
|
150
|
-
# Match-case construct.
|
|
151
|
-
match_case = (PYVERSION >= (3, 10)) # fmt: skip
|
|
152
|
-
|
|
153
|
-
# Some words are keywords in some places, identifiers in other places.
|
|
154
|
-
soft_keywords = (PYVERSION >= (3, 10)) # fmt: skip
|
|
155
|
-
|
|
156
93
|
# f-strings are parsed as code, pep 701
|
|
157
94
|
fstring_syntax = (PYVERSION >= (3, 12)) # fmt: skip
|
|
158
95
|
|
coverage/exceptions.py
CHANGED
|
@@ -8,21 +8,15 @@ from __future__ import annotations
|
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class
|
|
12
|
-
"""The base
|
|
11
|
+
class CoverageException(Exception):
|
|
12
|
+
"""The base class of all exceptions raised by Coverage.py."""
|
|
13
13
|
|
|
14
14
|
def __init__(self, *args: Any, slug: str | None = None) -> None:
|
|
15
15
|
super().__init__(*args)
|
|
16
16
|
self.slug = slug
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class CoverageException
|
|
20
|
-
"""The base class of all exceptions raised by Coverage.py."""
|
|
21
|
-
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class ConfigError(_BaseCoverageException):
|
|
19
|
+
class ConfigError(CoverageException):
|
|
26
20
|
"""A problem with a config file, or a value in one."""
|
|
27
21
|
|
|
28
22
|
pass
|
coverage/misc.py
CHANGED
|
@@ -163,31 +163,32 @@ class Hasher:
|
|
|
163
163
|
def update(self, v: Any) -> None:
|
|
164
164
|
"""Add `v` to the hash, recursively if needed."""
|
|
165
165
|
self.hash.update(str(type(v)).encode("utf-8"))
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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)
|
|
191
192
|
self.hash.update(b".")
|
|
192
193
|
|
|
193
194
|
def hexdigest(self) -> str:
|
coverage/parser.py
CHANGED
|
@@ -10,7 +10,6 @@ import collections
|
|
|
10
10
|
import functools
|
|
11
11
|
import os
|
|
12
12
|
import re
|
|
13
|
-
import sys
|
|
14
13
|
import token
|
|
15
14
|
import tokenize
|
|
16
15
|
from collections.abc import Iterable, Sequence
|
|
@@ -299,10 +298,9 @@ class PythonParser:
|
|
|
299
298
|
aaa = AstArcAnalyzer(self.filename, self._ast_root, self.raw_statements, self._multiline)
|
|
300
299
|
aaa.analyze()
|
|
301
300
|
arcs = aaa.arcs
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
arcs = self.fix_with_jumps(arcs)
|
|
301
|
+
self._with_jump_fixers = aaa.with_jump_fixers()
|
|
302
|
+
if self._with_jump_fixers:
|
|
303
|
+
arcs = self.fix_with_jumps(arcs)
|
|
306
304
|
|
|
307
305
|
self._all_arcs = set()
|
|
308
306
|
for l1, l2 in arcs:
|
|
@@ -451,33 +449,11 @@ class ByteParser:
|
|
|
451
449
|
def _line_numbers(self) -> Iterable[TLineNo]:
|
|
452
450
|
"""Yield the line numbers possible in this code object.
|
|
453
451
|
|
|
454
|
-
Uses
|
|
455
|
-
line numbers. Produces a sequence: l0, l1, ...
|
|
452
|
+
Uses co_lines() to produce a sequence: l0, l1, ...
|
|
456
453
|
"""
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
if line:
|
|
461
|
-
yield line
|
|
462
|
-
else:
|
|
463
|
-
# Adapted from dis.py in the standard library.
|
|
464
|
-
byte_increments = self.code.co_lnotab[0::2]
|
|
465
|
-
line_increments = self.code.co_lnotab[1::2]
|
|
466
|
-
|
|
467
|
-
last_line_num: TLineNo | None = None
|
|
468
|
-
line_num = self.code.co_firstlineno
|
|
469
|
-
byte_num = 0
|
|
470
|
-
for byte_incr, line_incr in zip(byte_increments, line_increments):
|
|
471
|
-
if byte_incr:
|
|
472
|
-
if line_num != last_line_num:
|
|
473
|
-
yield line_num
|
|
474
|
-
last_line_num = line_num
|
|
475
|
-
byte_num += byte_incr
|
|
476
|
-
if line_incr >= 0x80:
|
|
477
|
-
line_incr -= 0x100
|
|
478
|
-
line_num += line_incr
|
|
479
|
-
if line_num != last_line_num:
|
|
480
|
-
yield line_num
|
|
454
|
+
for _, _, line in self.code.co_lines():
|
|
455
|
+
if line:
|
|
456
|
+
yield line
|
|
481
457
|
|
|
482
458
|
def _find_statements(self) -> Iterable[TLineNo]:
|
|
483
459
|
"""Find the statements in `self.code`.
|
|
@@ -650,19 +626,6 @@ class TryBlock(Block):
|
|
|
650
626
|
return True
|
|
651
627
|
|
|
652
628
|
|
|
653
|
-
class NodeList(ast.AST):
|
|
654
|
-
"""A synthetic fictitious node, containing a sequence of nodes.
|
|
655
|
-
|
|
656
|
-
This is used when collapsing optimized if-statements, to represent the
|
|
657
|
-
unconditional execution of one of the clauses.
|
|
658
|
-
|
|
659
|
-
"""
|
|
660
|
-
|
|
661
|
-
def __init__(self, body: Sequence[ast.AST]) -> None:
|
|
662
|
-
self.body = body
|
|
663
|
-
self.lineno = body[0].lineno # type: ignore[attr-defined]
|
|
664
|
-
|
|
665
|
-
|
|
666
629
|
# TODO: Shouldn't the cause messages join with "and" instead of "or"?
|
|
667
630
|
|
|
668
631
|
|
|
@@ -673,20 +636,22 @@ def is_constant_test_expr(node: ast.AST) -> tuple[bool, bool]:
|
|
|
673
636
|
handle the kinds of constant expressions people might actually use.
|
|
674
637
|
|
|
675
638
|
"""
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
639
|
+
match node:
|
|
640
|
+
case ast.Constant():
|
|
641
|
+
return True, bool(node.value)
|
|
642
|
+
case ast.Name():
|
|
643
|
+
if node.id in ["True", "False", "None", "__debug__"]:
|
|
644
|
+
return True, eval(node.id) # pylint: disable=eval-used
|
|
645
|
+
case ast.UnaryOp():
|
|
646
|
+
if isinstance(node.op, ast.Not):
|
|
647
|
+
is_constant, val = is_constant_test_expr(node.operand)
|
|
648
|
+
return is_constant, not val
|
|
649
|
+
case ast.BoolOp():
|
|
650
|
+
rets = [is_constant_test_expr(v) for v in node.values]
|
|
651
|
+
is_constant = all(is_const for is_const, _ in rets)
|
|
652
|
+
if is_constant:
|
|
653
|
+
op = any if isinstance(node.op, ast.Or) else all
|
|
654
|
+
return True, op(v for _, v in rets)
|
|
690
655
|
return False, False
|
|
691
656
|
|
|
692
657
|
|
|
@@ -890,14 +855,8 @@ class AstArcAnalyzer:
|
|
|
890
855
|
else:
|
|
891
856
|
return node.lineno
|
|
892
857
|
|
|
893
|
-
def _line__Module(self, node: ast.Module) -> TLineNo:
|
|
894
|
-
|
|
895
|
-
return 1
|
|
896
|
-
elif node.body:
|
|
897
|
-
return self.line_for_node(node.body[0])
|
|
898
|
-
else:
|
|
899
|
-
# Empty modules have no line number, they always start at 1.
|
|
900
|
-
return 1
|
|
858
|
+
def _line__Module(self, node: ast.Module) -> TLineNo: # pylint: disable=unused-argument
|
|
859
|
+
return 1
|
|
901
860
|
|
|
902
861
|
# The node types that just flow to the next node with no complications.
|
|
903
862
|
OK_TO_DEFAULT = {
|
|
@@ -982,98 +941,12 @@ class AstArcAnalyzer:
|
|
|
982
941
|
for body_node in body:
|
|
983
942
|
lineno = self.line_for_node(body_node)
|
|
984
943
|
if lineno not in self.statements:
|
|
985
|
-
|
|
986
|
-
if maybe_body_node is None:
|
|
987
|
-
continue
|
|
988
|
-
body_node = maybe_body_node
|
|
989
|
-
lineno = self.line_for_node(body_node)
|
|
944
|
+
continue
|
|
990
945
|
for prev_start in prev_starts:
|
|
991
946
|
self.add_arc(prev_start.lineno, lineno, prev_start.cause)
|
|
992
947
|
prev_starts = self.node_exits(body_node)
|
|
993
948
|
return prev_starts
|
|
994
949
|
|
|
995
|
-
def find_non_missing_node(self, node: ast.AST) -> ast.AST | None:
|
|
996
|
-
"""Search `node` looking for a child that has not been optimized away.
|
|
997
|
-
|
|
998
|
-
This might return the node you started with, or it will work recursively
|
|
999
|
-
to find a child node in self.statements.
|
|
1000
|
-
|
|
1001
|
-
Returns a node, or None if none of the node remains.
|
|
1002
|
-
|
|
1003
|
-
"""
|
|
1004
|
-
# This repeats work just done in process_body, but this duplication
|
|
1005
|
-
# means we can avoid a function call in the 99.9999% case of not
|
|
1006
|
-
# optimizing away statements.
|
|
1007
|
-
lineno = self.line_for_node(node)
|
|
1008
|
-
if lineno in self.statements:
|
|
1009
|
-
return node
|
|
1010
|
-
|
|
1011
|
-
missing_fn = cast(
|
|
1012
|
-
Optional[Callable[[ast.AST], Optional[ast.AST]]],
|
|
1013
|
-
getattr(self, f"_missing__{node.__class__.__name__}", None),
|
|
1014
|
-
)
|
|
1015
|
-
if missing_fn is not None:
|
|
1016
|
-
ret_node = missing_fn(node)
|
|
1017
|
-
else:
|
|
1018
|
-
ret_node = None
|
|
1019
|
-
return ret_node
|
|
1020
|
-
|
|
1021
|
-
# Missing nodes: _missing__*
|
|
1022
|
-
#
|
|
1023
|
-
# Entire statements can be optimized away by Python. They will appear in
|
|
1024
|
-
# the AST, but not the bytecode. These functions are called (by
|
|
1025
|
-
# find_non_missing_node) to find a node to use instead of the missing
|
|
1026
|
-
# node. They can return None if the node should truly be gone.
|
|
1027
|
-
|
|
1028
|
-
def _missing__If(self, node: ast.If) -> ast.AST | None:
|
|
1029
|
-
# If the if-node is missing, then one of its children might still be
|
|
1030
|
-
# here, but not both. So return the first of the two that isn't missing.
|
|
1031
|
-
# Use a NodeList to hold the clauses as a single node.
|
|
1032
|
-
non_missing = self.find_non_missing_node(NodeList(node.body))
|
|
1033
|
-
if non_missing:
|
|
1034
|
-
return non_missing
|
|
1035
|
-
if node.orelse:
|
|
1036
|
-
return self.find_non_missing_node(NodeList(node.orelse))
|
|
1037
|
-
return None
|
|
1038
|
-
|
|
1039
|
-
def _missing__NodeList(self, node: NodeList) -> ast.AST | None:
|
|
1040
|
-
# A NodeList might be a mixture of missing and present nodes. Find the
|
|
1041
|
-
# ones that are present.
|
|
1042
|
-
non_missing_children = []
|
|
1043
|
-
for child in node.body:
|
|
1044
|
-
maybe_child = self.find_non_missing_node(child)
|
|
1045
|
-
if maybe_child is not None:
|
|
1046
|
-
non_missing_children.append(maybe_child)
|
|
1047
|
-
|
|
1048
|
-
# Return the simplest representation of the present children.
|
|
1049
|
-
if not non_missing_children:
|
|
1050
|
-
return None
|
|
1051
|
-
if len(non_missing_children) == 1:
|
|
1052
|
-
return non_missing_children[0]
|
|
1053
|
-
return NodeList(non_missing_children)
|
|
1054
|
-
|
|
1055
|
-
def _missing__While(self, node: ast.While) -> ast.AST | None:
|
|
1056
|
-
body_nodes = self.find_non_missing_node(NodeList(node.body))
|
|
1057
|
-
if not body_nodes:
|
|
1058
|
-
return None
|
|
1059
|
-
# Make a synthetic While-true node.
|
|
1060
|
-
new_while = ast.While() # type: ignore[call-arg]
|
|
1061
|
-
new_while.lineno = body_nodes.lineno # type: ignore[attr-defined]
|
|
1062
|
-
new_while.test = ast.Name() # type: ignore[call-arg]
|
|
1063
|
-
new_while.test.lineno = body_nodes.lineno # type: ignore[attr-defined]
|
|
1064
|
-
new_while.test.id = "True"
|
|
1065
|
-
assert hasattr(body_nodes, "body")
|
|
1066
|
-
new_while.body = body_nodes.body
|
|
1067
|
-
new_while.orelse = []
|
|
1068
|
-
return new_while
|
|
1069
|
-
|
|
1070
|
-
# In the fullness of time, these might be good tests to write:
|
|
1071
|
-
# while EXPR:
|
|
1072
|
-
# while False:
|
|
1073
|
-
# listcomps hidden deep in other expressions
|
|
1074
|
-
# listcomps hidden in lists: x = [[i for i in range(10)]]
|
|
1075
|
-
# nested function definitions
|
|
1076
|
-
|
|
1077
950
|
# Exit processing: process_*_exits
|
|
1078
951
|
#
|
|
1079
952
|
# These functions process the four kinds of jump exits: break, continue,
|
|
@@ -1192,41 +1065,34 @@ class AstArcAnalyzer:
|
|
|
1192
1065
|
exits |= self.process_body(node.orelse, from_start=from_start)
|
|
1193
1066
|
return exits
|
|
1194
1067
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
case_start,
|
|
1206
|
-
cause="the pattern on line {lineno} never matched",
|
|
1207
|
-
)
|
|
1208
|
-
exits |= self.process_body(case.body, from_start=from_start)
|
|
1209
|
-
last_start = case_start
|
|
1210
|
-
|
|
1211
|
-
# case is now the last case, check for wildcard match.
|
|
1212
|
-
pattern = case.pattern # pylint: disable=undefined-loop-variable
|
|
1213
|
-
while isinstance(pattern, ast.MatchOr):
|
|
1214
|
-
pattern = pattern.patterns[-1]
|
|
1215
|
-
while isinstance(pattern, ast.MatchAs) and pattern.pattern is not None:
|
|
1216
|
-
pattern = pattern.pattern
|
|
1217
|
-
had_wildcard = (
|
|
1218
|
-
isinstance(pattern, ast.MatchAs) and pattern.pattern is None and case.guard is None # pylint: disable=undefined-loop-variable
|
|
1068
|
+
def _handle__Match(self, node: ast.Match) -> set[ArcStart]:
|
|
1069
|
+
start = self.line_for_node(node)
|
|
1070
|
+
last_start = start
|
|
1071
|
+
exits = set()
|
|
1072
|
+
for case in node.cases:
|
|
1073
|
+
case_start = self.line_for_node(case.pattern)
|
|
1074
|
+
self.add_arc(last_start, case_start, "the pattern on line {lineno} always matched")
|
|
1075
|
+
from_start = ArcStart(
|
|
1076
|
+
case_start,
|
|
1077
|
+
cause="the pattern on line {lineno} never matched",
|
|
1219
1078
|
)
|
|
1079
|
+
exits |= self.process_body(case.body, from_start=from_start)
|
|
1080
|
+
last_start = case_start
|
|
1081
|
+
|
|
1082
|
+
# case is now the last case, check for wildcard match.
|
|
1083
|
+
pattern = case.pattern # pylint: disable=undefined-loop-variable
|
|
1084
|
+
while isinstance(pattern, ast.MatchOr):
|
|
1085
|
+
pattern = pattern.patterns[-1]
|
|
1086
|
+
while isinstance(pattern, ast.MatchAs) and pattern.pattern is not None:
|
|
1087
|
+
pattern = pattern.pattern
|
|
1088
|
+
had_wildcard = (
|
|
1089
|
+
isinstance(pattern, ast.MatchAs) and pattern.pattern is None and case.guard is None # pylint: disable=undefined-loop-variable
|
|
1090
|
+
)
|
|
1220
1091
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
return exits
|
|
1226
|
-
|
|
1227
|
-
def _handle__NodeList(self, node: NodeList) -> set[ArcStart]:
|
|
1228
|
-
start = self.line_for_node(node)
|
|
1229
|
-
exits = self.process_body(node.body, from_start=ArcStart(start))
|
|
1092
|
+
if not had_wildcard:
|
|
1093
|
+
exits.add(
|
|
1094
|
+
ArcStart(case_start, cause="the pattern on line {lineno} always matched"),
|
|
1095
|
+
)
|
|
1230
1096
|
return exits
|
|
1231
1097
|
|
|
1232
1098
|
def _handle__Raise(self, node: ast.Raise) -> set[ArcStart]:
|
|
@@ -1301,13 +1167,6 @@ class AstArcAnalyzer:
|
|
|
1301
1167
|
def _handle__While(self, node: ast.While) -> set[ArcStart]:
|
|
1302
1168
|
start = to_top = self.line_for_node(node.test)
|
|
1303
1169
|
constant_test, _ = is_constant_test_expr(node.test)
|
|
1304
|
-
top_is_body0 = False
|
|
1305
|
-
if constant_test:
|
|
1306
|
-
top_is_body0 = True
|
|
1307
|
-
if env.PYBEHAVIOR.keep_constant_test:
|
|
1308
|
-
top_is_body0 = False
|
|
1309
|
-
if top_is_body0:
|
|
1310
|
-
to_top = self.line_for_node(node.body[0])
|
|
1311
1170
|
self.block_stack.append(LoopBlock(start=to_top))
|
|
1312
1171
|
from_start = ArcStart(start, cause="the condition on line {lineno} was never true")
|
|
1313
1172
|
exits = self.process_body(node.body, from_start=from_start)
|
|
@@ -1332,22 +1191,20 @@ class AstArcAnalyzer:
|
|
|
1332
1191
|
starts = [self.line_for_node(item.context_expr) for item in node.items]
|
|
1333
1192
|
else:
|
|
1334
1193
|
starts = [self.line_for_node(node)]
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
self.all_with_starts.add(start)
|
|
1194
|
+
for start in starts:
|
|
1195
|
+
self.current_with_starts.add(start)
|
|
1196
|
+
self.all_with_starts.add(start)
|
|
1339
1197
|
|
|
1340
1198
|
exits = self.process_body(node.body, from_start=ArcStart(starts[-1]))
|
|
1341
1199
|
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
exits = with_exit
|
|
1200
|
+
start = starts[-1]
|
|
1201
|
+
self.current_with_starts.remove(start)
|
|
1202
|
+
with_exit = {ArcStart(start)}
|
|
1203
|
+
if exits:
|
|
1204
|
+
for xit in exits:
|
|
1205
|
+
self.add_arc(xit.lineno, start)
|
|
1206
|
+
self.with_exits.add((xit.lineno, start))
|
|
1207
|
+
exits = with_exit
|
|
1351
1208
|
|
|
1352
1209
|
return exits
|
|
1353
1210
|
|
coverage/patch.py
CHANGED
|
@@ -32,20 +32,21 @@ def apply_patches(
|
|
|
32
32
|
"""Apply invasive patches requested by `[run] patch=`."""
|
|
33
33
|
debug = debug if debug.should("patch") else DevNullDebug()
|
|
34
34
|
for patch in sorted(set(config.patch)):
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
match patch:
|
|
36
|
+
case "_exit":
|
|
37
|
+
_patch__exit(cov, debug)
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
case "execv":
|
|
40
|
+
_patch_execv(cov, config, debug)
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
case "fork":
|
|
43
|
+
_patch_fork(debug)
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
case "subprocess":
|
|
46
|
+
_patch_subprocess(config, debug, make_pth_file)
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
case _:
|
|
49
|
+
raise ConfigError(f"Unknown patch {patch!r}")
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
def _patch__exit(cov: Coverage, debug: TDebugCtl) -> None:
|
coverage/phystokens.py
CHANGED
|
@@ -95,7 +95,7 @@ def find_soft_key_lines(source: str) -> set[TLineNo]:
|
|
|
95
95
|
soft_key_lines: set[TLineNo] = set()
|
|
96
96
|
|
|
97
97
|
for node in ast.walk(ast.parse(source)):
|
|
98
|
-
if
|
|
98
|
+
if isinstance(node, ast.Match):
|
|
99
99
|
soft_key_lines.add(node.lineno)
|
|
100
100
|
for case in node.cases:
|
|
101
101
|
soft_key_lines.add(case.pattern.lineno)
|
|
@@ -128,10 +128,7 @@ def source_token_lines(source: str) -> TSourceTokenLines:
|
|
|
128
128
|
source = source.expandtabs(8).replace("\r\n", "\n")
|
|
129
129
|
tokgen = generate_tokens(source)
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
soft_key_lines = find_soft_key_lines(source)
|
|
133
|
-
else:
|
|
134
|
-
soft_key_lines = set()
|
|
131
|
+
soft_key_lines = find_soft_key_lines(source)
|
|
135
132
|
|
|
136
133
|
for ttype, ttext, (sline, scol), (_, ecol), _ in _phys_tokens(tokgen):
|
|
137
134
|
mark_start = True
|
|
@@ -157,7 +154,7 @@ def source_token_lines(source: str) -> TSourceTokenLines:
|
|
|
157
154
|
if keyword.iskeyword(ttext):
|
|
158
155
|
# Hard keywords are always keywords.
|
|
159
156
|
tok_class = "key"
|
|
160
|
-
elif
|
|
157
|
+
elif keyword.issoftkeyword(ttext):
|
|
161
158
|
# Soft keywords appear at the start of their line.
|
|
162
159
|
if len(line) == 0:
|
|
163
160
|
is_start_of_line = True
|
|
Binary file
|
coverage/types.py
CHANGED
|
@@ -11,7 +11,7 @@ import os
|
|
|
11
11
|
import pathlib
|
|
12
12
|
from collections.abc import Iterable, Mapping
|
|
13
13
|
from types import FrameType, ModuleType
|
|
14
|
-
from typing import TYPE_CHECKING, Any, Callable, Optional, Protocol
|
|
14
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, Protocol
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
17
|
from coverage.plugin import FileTracer
|
|
@@ -22,14 +22,10 @@ AnyCallable = Callable[..., Any]
|
|
|
22
22
|
## File paths
|
|
23
23
|
|
|
24
24
|
# For arguments that are file paths:
|
|
25
|
-
|
|
26
|
-
FilePath = Union[str, os.PathLike[str]]
|
|
27
|
-
else:
|
|
28
|
-
# PathLike < python3.9 doesn't support subscription
|
|
29
|
-
FilePath = Union[str, os.PathLike]
|
|
25
|
+
FilePath = str | os.PathLike[str]
|
|
30
26
|
# For testing FilePath arguments
|
|
31
27
|
FilePathClasses = [str, pathlib.Path]
|
|
32
|
-
FilePathType =
|
|
28
|
+
FilePathType = type[str] | type[pathlib.Path]
|
|
33
29
|
|
|
34
30
|
## Python tracing
|
|
35
31
|
|
|
@@ -77,14 +73,14 @@ class TFileDisposition(Protocol):
|
|
|
77
73
|
# - If measuring arcs in the C tracer, the values are sets of packed arcs (two
|
|
78
74
|
# line numbers combined into one integer).
|
|
79
75
|
|
|
80
|
-
TTraceFileData =
|
|
76
|
+
TTraceFileData = set[TLineNo] | set[TArc] | set[int]
|
|
81
77
|
|
|
82
78
|
TTraceData = dict[str, TTraceFileData]
|
|
83
79
|
|
|
84
80
|
# Functions passed into collectors.
|
|
85
81
|
TShouldTraceFn = Callable[[str, FrameType], TFileDisposition]
|
|
86
82
|
TCheckIncludeFn = Callable[[str, FrameType], bool]
|
|
87
|
-
TShouldStartContextFn = Callable[[FrameType],
|
|
83
|
+
TShouldStartContextFn = Callable[[FrameType], str | None]
|
|
88
84
|
|
|
89
85
|
|
|
90
86
|
class Tracer(Protocol):
|
|
@@ -127,8 +123,8 @@ TCovKwargs = Any
|
|
|
127
123
|
## Configuration
|
|
128
124
|
|
|
129
125
|
# One value read from a config file.
|
|
130
|
-
TConfigValueIn = Optional[
|
|
131
|
-
TConfigValueOut = Optional[
|
|
126
|
+
TConfigValueIn = Optional[bool | int | float | str | Iterable[str] | Mapping[str, Iterable[str]]]
|
|
127
|
+
TConfigValueOut = Optional[bool | int | float | str | list[str] | dict[str, list[str]]]
|
|
132
128
|
# An entire config section, mapping option names to values.
|
|
133
129
|
TConfigSectionIn = Mapping[str, TConfigValueIn]
|
|
134
130
|
TConfigSectionOut = Mapping[str, TConfigValueOut]
|
|
@@ -169,7 +165,7 @@ class TPluginConfig(Protocol):
|
|
|
169
165
|
|
|
170
166
|
## Parsing
|
|
171
167
|
|
|
172
|
-
TMorf =
|
|
168
|
+
TMorf = ModuleType | str
|
|
173
169
|
|
|
174
170
|
TSourceTokenLines = Iterable[list[tuple[str, str]]]
|
|
175
171
|
|
coverage/version.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coverage
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.11.0
|
|
4
4
|
Summary: Code coverage measurement for Python
|
|
5
5
|
Home-page: https://github.com/nedbat/coveragepy
|
|
6
6
|
Author: Ned Batchelder and 249 others
|
|
7
7
|
Author-email: ned@nedbatchelder.com
|
|
8
8
|
License: Apache-2.0
|
|
9
|
-
Project-URL: Documentation, https://coverage.readthedocs.io/en/7.
|
|
9
|
+
Project-URL: Documentation, https://coverage.readthedocs.io/en/7.11.0
|
|
10
10
|
Project-URL: Funding, https://tidelift.com/subscription/pkg/pypi-coverage?utm_source=pypi-coverage&utm_medium=referral&utm_campaign=pypi
|
|
11
11
|
Project-URL: Issues, https://github.com/nedbat/coveragepy/issues
|
|
12
12
|
Project-URL: Mastodon, https://hachyderm.io/@coveragepy
|
|
@@ -17,18 +17,18 @@ Classifier: Intended Audience :: Developers
|
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Programming Language :: Python
|
|
19
19
|
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
24
|
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
27
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
28
28
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
29
29
|
Classifier: Topic :: Software Development :: Testing
|
|
30
30
|
Classifier: Development Status :: 5 - Production/Stable
|
|
31
|
-
Requires-Python: >=3.
|
|
31
|
+
Requires-Python: >=3.10
|
|
32
32
|
Description-Content-Type: text/x-rst
|
|
33
33
|
License-File: LICENSE.txt
|
|
34
34
|
Provides-Extra: toml
|
|
@@ -75,13 +75,13 @@ Coverage.py runs on these versions of Python:
|
|
|
75
75
|
|
|
76
76
|
.. PYVERSIONS
|
|
77
77
|
|
|
78
|
-
* Python 3.
|
|
79
|
-
* PyPy3 versions 3.
|
|
78
|
+
* Python 3.10 through 3.15 alpha, including free-threading.
|
|
79
|
+
* PyPy3 versions 3.10 and 3.11.
|
|
80
80
|
|
|
81
81
|
Documentation is on `Read the Docs`_. Code repository and issue tracker are on
|
|
82
82
|
`GitHub`_.
|
|
83
83
|
|
|
84
|
-
.. _Read the Docs: https://coverage.readthedocs.io/en/7.
|
|
84
|
+
.. _Read the Docs: https://coverage.readthedocs.io/en/7.11.0/
|
|
85
85
|
.. _GitHub: https://github.com/nedbat/coveragepy
|
|
86
86
|
|
|
87
87
|
**New in 7.x:**
|
|
@@ -93,7 +93,7 @@ Documentation is on `Read the Docs`_. Code repository and issue tracker are on
|
|
|
93
93
|
multi-line exclusion patterns;
|
|
94
94
|
function/class reporting;
|
|
95
95
|
experimental support for sys.monitoring;
|
|
96
|
-
dropped support for Python
|
|
96
|
+
dropped support for Python up to 3.9;
|
|
97
97
|
added ``Coverage.collect()`` context manager;
|
|
98
98
|
improved data combining;
|
|
99
99
|
``[run] exclude_also`` setting;
|
|
@@ -131,7 +131,7 @@ Getting Started
|
|
|
131
131
|
Looking to run ``coverage`` on your test suite? See the `Quick Start section`_
|
|
132
132
|
of the docs.
|
|
133
133
|
|
|
134
|
-
.. _Quick Start section: https://coverage.readthedocs.io/en/7.
|
|
134
|
+
.. _Quick Start section: https://coverage.readthedocs.io/en/7.11.0/#quick-start
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
Change history
|
|
@@ -139,7 +139,7 @@ Change history
|
|
|
139
139
|
|
|
140
140
|
The complete history of changes is on the `change history page`_.
|
|
141
141
|
|
|
142
|
-
.. _change history page: https://coverage.readthedocs.io/en/7.
|
|
142
|
+
.. _change history page: https://coverage.readthedocs.io/en/7.11.0/changes.html
|
|
143
143
|
|
|
144
144
|
|
|
145
145
|
Code of Conduct
|
|
@@ -158,7 +158,7 @@ Contributing
|
|
|
158
158
|
Found a bug? Want to help improve the code or documentation? See the
|
|
159
159
|
`Contributing section`_ of the docs.
|
|
160
160
|
|
|
161
|
-
.. _Contributing section: https://coverage.readthedocs.io/en/7.
|
|
161
|
+
.. _Contributing section: https://coverage.readthedocs.io/en/7.11.0/contributing.html
|
|
162
162
|
|
|
163
163
|
|
|
164
164
|
Security
|
|
@@ -186,7 +186,7 @@ Licensed under the `Apache 2.0 License`_. For details, see `NOTICE.txt`_.
|
|
|
186
186
|
:target: https://github.com/nedbat/coveragepy/actions/workflows/quality.yml
|
|
187
187
|
:alt: Quality check status
|
|
188
188
|
.. |docs| image:: https://readthedocs.org/projects/coverage/badge/?version=latest&style=flat
|
|
189
|
-
:target: https://coverage.readthedocs.io/en/7.
|
|
189
|
+
:target: https://coverage.readthedocs.io/en/7.11.0/
|
|
190
190
|
:alt: Documentation
|
|
191
191
|
.. |kit| image:: https://img.shields.io/pypi/v/coverage
|
|
192
192
|
:target: https://pypi.org/project/coverage/
|
|
@@ -195,7 +195,7 @@ Licensed under the `Apache 2.0 License`_. For details, see `NOTICE.txt`_.
|
|
|
195
195
|
:target: https://pypi.org/project/coverage/
|
|
196
196
|
:alt: Python versions supported
|
|
197
197
|
.. |license| image:: https://img.shields.io/pypi/l/coverage.svg
|
|
198
|
-
:target: https://
|
|
198
|
+
:target: https://github.com/nedbat/coveragepy/blob/master/LICENSE.txt
|
|
199
199
|
:alt: License
|
|
200
200
|
.. |metacov| image:: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/nedbat/8c6980f77988a327348f9b02bbaf67f5/raw/metacov.json
|
|
201
201
|
:target: https://nedbat.github.io/coverage-reports/latest.html
|
|
@@ -2,29 +2,29 @@ coverage/__init__.py,sha256=p80cmYrM35VlYk07TtKV90tz0FyOH7HFS_mMqqlkQO8,1103
|
|
|
2
2
|
coverage/__main__.py,sha256=M2jcqCZIu_rkmoO4CKgwElX084u6SHdZfVUg3lGiWhg,307
|
|
3
3
|
coverage/annotate.py,sha256=rcUxalBphRmZePMoSZO8yPCMR7NkdEKsglUmAQV7COM,3863
|
|
4
4
|
coverage/bytecode.py,sha256=eaUA9uzyxoC_T11d4hdxZyRZVhtbNRDUsVlA4_sQ1rQ,6504
|
|
5
|
-
coverage/cmdline.py,sha256=
|
|
6
|
-
coverage/collector.py,sha256=
|
|
7
|
-
coverage/config.py,sha256=
|
|
5
|
+
coverage/cmdline.py,sha256=dCYQCAeO2Vo56W6mrW2WXdV9qy5R7v-lm0LBCPvQHYk,37752
|
|
6
|
+
coverage/collector.py,sha256=JEnp6NKbywHOopu6FXlNDlnk2NbbOqa4kNpx1FoR2zw,19798
|
|
7
|
+
coverage/config.py,sha256=JL7XwK4uoW5wVMjT-hU6cFpgHCimUtUiAEQzSNaSOO4,26033
|
|
8
8
|
coverage/context.py,sha256=YX7Pg0y3Og-d3qDcgoMmEpuf9jIcigcYnF0edZaqIsM,2506
|
|
9
|
-
coverage/control.py,sha256=
|
|
9
|
+
coverage/control.py,sha256=oPZYE10LjV5gJtTEVrhb5hAARXO5DkFJLbxpZu-AF90,56087
|
|
10
10
|
coverage/core.py,sha256=FgNbMrDRj9_ETraUQLjx3baRaUnpmb4CAW32S1DCUqg,4477
|
|
11
11
|
coverage/data.py,sha256=WuNUTfXoytulNWHA-F1OnSfvqu0DgSN7tg9R4ow2CjA,8352
|
|
12
|
-
coverage/debug.py,sha256=
|
|
12
|
+
coverage/debug.py,sha256=rY7n6UYRtIaWjC1Wn764AfH8XjYrvJB3XZcvQAH-bNs,22235
|
|
13
13
|
coverage/disposition.py,sha256=eZmBzTPMmLkDi5OLRNrqtJQMZ4XXh4sHrP1xPEZ50D8,1954
|
|
14
|
-
coverage/env.py,sha256
|
|
15
|
-
coverage/exceptions.py,sha256=
|
|
14
|
+
coverage/env.py,sha256=-QCJcrE6UoJmUzO_3shtviXViblPiYEBEmb6vgrpq0c,5105
|
|
15
|
+
coverage/exceptions.py,sha256=SM3t24dubPw7bB1oAjo2t3M2B-kaJWBudoYsuGX-v4c,1502
|
|
16
16
|
coverage/execfile.py,sha256=TSqB02-3aCYLqPe_ELpD91Y29UVi7EwOLrkTZsZ4pFg,12320
|
|
17
17
|
coverage/files.py,sha256=xXp40_DeEM8oUd-EEtUcvK24YHTxmiHCfhfcgeOTQxc,19908
|
|
18
18
|
coverage/html.py,sha256=9oO7s6BHzoHNaYCldJ_k9oFD4TIMDd0x4wH_jXJaSUw,32238
|
|
19
19
|
coverage/inorout.py,sha256=HbNb7xIolXGyXtohzwgDQCLrO4HkFnGo5oCvws2lqmY,24957
|
|
20
20
|
coverage/jsonreport.py,sha256=wZgntJY2uApDvAdpnNPcrwNvmyb3Tc4XK3fN5L2Opf0,7255
|
|
21
21
|
coverage/lcovreport.py,sha256=OmqTh9rQ2GaIRYADx_3OOhmfZOoG_ocPqbOB9j7Kp_A,8091
|
|
22
|
-
coverage/misc.py,sha256=
|
|
22
|
+
coverage/misc.py,sha256=pvDaKapNAHzE76UaHRqsJuhhmMhgXBJLAYKwEIOwPkI,11662
|
|
23
23
|
coverage/multiproc.py,sha256=PpThtQg0j9NHlYpceNxx5wg9O4XdOjjt03jlI2rkfwI,4293
|
|
24
24
|
coverage/numbits.py,sha256=t7XK_d-I-tVZgRS2M3Y5PG0Pq017D3rvecSipBsT_CA,4817
|
|
25
|
-
coverage/parser.py,sha256=
|
|
26
|
-
coverage/patch.py,sha256=
|
|
27
|
-
coverage/phystokens.py,sha256=
|
|
25
|
+
coverage/parser.py,sha256=vP552qMlBqw-uUwA8Vbf8Cv4W37CxP8BH-3owuojqHg,47437
|
|
26
|
+
coverage/patch.py,sha256=3GHFJnl1scWtvRVhFp2-qPHdAcF8Ve44vdl8xl3C7Oo,5731
|
|
27
|
+
coverage/phystokens.py,sha256=QYlZQBB343TW7SRHhaeo6AoKr9abhMCFjSC4c6aLg3Y,7645
|
|
28
28
|
coverage/plugin.py,sha256=sWFPqm3JrMLRrRNZryP3WmRi3VbGBmCWol9cKEKFYas,22124
|
|
29
29
|
coverage/plugin_support.py,sha256=DWcHXg2Gde0r5XH68sxygXpLGcMlp8H6zDhNOKg6Wc4,10741
|
|
30
30
|
coverage/py.typed,sha256=QhKiyYY18iX2PTjtgwSYebGpYvH_m0bYEyU_kMST7EU,73
|
|
@@ -39,10 +39,10 @@ coverage/sqlitedb.py,sha256=7MmRxX7alrq-Elzx5TzJJNi6xURwUH5mX2Pvgr_Qnp8,10249
|
|
|
39
39
|
coverage/sysmon.py,sha256=u3Oek5ToXFSwjy_x9zOymOWFznRFPT0YxIXyou_QU_Y,17965
|
|
40
40
|
coverage/templite.py,sha256=ETQ1TTufhLF6qlS2kuaX9gg7iQ-c0V6hTlGcInJ0dWA,11116
|
|
41
41
|
coverage/tomlconfig.py,sha256=GtiVV3RzKwj5Z6-RSL8XZFSO5iLfj97dcvqpODkw5Ek,7766
|
|
42
|
-
coverage/tracer.cp313-win_arm64.pyd,sha256=
|
|
42
|
+
coverage/tracer.cp313-win_arm64.pyd,sha256=jqGCgYg9Lsp09kpFcRkZ0PUTRM0IUrwNFkeeUT7RWZE,22016
|
|
43
43
|
coverage/tracer.pyi,sha256=e1YXvQg8IuQaaoP7Tj25It3pNAtv0Mt29DwwxO4KfaM,1248
|
|
44
|
-
coverage/types.py,sha256=
|
|
45
|
-
coverage/version.py,sha256=
|
|
44
|
+
coverage/types.py,sha256=0f03sJRwr4TZItHwZPHNFxL5bhjU1B3ye8C1BVQaUPc,5804
|
|
45
|
+
coverage/version.py,sha256=S45hpB6zMbJnEW8jDIl4pxGE0QjLTKTOJvk5DUXNmhc,1127
|
|
46
46
|
coverage/xmlreport.py,sha256=Wha1LxJgIEqKPO2hVqywTDt3QfPNtk4bgHqxBnog-mA,10133
|
|
47
47
|
coverage/htmlfiles/coverage_html.js,sha256=PqDTAlVdIaB9gIjEf6JHHysMm_D7HyRe4BzQFfpf3OM,26207
|
|
48
48
|
coverage/htmlfiles/favicon_32.png,sha256=vIEA-odDwRvSQ-syWfSwEnWGUWEv2b-Tv4tzTRfwJWE,1732
|
|
@@ -51,9 +51,9 @@ coverage/htmlfiles/keybd_closed.png,sha256=fZv4rmY3DkNJtPQjrFJ5UBOE5DdNof3mdeCZW
|
|
|
51
51
|
coverage/htmlfiles/pyfile.html,sha256=dJV8bc3mMQz6J_N2KxVMXNKVge6vnMiQiqqe1QYuZmw,6643
|
|
52
52
|
coverage/htmlfiles/style.css,sha256=DoE2sbDGB3s5ZrE9QCbgKivfw-HcpTRvtMeXbJn7EjA,16020
|
|
53
53
|
coverage/htmlfiles/style.scss,sha256=ZjH-qCU3X7wrMfepdUhqyYc8gXaqBz6n_M9hTMU93Kw,21737
|
|
54
|
-
coverage-7.
|
|
55
|
-
coverage-7.
|
|
56
|
-
coverage-7.
|
|
57
|
-
coverage-7.
|
|
58
|
-
coverage-7.
|
|
59
|
-
coverage-7.
|
|
54
|
+
coverage-7.11.0.dist-info/licenses/LICENSE.txt,sha256=6z17VIVGasvYHytJb1latjfSeS4mggayfZnnk722dUk,10351
|
|
55
|
+
coverage-7.11.0.dist-info/METADATA,sha256=zNoryzJsdBM_IZJaCVbnOeYW3SizS9bM6TLvHBI_l4s,9178
|
|
56
|
+
coverage-7.11.0.dist-info/WHEEL,sha256=QL7uMKXoDJRpSwAf1VOVpjVXYPYll2YWTJ-omqdO8-4,101
|
|
57
|
+
coverage-7.11.0.dist-info/entry_points.txt,sha256=pnhoSeaPIYrhkvLFbNNfBlAf4ROp08ys-4Bzf9zNz1o,123
|
|
58
|
+
coverage-7.11.0.dist-info/top_level.txt,sha256=BjhyiIvusb5OJkqCXjRncTF3soKF-mDOby-hxkWwwv0,9
|
|
59
|
+
coverage-7.11.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|