mutmut 3.3.0__tar.gz → 3.4.0__tar.gz

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 (38) hide show
  1. {mutmut-3.3.0 → mutmut-3.4.0}/HISTORY.rst +47 -1
  2. {mutmut-3.3.0/mutmut.egg-info → mutmut-3.4.0}/PKG-INFO +97 -36
  3. mutmut-3.3.0/PKG-INFO → mutmut-3.4.0/README.rst +73 -44
  4. mutmut-3.4.0/pyproject.toml +62 -0
  5. {mutmut-3.3.0 → mutmut-3.4.0/src}/mutmut/__init__.py +7 -4
  6. {mutmut-3.3.0 → mutmut-3.4.0/src}/mutmut/__main__.py +254 -92
  7. mutmut-3.4.0/src/mutmut/code_coverage.py +64 -0
  8. {mutmut-3.3.0 → mutmut-3.4.0/src}/mutmut/file_mutation.py +20 -42
  9. {mutmut-3.3.0 → mutmut-3.4.0/src}/mutmut/node_mutation.py +42 -12
  10. {mutmut-3.3.0 → mutmut-3.4.0/src}/mutmut/trampoline_templates.py +6 -12
  11. mutmut-3.3.0/AUTHORS.rst +0 -29
  12. mutmut-3.3.0/MANIFEST.in +0 -6
  13. mutmut-3.3.0/README.rst +0 -199
  14. mutmut-3.3.0/mutmut/.DS_Store +0 -0
  15. mutmut-3.3.0/mutmut/__pycache__/__init__.cpython-311.pyc +0 -0
  16. mutmut-3.3.0/mutmut/__pycache__/__init__.cpython-312.pyc +0 -0
  17. mutmut-3.3.0/mutmut/__pycache__/__main__.cpython-311.pyc +0 -0
  18. mutmut-3.3.0/mutmut/__pycache__/__main__.cpython-312.pyc +0 -0
  19. mutmut-3.3.0/mutmut/__pycache__/file_mutation.cpython-312.pyc +0 -0
  20. mutmut-3.3.0/mutmut/__pycache__/node_mutation.cpython-312.pyc +0 -0
  21. mutmut-3.3.0/mutmut/__pycache__/trampoline_templates.cpython-312.pyc +0 -0
  22. mutmut-3.3.0/mutmut.egg-info/SOURCES.txt +0 -41
  23. mutmut-3.3.0/mutmut.egg-info/dependency_links.txt +0 -1
  24. mutmut-3.3.0/mutmut.egg-info/entry_points.txt +0 -2
  25. mutmut-3.3.0/mutmut.egg-info/not-zip-safe +0 -1
  26. mutmut-3.3.0/mutmut.egg-info/requires.txt +0 -8
  27. mutmut-3.3.0/mutmut.egg-info/top_level.txt +0 -2
  28. mutmut-3.3.0/requirements.txt +0 -7
  29. mutmut-3.3.0/setup.cfg +0 -19
  30. mutmut-3.3.0/setup.py +0 -112
  31. mutmut-3.3.0/tests/__init__.py +0 -0
  32. mutmut-3.3.0/tests/e2e/__init__.py +0 -0
  33. mutmut-3.3.0/tests/e2e/test_cli_version.py +0 -9
  34. mutmut-3.3.0/tests/e2e/test_e2e_result_snapshots.py +0 -80
  35. mutmut-3.3.0/tests/test_mutation.py +0 -697
  36. mutmut-3.3.0/tests/test_mutmut3.py +0 -77
  37. {mutmut-3.3.0 → mutmut-3.4.0}/LICENSE +0 -0
  38. {mutmut-3.3.0 → mutmut-3.4.0/src}/mutmut/result_browser_layout.tcss +0 -0
@@ -1,6 +1,52 @@
1
1
  Changelog
2
2
  ---------
3
3
 
4
+ 3.4.0
5
+ ~~~~~
6
+
7
+ * Add action to view tests for mutant
8
+
9
+ * Add basic description for all results in mutmut browse
10
+
11
+ * Add description for timeout mutants
12
+
13
+ * Early exit when stats find no tests for any mutant
14
+
15
+ * Support python 3.14
16
+
17
+ * Performance improvements
18
+
19
+ * Fix `mutate_only_covered_lines` when files are excluded from test run
20
+
21
+ * Add `pytest_add_cli_args` and `pytest_add_cli_args_test_selection` configs
22
+
23
+ * `mutate_only_covered_lines` added to config to control whether coverage.py is used to filter down mutations
24
+
25
+ * Filter out identical string mutants with different values
26
+
27
+ * Handle more exit codes
28
+
29
+ * Disable common order-randomising pytest plugins, as that can seriously deteriorate mutation testing performance
30
+
31
+ * Fixed packaging issue
32
+
33
+
34
+ 3.3.1
35
+ ~~~~~
36
+
37
+ * Increased threshold for mutant timeouts
38
+
39
+ * Added `tests_dir` config. Accepts a single entry or a list of directories.
40
+
41
+ * Async generators fixes
42
+
43
+ * Fixed bad mutations for certain string escape sequences
44
+
45
+ * Performance fixes
46
+
47
+ * Various internal bug fixes
48
+
49
+
4
50
  3.3.0
