NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1636 most downloaded on PyPI
mutation testing for Python 3
Last release 22 days ago
12 Sep 2026
Ships fairly regularly
a new release about every 2 months
Most releases are documented
notes for 46 of 59 stable releases
5 versions withdrawn
withdrawn after publishing
10 years old
64 releases · first in 2016
feat: mutate ternary conditions by @espressolee in #546
Full Changelog: 3.7.0...3.8.0
One column per quarter.
Fix obsolete test names never being removed from mutants/mutmut-stats.json (#564)
Fix # pragma: no mutate block being silently ignored when placed on an else, except, except* or finally header, and on the try line of a try/except* (#559)
Fix # pragma: no mutate being silently ignored on match and case headers (#554)
Fix mutants being reported as survived when a test uses patch.dict(os.environ, ..., clear=True) (#511, #552)
Fix mutate_only_covered_lines mutating code that coverage.py excludes from measurement (# pragma: no cover, exclude_lines, exclude_also) (#547)
Fix mutations that delete ignored code. Dropping a case from a match, or an argument from a call, is a mutation of the enclosing node, so it used to be made even when the removed lines were themselves ignored (#547)
Fix methods of decorated classes (for example @dataclass) not being mutated (#480, #539)
Fix time measurement including test setup/teardown instead of only the main test run (#544)
Fix mutants stopped by the CPU-time limit being reported as killed instead of timed out (#565)
Fix mutate_only_covered_lines breaking when the test suite imports a dependency that cannot be initialized twice in one process, which raised for numpy and libyaml, produced misleading type errors for cryptography, and segfaulted for asyncpg. Coverage is now gathered in a separate process, so the modules the coverage run imports are no longer unloaded and re-imported in the main process (#528, #566)
Mutate the condition of ternary expressions (#196, #546)
Add a process_isolation config for choosing which process mutant workers are forked from. The new forkserver strategy keeps mutmut's main process free of pytest and your conftest.py, routing every fork through a dedicated fork server process, for test setups that are not fork-safe (gevent, grpc, torch). Tune what it preloads with forkserver_warmup (#578, #566)
Add a badge command that writes a shields.io endpoint file, for publishing the mutation score (#549)
Support python3.15 (#551)
Fix the trampoline dropping a generator's return value, so yield from on a mutated generator no longer yields None instead of its result
Fix the trampoline dropping a generator's return value, so yield from on a mutated generator no longer yields None instead of its result
Fix async generators, so that aclose()/athrow() are handled by the except/finally blocks of the mutated function instead of being swallowed by the trampoline
Fix max_stack_depth when a test changes the working directory (for example via a tmpdir fixture)
Fix type_check_command reporting type errors in copied files that have no mutants
Per-function source hashing for incremental cache invalidation — only re-test mutants in functions that changed
Cross-call dependency tracking — invalidate mutants in callers when a called function changes
Use git to detect non-Python dependency file changes; falls back to a curated file list when git is unavailable
Add cache_invalidation_exclude config to suppress noisy files from change detection
Add use_git_change_detection config (default true) to opt out of git-based detection
Add uv.lock, poetry.lock, Pipfile.lock, and pdm.lock to the list of files copied by default
Invalidate cached results automatically when result-affecting config fields change
Make mutmut browse, show and apply much faster and use far less memory, by storing where each mutant is in the mutated file instead of parsing the whole file to find it
Deprecate tests_dir in favor of pytest_add_cli_args_test_selection
Add # pragma: no mutate block and # pragma: no mutate start/end comments
Add do_not_mutate_patterns to disable mutations with a regex
Add only_mutate config to select which files get mutated
Also mutate methods decorated with (only) @staticmethod or @classmethod
Add use_setproctitle option to disable process renaming (automatically disabled on MacOS)
Add (unstable) timeout_multiplier and timeout_constant options
Rename paths_to_mutate to source_paths
Deprecate tests_dir in favor of pytest_add_cli_args_test_selection
Change max_stack_depth to only consider functions inside source_paths
Disable mutation of enums and @staticmethod/@classmethod methods when type_check_command is set, as these mutations break type checking
Fix mutation for enum class methods
Fix mutate_only_covered_lines when project uses custom coverage.py config
Fix execution when running mutmut via python -m mutmut run
Fix mutation of class _SomePrivateClass class methods
Fix mutation of default args
Fix mutmut browse crash when no file is selected yet
Fix timeout checker looking up the wrong mutant's expected test time, which could cause mutants to hang
Compare stats paths after resolving symlinks
Warn when mutmut cannot match mutants with the collected stats
Filter mutants based on type annotations. This feature needs to be turned on with the type_check_command config.
Filter mutants based on type annotations. This feature needs to be turned on with the type_check_command config.
Show error message when running on Windows
Save mutation stats for use with CI/CD pipeline (#460)
Async functions fixed
Fix for functions with positional only arguments
Support signatures with PEP 649 deferred annotations
Add action to view tests for mutant
Add action to view tests for mutant
Add basic description for all results in mutmut browse
Add description for timeout mutants
Early exit when stats find no tests for any mutant
Support python 3.14
Performance improvements
Fix mutate_only_covered_lines when files are excluded from test run
Add pytest_add_cli_args and pytest_add_cli_args_test_selection configs
mutate_only_covered_lines added to config to control whether coverage.py is used to filter down mutations
Filter out identical string mutants with different values
Handle more exit codes
Disable common order-randomising pytest plugins, as that can seriously deteriorate mutation testing performance
Fixed packaging issue
Increased threshold for mutant timeouts
Increased threshold for mutant timeouts
Added tests_dir config. Accepts a single entry or a list of directories.
Async generators fixes
Fixed bad mutations for certain string escape sequences
Performance fixes
Various internal bug fixes
New argument --show-killed for mutmut browse
Python 3.13 compatibility!
New argument --show-killed for mutmut browse
Fix to avoid accidentally importing the un-mutated original code
Handle segfault for mutant subprocesses
Added mutations for string literals
Added mutations for common string methods
Faster mutant generation via subprocesses
Fix self parameter for mutated class methods
Fix trampoline generation for function calls with 'orig' or 'mutants' as argument names.
Copy full source directory before creating mutants
Improved error message when forced fail test fails
Fixed issue with spaces in the python executable path
Do not mutate __new__
Annotate mutant dicts (and fixes compatibility with Pydantic)
Replaced parso with LibCST
Crash with error message on invalid imports for src module
Crash with error message on invalid imports for src module
Autodetect simpler project configurations with test_*.py in the dir directly
Handle filenames (as opposed to dirnames) in paths_to_mutate
Also copy setup.cfg and pyproject.toml by default
Handle single line paths_to_mutate
Fixed crash when running mutmut results
Fixed crash when running mutmut results
Read paths_to_mutate from config file
Read paths_to_mutate from config file
Mutate break to return to avoid timeouts
Added debug mode. Enable with debug=True in setup.cfg under [mutmut]
Fixed new test detection. The old code incorrectly detected new tests when there were none, creating a much slower interaction loop for fixing mutants.
And many more fixes
Timeouts for mutants implemented.
Timeouts for mutants implemented.
Browser: syntax highlighting for diff view
More fixes for generators.
Fix for src-style layout of projects.
Fixed bug where mutmut would recollect all tests on every run, slowing down startup.
Correctly handle mutation for generator functions (yield).
Correctly handle mutation for generator functions (yield).
Fixed so that from __future__ lines are always first.
If no stats are collected exit directly, as that is a breaking error for mutation testing.
Changed name mangling to make mutants less likely to trigger name-based python magic, like in pytest where functions named test_* have special meaning.
Another attempt to get the pypi package to work
Another attempt to get the pypi package to work
Another attempt to get the pypi package to work
Another attempt to get the pypi package to work
Fixed missing requirement in install package
Fixed missing requirement in install package
Fixed missing file from the install package
Fixed bad entrypoint definition
Fixed bad entrypoint definition
Ignore files that can't be parsed by parso
Missed a file in distribution, so browse command was broken.
Missed a file in distribution, so browse command was broken.
Execution model switched to mutation schemata, which enabled parallel execution.
Execution model switched to mutation schemata, which enabled parallel execution.
New terminal UI
Pytest only, which enabled better integration, cutting execution time significantly.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
New execution model. This should result in some modest speed improvements when using pytest.
New execution model. This should result in some modest speed improvements when using pytest.
A special execution mode when using the hammett test runner. This is MUCH MUCH faster. Please try it!
Dropped support for python < 3.7. If you need to use mutmut on older versions of python, please use mutmut 1.9.0
Some other speed improvements.
mutmut run 7 will always rerun the mutant 7
mutmut run 7 will always rerun the mutant 7
mutmut show <filename> to show all mutants for that file
mutmut run <filename> to run mutation testing on that file
New experimental plugin system: create a file mutmut_config.py in your base directory. In it you can have an init() function, and a pre_mutation(context) function. You can set context.skip = True to skip a mutant, and you can modify context.config.runner, this is useful to limit the tests. Check out the Context class for what information you get.
Better display of mutmut show/mutmut result
Fixed a spurious mutant on assigning a local variable with type annotations
mutmut now will rerun tests without mutation when tests have changed. This avoids a common pitfall of introducing a failing test and then having all m
mutmut now will rerun tests without mutation when tests have changed. This avoids a common pitfall of introducing a failing test and then having all mutants killed incorrectly
Added mutmut html report generation.
Added mutmut html report generation.
Bugfix for multiple assignment. Mutmut used to not handle foo = bar = baz correctly (Thanks Roxane Bellot!)
Bugfix for multiple assignment. Mutmut used to not handle foo = bar = baz correctly (Thanks Roxane Bellot!)
Bugfix for incorrect mutation of "in" operator (Thanks Roxane Bellot!)
Fixed bug where a mutant survived in the internal AST too long. This could cause mutmut to apply more than one mutant at a time.
Vastly improved startup performance when resuming a mutation run.
Added new experimental feature for advanced config at runtime of mutations
Add mutmut show [path to file] command that shows all mutants for a given file
Add mutmut show [path to file] command that shows all mutants for a given file
Better error messages if .coverage file isn't usable
Added support for windows paths in tests
Use the same python executable as mutmut is started as if possible
Dropped python 2 support
Added more assignment operator mutations
Bugfixes
Nothing published for this version
Display all diffs for surviving mutants for a specific file with mutmut show all path/to/file.py
New mutation: None -> ''
Display all diffs for surviving mutants for a specific file with mutmut show all path/to/file.py
Display all diffs for surviving mutants with mutmut show all
Fixed a bug with grouping of the results for mutmut results
Fixed bug where mutmut show X sometimes showed no diff
Fixed bug where mutmut apply X sometimes didn't apply a mutation
Improved error message when trying to find the code
Fixed incorrect help message
New setting: --test-time-base=15.0. This flag can be used to avoid issues with timing.
New setting: --test-time-base=15.0. This flag can be used to avoid issues with timing.
Post and pre hooks for the mutation step: --pre-mutation=command and --post-mutation=command if you want to run some command before and after a mutation testing round.
Fixed a bug with mutation of imports.
Fixed missing newline at end of the output of mutmut.
Support for mutating only lines specified by a patch file: --use-patch-file=foo.patch.
Fixed mutation of arguments in function call.
Looser heuristics for finding the source to mutate. This should mean more projects will just work out of the box.
Fixed mutation of arguments in function call for python 2.7.
Fixed a bug where if mutmut couldn't find the test code it thought the tests hadn't changed. Now mutmut treats this situation as the tests always being changed.
Fixed bug where the function body was skipped for mutation if a return type annotation existed.
Fixed a bug where mutmut crashed if a file contained exactly zero bytes.
Fixed a bug where mutmut crashed if a file contained exactly zero bytes.
Fixed incorrect loading of coverage data when using the --use-coverage flag.
Fixed incorrect loading of coverage data when using the --use-coverage flag.
Fixed a bug when updating the cache.
Fixed incorrect handling of source files that didn't end with a newline.
JUnit XML output: Run mutmut junitxml to output the results as a JUnit compatible XML file.
JUnit XML output: Run mutmut junitxml to output the results as a JUnit compatible XML file.
Python 2 compatibility fixes.
pypy compatibility fixes.
Fixed an issue where mutmut couldn't kill the spawned test process.
Travis tests now test much more thoroughly, both python2, 3, pypy and on windows.
The return code of mutmut now reflects what mutmut found during execution.
New command line option --test-time-multiplier to tweak the detection threshold for mutations that make the code slower.
Fixed compatibility with Windows.
Thanks goes out Marcelo Da Cruz Pinto, Savo Kovačević,
New mutant: mutate the first argument of function calls to None if it's not already None
New mutant: mutate the first argument of function calls to None if it's not already None
Totally overhauled cache system: now handles duplicates lines correctly.
Minor UX fixes: --version command was broken, incorrect documentation shown, missing newline at the very end.
Minor UX fixes: --version command was broken, incorrect documentation shown, missing newline at the very end.
Caching the baseline test time. This makes restarting/rechecking existing mutants much faster, with a small risk of that time being out of date.
Totally new user interface! Should be much easier to understand and it's easier to see that something is happening
Totally new user interface! Should be much easier to understand and it's easier to see that something is happening
Totally new cache handling. Mutmut will now know which mutants are already killed and not try them again, and it will know which mutants to retest if the tests change
Infinite loop detection now works in Python < 3.3
Added --version flag
Nice error message when no .coverage file is found when using the --use-coverage flag
Fixed crash when using --use-coverage flag. Thanks Daniel Hahler!
Added mutation based on finding on tri.struct
Make number_mutation more robust to floats (Thanks Trevin Gandhi!)
Make number_mutation more robust to floats (Thanks Trevin Gandhi!)
Fixed crash when using Python 3 typing to declare a type but not assigning to that variable
Handle annotated assignment in Python 3.6. Thanks William Orr!
Handle annotated assignment in Python 3.6. Thanks William Orr!
Fixed critical bug: mutmut reported killed mutants as surviving and vice versa.
Fixed critical bug: mutmut reported killed mutants as surviving and vice versa.
Fixed an issue where the install failed on some systems.
Handle tests dirs spread out in the file system. This is the normal case for django projects for example.
Fixes for supporting both python 3 and 2.
Misc mutation fixes.
Ability to test a single mutation.
Feature to print the cache (--print-cache).
Turned off error recovery mode for parso. You will now get exceptions for invalid or unsupported python code.
Changed AST library from baron to parso
Changed AST library from baron to parso
Some usability enhancements suggested by David M. Howcraft
Caching of mutation testing results. This is still rather primitive but can in some cases cut down on rerunning mutmut drastically.
Caching of mutation testing results. This is still rather primitive but can in some cases cut down on rerunning mutmut drastically.
New mutation IDs. They are now indexed per line instead of an index for the entire file. This means you can apply your mutations in any order you see fit and the rest of the apply commands will be unaffected.
Fixed bug where initial mutation count was wrong, which caused mutmut to miss mutants at the end of the file
Fixed bug where initial mutation count was wrong, which caused mutmut to miss mutants at the end of the file
Changed mutation API to always require a Context object. This makes is much easier to pass additional data out to the caller
Support specifying individual files to mutate (thanks Felipe Pontes!)
Nothing published for this version
Improve error message when baron crashes a bit (fixes #10)
Improve error message when baron crashes a bit (fixes #10)
New mutation: right hand side of assignments
Fixed nasty bug where applying a mutation could apply a different mutation than the one that was found during mutation testing
Don't assume UNIX (fixes github issue #9: didn't work on windows)
Don't assume UNIX (fixes github issue #9: didn't work on windows)
Nothing published for this version
Changed default runner to add -x flag to pytest. Could radically speed up tests if you're lucky!
Changed default runner to add -x flag to pytest. Could radically speed up tests if you're lucky!
New flag: --show-times
Now warns if a mutation triggers very long test times
Added a workaround for pytest-testmon (all tests deselected is return code 5 even though it's a success)
Fixed bug that made mutmut crash when setup.cfg was missing
Fixed bug that made mutmut crash when setup.cfg was missing
Renamed parameter --testsdir to --tests-dir
Renamed parameter --testsdir to --tests-dir
Refactored handling of setup.cfg file. Much cleaner solution and adds --dict-synonyms command line parameter
Bug with dict param mutations: it mutated all parameters, this could vastly decrease the odds of finding a mutant
Bug with dict param mutations: it mutated all parameters, this could vastly decrease the odds of finding a mutant
New mutation: remove the body or return 0 instead of None
Previous version had broken version on pypi
Previous version had broken version on pypi
Fixed bug where pragma didn't work for decorator mutations
Fixed bug where pragma didn't work for decorator mutations
Dict literals looking like dict(a=foo) now have mutated keys. You can also declare synonyms in setup.cfg.
Fix from x import *
New mutation: remove decorators!
New mutation: remove decorators!
Improved status while running. This should make it easier to handle when you hit mutants that cause infinite loops.
Fixes failing attempts to mutate parentheses. (Thanks Hristo Georgiev!)
Your coding agent can read these notes before it upgrades. Set up the MCP server →