coverage 7.11.2__cp314-cp314t-musllinux_1_2_riscv64.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 +142 -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 +482 -0
  47. coverage/templite.py +306 -0
  48. coverage/tomlconfig.py +210 -0
  49. coverage/tracer.cpython-314t-riscv64-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.2.dist-info/METADATA +221 -0
  55. coverage-7.11.2.dist-info/RECORD +59 -0
  56. coverage-7.11.2.dist-info/WHEEL +5 -0
  57. coverage-7.11.2.dist-info/entry_points.txt +4 -0
  58. coverage-7.11.2.dist-info/licenses/LICENSE.txt +177 -0
  59. coverage-7.11.2.dist-info/top_level.txt +1 -0
coverage/templite.py ADDED
@@ -0,0 +1,306 @@
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
+ """A simple Python template renderer, for a nano-subset of Django syntax.
5
+
6
+ For a detailed discussion of this code, see this chapter from 500 Lines:
7
+ http://aosabook.org/en/500L/a-template-engine.html
8
+
9
+ """
10
+
11
+ # Coincidentally named the same as http://code.activestate.com/recipes/496702/
12
+
13
+ from __future__ import annotations
14
+
15
+ import re
16
+ from typing import Any, Callable, NoReturn, cast
17
+
18
+
19
+ class TempliteSyntaxError(ValueError):
20
+ """Raised when a template has a syntax error."""
21
+
22
+ pass
23
+
24
+
25
+ class TempliteValueError(ValueError):
26
+ """Raised when an expression won't evaluate in a template."""
27
+
28
+ pass
29
+
30
+
31
+ class CodeBuilder:
32
+ """Build source code conveniently."""
33
+
34
+ def __init__(self, indent: int = 0) -> None:
35
+ self.code: list[str | CodeBuilder] = []
36
+ self.indent_level = indent
37
+
38
+ def __str__(self) -> str:
39
+ return "".join(str(c) for c in self.code)
40
+
41
+ def add_line(self, line: str) -> None:
42
+ """Add a line of source to the code.
43
+
44
+ Indentation and newline will be added for you, don't provide them.
45
+
46
+ """
47
+ self.code.extend([" " * self.indent_level, line, "\n"])
48
+
49
+ def add_section(self) -> CodeBuilder:
50
+ """Add a section, a sub-CodeBuilder."""
51
+ section = CodeBuilder(self.indent_level)
52
+ self.code.append(section)
53
+ return section
54
+
55
+ INDENT_STEP = 4 # PEP8 says so!
56
+
57
+ def indent(self) -> None:
58
+ """Increase the current indent for following lines."""
59
+ self.indent_level += self.INDENT_STEP
60
+
61
+ def dedent(self) -> None:
62
+ """Decrease the current indent for following lines."""
63
+ self.indent_level -= self.INDENT_STEP
64
+
65
+ def get_globals(self) -> dict[str, Any]:
66
+ """Execute the code, and return a dict of globals it defines."""
67
+ # A check that the caller really finished all the blocks they started.
68
+ assert self.indent_level == 0
69
+ # Get the Python source as a single string.
70
+ python_source = str(self)
71
+ # Execute the source, defining globals, and return them.
72
+ global_namespace: dict[str, Any] = {}
73
+ exec(python_source, global_namespace)
74
+ return global_namespace
75
+
76
+
77
+ class Templite:
78
+ """A simple template renderer, for a nano-subset of Django syntax.
79
+
80
+ Supported constructs are extended variable access::
81
+
82
+ {{var.modifier.modifier|filter|filter}}
83
+
84
+ loops::
85
+
86
+ {% for var in list %}...{% endfor %}
87
+
88
+ and ifs::
89
+
90
+ {% if var %}...{% endif %}
91
+
92
+ Comments are within curly-hash markers::
93
+
94
+ {# This will be ignored #}
95
+
96
+ Lines between `{% joined %}` and `{% endjoined %}` will have lines stripped
97
+ and joined. Be careful, this could join words together!
98
+
99
+ Any of these constructs can have a hyphen at the end (`-}}`, `-%}`, `-#}`),
100
+ which will collapse the white space following the tag.
101
+
102
+ Construct a Templite with the template text, then use `render` against a
103
+ dictionary context to create a finished string::
104
+
105
+ templite = Templite('''
106
+ <h1>Hello {{name|upper}}!</h1>
107
+ {% for topic in topics %}
108
+ <p>You are interested in {{topic}}.</p>
109
+ {% endif %}
110
+ ''',
111
+ {"upper": str.upper},
112
+ )
113
+ text = templite.render({
114
+ "name": "Ned",
115
+ "topics": ["Python", "Geometry", "Juggling"],
116
+ })
117
+
118
+ """
119
+
120
+ def __init__(self, text: str, *contexts: dict[str, Any]) -> None:
121
+ """Construct a Templite with the given `text`.
122
+
123
+ `contexts` are dictionaries of values to use for future renderings.
124
+ These are good for filters and global values.
125
+
126
+ """
127
+ self.context = {}
128
+ for context in contexts:
129
+ self.context.update(context)
130
+
131
+ self.all_vars: set[str] = set()
132
+ self.loop_vars: set[str] = set()
133
+
134
+ # We construct a function in source form, then compile it and hold onto
135
+ # it, and execute it to render the template.
136
+ code = CodeBuilder()
137
+
138
+ code.add_line("def render_function(context, do_dots):")
139
+ code.indent()
140
+ vars_code = code.add_section()
141
+ code.add_line("result = []")
142
+ code.add_line("append_result = result.append")
143
+ code.add_line("extend_result = result.extend")
144
+ code.add_line("to_str = str")
145
+
146
+ buffered: list[str] = []
147
+
148
+ def flush_output() -> None:
149
+ """Force `buffered` to the code builder."""
150
+ if len(buffered) == 1:
151
+ code.add_line("append_result(%s)" % buffered[0])
152
+ elif len(buffered) > 1:
153
+ code.add_line("extend_result([%s])" % ", ".join(buffered))
154
+ del buffered[:]
155
+
156
+ ops_stack = []
157
+
158
+ # Split the text to form a list of tokens.
159
+ tokens = re.split(r"(?s)({{.*?}}|{%.*?%}|{#.*?#})", text)
160
+
161
+ squash = in_joined = False
162
+
163
+ for token in tokens:
164
+ if token.startswith("{"):
165
+ start, end = 2, -2
166
+ squash = (token[-3] == "-") # fmt: skip
167
+ if squash:
168
+ end = -3
169
+
170
+ if token.startswith("{#"):
171
+ # Comment: ignore it and move on.
172
+ continue
173
+ elif token.startswith("{{"):
174
+ # An expression to evaluate.
175
+ expr = self._expr_code(token[start:end].strip())
176
+ buffered.append("to_str(%s)" % expr)
177
+ else:
178
+ # token.startswith("{%")
179
+ # Action tag: split into words and parse further.
180
+ flush_output()
181
+
182
+ words = token[start:end].strip().split()
183
+ if words[0] == "if":
184
+ # An if statement: evaluate the expression to determine if.
185
+ if len(words) != 2:
186
+ self._syntax_error("Don't understand if", token)
187
+ ops_stack.append("if")
188
+ code.add_line("if %s:" % self._expr_code(words[1]))
189
+ code.indent()
190
+ elif words[0] == "for":
191
+ # A loop: iterate over expression result.
192
+ if len(words) != 4 or words[2] != "in":
193
+ self._syntax_error("Don't understand for", token)
194
+ ops_stack.append("for")
195
+ self._variable(words[1], self.loop_vars)
196
+ code.add_line(
197
+ f"for c_{words[1]} in {self._expr_code(words[3])}:",
198
+ )
199
+ code.indent()
200
+ elif words[0] == "joined":
201
+ ops_stack.append("joined")
202
+ in_joined = True
203
+ elif words[0].startswith("end"):
204
+ # Endsomething. Pop the ops stack.
205
+ if len(words) != 1:
206
+ self._syntax_error("Don't understand end", token)
207
+ end_what = words[0][3:]
208
+ if not ops_stack:
209
+ self._syntax_error("Too many ends", token)
210
+ start_what = ops_stack.pop()
211
+ if start_what != end_what:
212
+ self._syntax_error("Mismatched end tag", end_what)
213
+ if end_what == "joined":
214
+ in_joined = False
215
+ else:
216
+ code.dedent()
217
+ else:
218
+ self._syntax_error("Don't understand tag", words[0])
219
+ else:
220
+ # Literal content. If it isn't empty, output it.
221
+ if in_joined:
222
+ token = re.sub(r"\s*\n\s*", "", token.strip())
223
+ elif squash:
224
+ token = token.lstrip()
225
+ if token:
226
+ buffered.append(repr(token))
227
+
228
+ if ops_stack:
229
+ self._syntax_error("Unmatched action tag", ops_stack[-1])
230
+
231
+ flush_output()
232
+
233
+ for var_name in self.all_vars - self.loop_vars:
234
+ vars_code.add_line(f"c_{var_name} = context[{var_name!r}]")
235
+
236
+ code.add_line("return ''.join(result)")
237
+ code.dedent()
238
+ self._render_function = cast(
239
+ Callable[
240
+ [dict[str, Any], Callable[..., Any]],
241
+ str,
242
+ ],
243
+ code.get_globals()["render_function"],
244
+ )
245
+
246
+ def _expr_code(self, expr: str) -> str:
247
+ """Generate a Python expression for `expr`."""
248
+ if "|" in expr:
249
+ pipes = expr.split("|")
250
+ code = self._expr_code(pipes[0])
251
+ for func in pipes[1:]:
252
+ self._variable(func, self.all_vars)
253
+ code = f"c_{func}({code})"
254
+ elif "." in expr:
255
+ dots = expr.split(".")
256
+ code = self._expr_code(dots[0])
257
+ args = ", ".join(repr(d) for d in dots[1:])
258
+ code = f"do_dots({code}, {args})"
259
+ else:
260
+ self._variable(expr, self.all_vars)
261
+ code = "c_%s" % expr
262
+ return code
263
+
264
+ def _syntax_error(self, msg: str, thing: Any) -> NoReturn:
265
+ """Raise a syntax error using `msg`, and showing `thing`."""
266
+ raise TempliteSyntaxError(f"{msg}: {thing!r}")
267
+
268
+ def _variable(self, name: str, vars_set: set[str]) -> None:
269
+ """Track that `name` is used as a variable.
270
+
271
+ Adds the name to `vars_set`, a set of variable names.
272
+
273
+ Raises an syntax error if `name` is not a valid name.
274
+
275
+ """
276
+ if not re.match(r"[_a-zA-Z][_a-zA-Z0-9]*$", name):
277
+ self._syntax_error("Not a valid name", name)
278
+ vars_set.add(name)
279
+
280
+ def render(self, context: dict[str, Any] | None = None) -> str:
281
+ """Render this template by applying it to `context`.
282
+
283
+ `context` is a dictionary of values to use in this rendering.
284
+
285
+ """
286
+ # Make the complete context we'll use.
287
+ render_context = dict(self.context)
288
+ if context:
289
+ render_context.update(context)
290
+ return self._render_function(render_context, self._do_dots)
291
+
292
+ def _do_dots(self, value: Any, *dots: str) -> Any:
293
+ """Evaluate dotted expressions at run-time."""
294
+ for dot in dots:
295
+ try:
296
+ value = getattr(value, dot)
297
+ except AttributeError:
298
+ try:
299
+ value = value[dot]
300
+ except (TypeError, KeyError) as exc:
301
+ raise TempliteValueError(
302
+ f"Couldn't evaluate {value!r}.{dot}",
303
+ ) from exc
304
+ if callable(value):
305
+ value = value()
306
+ return value
coverage/tomlconfig.py ADDED
@@ -0,0 +1,210 @@
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
+ """TOML configuration support for coverage.py"""
5
+
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ import re
10
+ from collections.abc import Iterable
11
+ from typing import Any, Callable, TypeVar
12
+
13
+ from coverage import config, env
14
+ from coverage.exceptions import ConfigError
15
+ from coverage.misc import import_third_party, isolate_module, substitute_variables
16
+ from coverage.types import TConfigSectionOut, TConfigValueOut
17
+
18
+ os = isolate_module(os)
19
+
20
+ if env.PYVERSION >= (3, 11, 0, "alpha", 7):
21
+ import tomllib # pylint: disable=import-error
22
+
23
+ has_tomllib = True
24
+ else:
25
+ # TOML support on Python 3.10 and below is an install-time extra option.
26
+ tomllib, has_tomllib = import_third_party("tomli")
27
+
28
+
29
+ class TomlDecodeError(Exception):
30
+ """An exception class that exists even when toml isn't installed."""
31
+
32
+ pass
33
+
34
+
35
+ TWant = TypeVar("TWant")
36
+
37
+
38
+ class TomlConfigParser:
39
+ """TOML file reading with the interface of HandyConfigParser."""
40
+
41
+ # This class has the same interface as config.HandyConfigParser, no
42
+ # need for docstrings.
43
+ # pylint: disable=missing-function-docstring
44
+
45
+ def __init__(self, our_file: bool) -> None:
46
+ self.our_file = our_file
47
+ self.data: dict[str, Any] = {}
48
+
49
+ def read(self, filenames: Iterable[str]) -> list[str]:
50
+ # RawConfigParser takes a filename or list of filenames, but we only
51
+ # ever call this with a single filename.
52
+ assert isinstance(filenames, (bytes, str, os.PathLike))
53
+ filename = os.fspath(filenames)
54
+
55
+ try:
56
+ with open(filename, encoding="utf-8") as fp:
57
+ toml_text = fp.read()
58
+ except OSError:
59
+ return []
60
+ if has_tomllib:
61
+ try:
62
+ self.data = tomllib.loads(toml_text)
63
+ except tomllib.TOMLDecodeError as err:
64
+ raise TomlDecodeError(str(err)) from err
65
+ return [filename]
66
+ else:
67
+ has_toml = re.search(r"^\[tool\.coverage(\.|])", toml_text, flags=re.MULTILINE)
68
+ if self.our_file or has_toml:
69
+ # Looks like they meant to read TOML, but we can't read it.
70
+ msg = "Can't read {!r} without TOML support. Install with [toml] extra"
71
+ raise ConfigError(msg.format(filename))
72
+ return []
73
+
74
+ def _get_section(self, section: str) -> tuple[str | None, TConfigSectionOut | None]:
75
+ """Get a section from the data.
76
+
77
+ Arguments:
78
+ section (str): A section name, which can be dotted.
79
+
80
+ Returns:
81
+ name (str): the actual name of the section that was found, if any,
82
+ or None.
83
+ data (str): the dict of data in the section, or None if not found.
84
+
85
+ """
86
+ prefixes = ["tool.coverage."]
87
+ for prefix in prefixes:
88
+ real_section = prefix + section
89
+ parts = real_section.split(".")
90
+ try:
91
+ data = self.data[parts[0]]
92
+ for part in parts[1:]:
93
+ data = data[part]
94
+ except KeyError:
95
+ continue
96
+ break
97
+ else:
98
+ return None, None
99
+ return real_section, data
100
+
101
+ def _get(self, section: str, option: str) -> tuple[str, TConfigValueOut]:
102
+ """Like .get, but returns the real section name and the value."""
103
+ name, data = self._get_section(section)
104
+ if data is None:
105
+ raise ConfigError(f"No section: {section!r}")
106
+ assert name is not None
107
+ try:
108
+ value = data[option]
109
+ except KeyError:
110
+ raise ConfigError(f"No option {option!r} in section: {name!r}") from None
111
+ return name, value
112
+
113
+ def _get_single(self, section: str, option: str) -> Any:
114
+ """Get a single-valued option.
115
+
116
+ Performs environment substitution if the value is a string. Other types
117
+ will be converted later as needed.
118
+ """
119
+ name, value = self._get(section, option)
120
+ if isinstance(value, str):
121
+ value = substitute_variables(value, os.environ)
122
+ return name, value
123
+
124
+ def has_option(self, section: str, option: str) -> bool:
125
+ _, data = self._get_section(section)
126
+ if data is None:
127
+ return False
128
+ return option in data
129
+
130
+ def real_section(self, section: str) -> str | None:
131
+ name, _ = self._get_section(section)
132
+ return name
133
+
134
+ def has_section(self, section: str) -> bool:
135
+ name, _ = self._get_section(section)
136
+ return bool(name)
137
+
138
+ def options(self, section: str) -> list[str]:
139
+ _, data = self._get_section(section)
140
+ if data is None:
141
+ raise ConfigError(f"No section: {section!r}")
142
+ return list(data.keys())
143
+
144
+ def get_section(self, section: str) -> TConfigSectionOut:
145
+ _, data = self._get_section(section)
146
+ return data or {}
147
+
148
+ def get(self, section: str, option: str) -> Any:
149
+ _, value = self._get_single(section, option)
150
+ return value
151
+
152
+ def _check_type(
153
+ self,
154
+ section: str,
155
+ option: str,
156
+ value: Any,
157
+ type_: type[TWant],
158
+ converter: Callable[[Any], TWant] | None,
159
+ type_desc: str,
160
+ ) -> TWant:
161
+ """Check that `value` has the type we want, converting if needed.
162
+
163
+ Returns the resulting value of the desired type.
164
+ """
165
+ if isinstance(value, type_):
166
+ return value
167
+ if isinstance(value, str) and converter is not None:
168
+ try:
169
+ return converter(value)
170
+ except Exception as e:
171
+ raise ValueError(
172
+ f"Option [{section}]{option} couldn't convert to {type_desc}: {value!r}",
173
+ ) from e
174
+ raise ValueError(
175
+ f"Option [{section}]{option} is not {type_desc}: {value!r}",
176
+ )
177
+
178
+ def getboolean(self, section: str, option: str) -> bool:
179
+ name, value = self._get_single(section, option)
180
+ bool_strings = {"true": True, "false": False}
181
+ return self._check_type(name, option, value, bool, bool_strings.__getitem__, "a boolean")
182
+
183
+ def getfile(self, section: str, option: str) -> str:
184
+ _, value = self._get_single(section, option)
185
+ return config.process_file_value(value)
186
+
187
+ def _get_list(self, section: str, option: str) -> tuple[str, list[str]]:
188
+ """Get a list of strings, substituting environment variables in the elements."""
189
+ name, values = self._get(section, option)
190
+ values = self._check_type(name, option, values, list, None, "a list")
191
+ values = [substitute_variables(value, os.environ) for value in values]
192
+ return name, values
193
+
194
+ def getlist(self, section: str, option: str) -> list[str]:
195
+ _, values = self._get_list(section, option)
196
+ return values
197
+
198
+ def getregexlist(self, section: str, option: str) -> list[str]:
199
+ name, values = self._get_list(section, option)
200
+ return config.process_regexlist(name, option, values)
201
+
202
+ def getint(self, section: str, option: str) -> int:
203
+ name, value = self._get_single(section, option)
204
+ return self._check_type(name, option, value, int, int, "an integer")
205
+
206
+ def getfloat(self, section: str, option: str) -> float:
207
+ name, value = self._get_single(section, option)
208
+ if isinstance(value, int):
209
+ value = float(value)
210
+ return self._check_type(name, option, value, float, float, "a float")
coverage/tracer.pyi ADDED
@@ -0,0 +1,43 @@
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
+ """Typing information for the constructs from our .c files."""
5
+
6
+ from typing import Any, Dict
7
+
8
+ from coverage.types import TFileDisposition, TTraceData, TTraceFn, Tracer
9
+
10
+ class CFileDisposition(TFileDisposition):
11
+ """CFileDisposition is in ctracer/filedisp.c"""
12
+
13
+ canonical_filename: Any
14
+ file_tracer: Any
15
+ has_dynamic_filename: Any
16
+ original_filename: Any
17
+ reason: Any
18
+ source_filename: Any
19
+ trace: Any
20
+ def __init__(self) -> None: ...
21
+
22
+ class CTracer(Tracer):
23
+ """CTracer is in ctracer/tracer.c"""
24
+
25
+ check_include: Any
26
+ concur_id_func: Any
27
+ data: TTraceData
28
+ disable_plugin: Any
29
+ file_tracers: Any
30
+ should_start_context: Any
31
+ should_trace: Any
32
+ should_trace_cache: Any
33
+ switch_context: Any
34
+ lock_data: Any
35
+ unlock_data: Any
36
+ trace_arcs: Any
37
+ warn: Any
38
+ def __init__(self) -> None: ...
39
+ def activity(self) -> bool: ...
40
+ def get_stats(self) -> Dict[str, int]: ...
41
+ def reset_activity(self) -> Any: ...
42
+ def start(self) -> TTraceFn: ...
43
+ def stop(self) -> None: ...