5
51
  ~~~~~
6
52
 
@@ -127,7 +173,7 @@ Changelog
127
173
  3.0.0
128
174
  ~~~~~
129
175
 
130
- * Execution model switched to mutation schemata, which enabled parallell execution.
176
+ * Execution model switched to mutation schemata, which enabled parallel execution.
131
177
 
132
178
  * New terminal UI
133
179
 
@@ -1,26 +1,34 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: mutmut
3
- Version: 3.3.0
3
+ Version: 3.4.0
4
4
  Summary: mutation testing for Python 3
5
- Home-page: https://github.com/boxed/mutmut
6
5
  Author: Anders Hovmöller
7
- Author-email: boxed@killingar.net
8
- License: BSD
9
- Keywords: mutmut mutant mutation test testing
6
+ Author-email: Anders Hovmöller <boxed@killingar.net>
7
+ License-Expression: BSD-3-Clause
8
+ License-File: LICENSE
10
9
  Classifier: Development Status :: 4 - Beta
11
10
  Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: BSD License
13
11
  Classifier: Natural Language :: English
14
12
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.7
16
- License-File: LICENSE
17
- License-File: AUTHORS.rst
18
- Requires-Dist: libcst~=1.7.0
19
- Requires-Dist: click
20
- Requires-Dist: setproctitle
21
- Requires-Dist: textual
22
- Requires-Dist: toml>=0.10.2; python_version < "3.11"
23
- Requires-Dist: pytest
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Dist: click>=8.0.0
19
+ Requires-Dist: coverage>=7.3.0
20
+ Requires-Dist: libcst>=1.8.5
21
+ Requires-Dist: pytest>=6.2.5
22
+ Requires-Dist: setproctitle>=1.1.0
23
+ Requires-Dist: textual>=1.0.0
24
+ Requires-Dist: toml>=0.10.2 ; python_full_version < '3.11'
25
+ Requires-Python: >=3.10
26
+ Project-URL: Changelog, https://github.com/boxed/mutmut/blob/main/HISTORY.rst
27
+ Project-URL: Documentation, https://mutmut.readthedocs.io/en/latest/
28
+ Project-URL: Homepage, https://github.com/boxed/mutmut
29
+ Project-URL: Issues, https://github.com/boxed/mutmut/issues
30
+ Project-URL: Repository, https://github.com/boxed/mutmut
31
+ Description-Content-Type: text/x-rst
24
32
 
25
33
  mutmut - python mutation tester
26
34
  ===============================
@@ -88,6 +96,23 @@ You can also write a mutant to disk from the `browse` interface, or via
88
96
  source code control and committed before you apply a mutant!
89
97
 
90
98
 
99
+ If during the installation you get an error for the `libcst` dependency mentioning the lack of a rust compiler on your system, it is because your architecture does not have a prebuilt binary for `libcst` and it requires both `rustc` and `cargo` from the [rust toolchain](https://www.rust-lang.org/tools/install) to be built. This is known for at least the `x86_64-darwin` architecture.
100
+
101
+
102
+ Wildcards for testing mutants
103
+ -----------------------------
104
+
105
+ Unix filename pattern matching style on mutants is supported. Example:
106
+
107
+ .. code-block:: console
108
+
109
+ mutmut run "my_module*"
110
+ mutmut run "my_module.my_function*"
111
+
112
+ In the `browse` TUI you can press `f` to retest a function, and `m` to retest
113
+ an entire module.
114
+
115
+
91
116
  Configuration
92
117
  -------------
93
118
 
@@ -97,7 +122,7 @@ In `setup.cfg` in the root of your project you can configure mutmut if you need
97
122
 
98
123
  [mutmut]
99
124
  paths_to_mutate=src/
100
- tests_dir=tests/
125
+ pytest_add_cli_args_test_selection=tests/
101
126
 
102
127
  If you use `pyproject.toml`, you must specify the paths as array in a `tool.mutmut` section:
103
128
 
@@ -105,27 +130,13 @@ If you use `pyproject.toml`, you must specify the paths as array in a `tool.mutm
105
130
 
106
131
  [tool.mutmut]
107
132
  paths_to_mutate = [ "src/" ]
108
- tests_dir = [ "tests/" ]
133
+ pytest_add_cli_args_test_selection= [ "tests/" ]
109
134
 
110
135
  See below for more options for configuring mutmut.
111
136
 
112
137
 
113
- Wildcards for testing mutants
114
- -----------------------------
115
-
116
- Unix filename pattern matching style on mutants is supported. Example:
117
-
118
- .. code-block:: console
119
-
120
- mutmut run "my_module*"
121
- mutmut run "my_module.my_function*"
122
-
123
- In the `browse` TUI you can press `f` to retest a function, and `m` to retest
124
- an entire module.
125
-
126
-
127
138
  "also copy" files
128
- -----------------
139
+ ~~~~~~~~~~~~~~~~~
129
140
 
130
141
  To run the full test suite some files are often needed above the tests and the
131
142
  source. You can configure to copy extra files that you need by adding
@@ -139,7 +150,7 @@ directories and files to `also_copy` in your `setup.cfg`:
139
150
 
140
151
 
141
152
  Limit stack depth
142
- -----------------
153
+ ~~~~~~~~~~~~~~~~~
143
154
 
144
155
  In big code bases some functions are called incidentally by huge swaths of the
145
156
  codebase, but you really don't want tests that hit those executions to count
@@ -163,7 +174,7 @@ caught.
163
174
 
164
175
 
165
176
  Exclude files from mutation
166
- ---------------------------
177
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
167
178
 
168
179
  You can exclude files from mutation in `setup.cfg`:
169
180
 
@@ -173,8 +184,37 @@ You can exclude files from mutation in `setup.cfg`:
173
184
  *__tests.py
174
185
 
175
186
 
187
+ Enable coverage.py filtering of lines to mutate
188
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189
+
190
+ By default, mutmut will mutate only functions that are called. But, if you would like a finer grained (line-level)
191
+ check for coverage, mutmut can use coverage.py to do that.
192
+
193
+ If you only want to mutate lines that are called (according to coverage.py), you can set
194
+ `mutate_only_covered_lines` to `true` in your configuration. The default value is `false`.
195
+
196
+
197
+ .. code-block::
198
+
199
+ mutate_only_covered_lines=true
200
+
201
+
202
+ Enable debug output (increase verbosity)
203
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204
+
205
+ By default, mutmut "swallows" all the test output etc. so that you get a nice clean output.
206
+
207
+ If you want to see all the detail to aid with debugging, you can set `debug` to `true` in your configuration.
208
+ Note that not all displayed errors are necessarily bad. In particular test runs of the mutated code will lead
209
+ to failing tests.
210
+
211
+ .. code-block::
212
+
213
+ debug=true
214
+
215
+
176
216
  Whitelisting
177
- ------------
217
+ ~~~~~~~~~~~~
178
218
 
179
219
  You can mark lines like this:
180
220
 
@@ -190,6 +230,27 @@ whitelist lines are:
190
230
  to continue, but it's slower.
191
231
 
192
232
 
233
+ Modifying pytest arguments
234
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
235
+
236
+ You can add and override pytest arguments:
237
+
238
+ .. code-block:: python
239
+
240
+ # for CLI args that select or deselect tests, use `pytest_add_cli_args_test_selection`
241
+ pytest_add_cli_args_test_selection = ["-m", "not fail", "-k", "test_include"]
242
+
243
+ # for other CLI args, use `pytest_add_cli_args`
244
+ pytest_add_cli_args = ["-p", "no:some_plugin"] # disable a plugin
245
+ pytest_add_cli_args = ["-o", "xfail_strict=False"] # overrides xfail_strict from your normal config
246
+
247
+ # if you want to ignore the normal pytest configuration
248
+ # you can specify a diferent pytest ini file to be used
249
+ pytest_add_cli_args = ["-c", "mutmut_pytest.ini"]
250
+ also_copy = ["mutmut_pytest.ini"]
251
+
252
+
253
+
193
254
  Example mutations
194
255
  -----------------
195
256
 
@@ -1,27 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: mutmut
3
- Version: 3.3.0
4
- Summary: mutation testing for Python 3
5
- Home-page: https://github.com/boxed/mutmut
6
- Author: Anders Hovmöller
7
- Author-email: boxed@killingar.net
8
- License: BSD
9
- Keywords: mutmut mutant mutation test testing
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: BSD License
13
- Classifier: Natural Language :: English
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.7
16
- License-File: LICENSE
17
- License-File: AUTHORS.rst
18
- Requires-Dist: libcst~=1.7.0
19
- Requires-Dist: click
20
- Requires-Dist: setproctitle
21
- Requires-Dist: textual
22
- Requires-Dist: toml>=0.10.2; python_version < "3.11"
23
- Requires-Dist: pytest
24
-
25
1
  mutmut - python mutation tester
26
2
  ===============================
27
3
 
@@ -88,6 +64,23 @@ You can also write a mutant to disk from the `browse` interface, or via
88
64
  source code control and committed before you apply a mutant!
89
65
 
90
66
 
67
+ If during the installation you get an error for the `libcst` dependency mentioning the lack of a rust compiler on your system, it is because your architecture does not have a prebuilt binary for `libcst` and it requires both `rustc` and `cargo` from the [rust toolchain](https://www.rust-lang.org/tools/install) to be built. This is known for at least the `x86_64-darwin` architecture.
68
+
69
+
70
+ Wildcards for testing mutants
71
+ -----------------------------
72
+
73
+ Unix filename pattern matching style on mutants is supported. Example:
74
+
75
+ .. code-block:: console
76
+
77
+ mutmut run "my_module*"
78
+ mutmut run "my_module.my_function*"
79
+
80
+ In the `browse` TUI you can press `f` to retest a function, and `m` to retest
81
+ an entire module.
82
+
83
+
91
84
  Configuration
92
85
  -------------
93
86
 
@@ -97,7 +90,7 @@ In `setup.cfg` in the root of your project you can configure mutmut if you need
97
90
 
98
91
  [mutmut]
99
92
  paths_to_mutate=src/
100
- tests_dir=tests/
93
+ pytest_add_cli_args_test_selection=tests/
101
94
 
102
95
  If you use `pyproject.toml`, you must specify the paths as array in a `tool.mutmut` section:
103
96
 
@@ -105,27 +98,13 @@ If you use `pyproject.toml`, you must specify the paths as array in a `tool.mutm
105
98
 
106
99
  [tool.mutmut]
107
100
  paths_to_mutate = [ "src/" ]
108
- tests_dir = [ "tests/" ]
101
+ pytest_add_cli_args_test_selection= [ "tests/" ]
109
102
 
110
103
  See below for more options for configuring mutmut.
111
104
 
112
105
 
113
- Wildcards for testing mutants
114
- -----------------------------
115
-
116
- Unix filename pattern matching style on mutants is supported. Example:
117
-
118
- .. code-block:: console
119
-
120
- mutmut run "my_module*"
121
- mutmut run "my_module.my_function*"
122
-
123
- In the `browse` TUI you can press `f` to retest a function, and `m` to retest
124
- an entire module.
125
-
126
-
127
106
  "also copy" files
128
- -----------------
107
+ ~~~~~~~~~~~~~~~~~
129
108
 
130
109
  To run the full test suite some files are often needed above the tests and the
131
110
  source. You can configure to copy extra files that you need by adding
@@ -139,7 +118,7 @@ directories and files to `also_copy` in your `setup.cfg`:
139
118
 
140
119
 
141
120
  Limit stack depth
142
- -----------------
121
+ ~~~~~~~~~~~~~~~~~
143
122
 
144
123
  In big code bases some functions are called incidentally by huge swaths of the
145
124
  codebase, but you really don't want tests that hit those executions to count
@@ -163,7 +142,7 @@ caught.
163
142
 
164
143
 
165
144
  Exclude files from mutation
166
- ---------------------------
145
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
167
146
 
168
147
  You can exclude files from mutation in `setup.cfg`:
169
148
 
@@ -173,8 +152,37 @@ You can exclude files from mutation in `setup.cfg`:
173
152
  *__tests.py
174
153
 
175
154
 
155
+ Enable coverage.py filtering of lines to mutate
156
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157
+
158
+ By default, mutmut will mutate only functions that are called. But, if you would like a finer grained (line-level)
159
+ check for coverage, mutmut can use coverage.py to do that.
160
+
161
+ If you only want to mutate lines that are called (according to coverage.py), you can set
162
+ `mutate_only_covered_lines` to `true` in your configuration. The default value is `false`.
163
+
164
+
165
+ .. code-block::
166
+
167
+ mutate_only_covered_lines=true
168
+
169
+
170
+ Enable debug output (increase verbosity)
171
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172
+
173
+ By default, mutmut "swallows" all the test output etc. so that you get a nice clean output.
174
+
175
+ If you want to see all the detail to aid with debugging, you can set `debug` to `true` in your configuration.
176
+ Note that not all displayed errors are necessarily bad. In particular test runs of the mutated code will lead
177
+ to failing tests.
178
+
179
+ .. code-block::
180
+
181
+ debug=true
182
+
183
+
176
184
  Whitelisting
177
- ------------
185
+ ~~~~~~~~~~~~
178
186
 
179
187
  You can mark lines like this:
180
188
 
@@ -190,6 +198,27 @@ whitelist lines are:
190
198
  to continue, but it's slower.
191
199
 
192
200
 
201
+ Modifying pytest arguments
202
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
203
+
204
+ You can add and override pytest arguments:
205
+
206
+ .. code-block:: python
207
+
208
+ # for CLI args that select or deselect tests, use `pytest_add_cli_args_test_selection`
209
+ pytest_add_cli_args_test_selection = ["-m", "not fail", "-k", "test_include"]
210
+
211
+ # for other CLI args, use `pytest_add_cli_args`
212
+ pytest_add_cli_args = ["-p", "no:some_plugin"] # disable a plugin
213
+ pytest_add_cli_args = ["-o", "xfail_strict=False"] # overrides xfail_strict from your normal config
214
+
215
+ # if you want to ignore the normal pytest configuration
216
+ # you can specify a diferent pytest ini file to be used
217
+ pytest_add_cli_args = ["-c", "mutmut_pytest.ini"]
218
+ also_copy = ["mutmut_pytest.ini"]
219
+
220
+
221
+
193
222
  Example mutations
194
223
  -----------------
195
224
 
@@ -0,0 +1,62 @@
1
+ [project]
2
+ name = "mutmut"
3
+ version = "3.4.0"
4
+ description = "mutation testing for Python 3"
5
+ keyowrds = ["mutmut", "mutant", "mutation", "test", "testing"]
6
+ authors = [
7
+ { name = "Anders Hovmöller", email = "boxed@killingar.net" },
8
+ ]
9
+ requires-python = ">=3.10"
10
+ readme = "README.rst"
11
+ license = "BSD-3-Clause"
12
+ license-files = ["LICENSE"]
13
+
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "Natural Language :: English",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
24
+ ]
25
+
26
+ dependencies = [
27
+ "click>=8.0.0",
28
+ "coverage>=7.3.0",
29
+ "libcst>=1.8.5",
30
+ "pytest>=6.2.5",
31
+ "setproctitle>=1.1.0",
32
+ "textual>=1.0.0",
33
+ "toml>=0.10.2 ; python_full_version < '3.11'",
34
+ ]
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/boxed/mutmut"
38
+ Documentation = "https://mutmut.readthedocs.io/en/latest/"
39
+ Repository = "https://github.com/boxed/mutmut"
40
+ Issues = "https://github.com/boxed/mutmut/issues"
41
+ Changelog = "https://github.com/boxed/mutmut/blob/main/HISTORY.rst"
42
+
43
+
44
+ [project.scripts]
45
+ mutmut = "mutmut.__main__:cli"
46
+
47
+ [build-system]
48
+ requires = ["uv_build>=0.9.5,<0.10.0"]
49
+ build-backend = "uv_build"
50
+
51
+ [tool.uv.build-backend]
52
+ source-include = ["HISTORY.rst"]
53
+
54
+ [dependency-groups]
55
+ dev = [
56
+ "pytest-asyncio>=1.0.0",
57
+ ]
58
+
59
+ [tool.pytest.ini_options]
60
+ testpaths = [
61
+ "tests",
62
+ ]
@@ -1,21 +1,24 @@
1
+ import importlib.metadata
1
2
  from collections import defaultdict
2
3
 
3
- __version__ = '3.3.0'
4
+ __version__ = importlib.metadata.version("mutmut")
4
5
 
5
6
 
6
- duration_by_test = {}
7
+ duration_by_test = defaultdict(float)
7
8
  stats_time = None
8
9
  config = None
9
10
 
10
11
  _stats = set()
11
12
  tests_by_mangled_function_name = defaultdict(set)
12
-
13
+ _covered_lines = None
13
14
 
14
15
  def _reset_globals():
15
16
  global duration_by_test, stats_time, config, _stats, tests_by_mangled_function_name
17
+ global _covered_lines
16
18
 
17
- duration_by_test = {}
19
+ duration_by_test.clear()
18
20
  stats_time = None
19
21
  config = None
20
22
  _stats = set()
21
23
  tests_by_mangled_function_name = defaultdict(set)
24
+ _covered_lines = None