fermut
Agent-first mutation testing for Python — built on
ruff parsing and
ty type-awareness.
New to mutation testing? Line and branch coverage tells you which
lines your tests execute; mutation testing tells you which lines your
tests check. fermut makes small changes to your source (a <= becomes
<, a + becomes -), re-runs your tests, and reports which changes
survived — those are the gaps your tests don't actually catch. In
short: it answers "are my tests any good?"
fermut is designed for coding agents in the loop: machine-readable JSON
reports, deterministic mutant IDs, cache-friendly incremental runs, and
exit codes that gate CI. Under the hood, it generates source-level
mutants via Astral's ruff_python_parser,
drops type-invalid candidates with ty before they reach your test
suite, and runs the survivors in parallel against pytest or
unittest. Hot loop is native Rust; test runner stays Python. Humans
welcome too.
Why fermut
On typer (~2,200 mutants, cold run, same machine):
| Tool | Time | Mutation score |
|---|---|---|
| fermut | 164s | 71.5% |
| mutmut | 298s | 70.5% |
fermut is faster and higher-scoring here — its ty pre-filter
and per-test coverage selection cut wall-clock without dropping
rigor. The win is suite-shaped: on tiny pure-Python libraries with
fast full suites (e.g. more-itertools) mutmut's simpler model still
wins. Full numbers, the repos where mutmut wins, and methodology:
benchmarks.
Documentation
Full documentation lives at https://fermut.readthedocs.io/, sourced
from the docs/ directory in this repo.
Start here:
- Coding agents — agent-driven inner loop, cache strategy, JSON parsing recipes.
- First steps —
fermut initthenfermut run, first report in under five minutes. - Installation — prerequisites and build paths.
- Working on projects — gradual rollout, profile choice, CI integration.
- CLI reference — every subcommand, every flag.
- Configuration reference — every
fermut.tomlkey. - Operators — the full mutation operator catalogue.
- Landscape — vs
mutmutandcosmic-ray. - Migrating? from mutmut /
from cosmic-ray — or run
fermut migrate {mutmut,cosmic-ray}for one-shot translation. - Internals + Adding an operator — contributor onboarding.
Quickstart
# install — pick the path that matches you
uv tool install fermut # prebuilt wheel from PyPI, no Rust needed
cargo install --git https://github.com/KovantAI/fermut --locked # from source: needs Rust + ~2 min first compile
# in your project (needs pytest, coverage, pytest-cov, ty on the same PATH — see Installation)
fermut init # detect source/tests/runner, write fermut.toml
# fermut init wires per-test coverage when pytest-cov is present;
# generate it before the first run (skip if your config has no `coverage` key):
pytest --cov=src --cov-context=test
coverage json -o coverage.json --show-contexts
fermut run src/ --tests tests/ # first mutation report (add -q to silence progress logs)
For a CI gate, generate the opinionated profile instead — diff-only + coverage + a narrow operator set, tuned to fail fast on pull requests:
fermut init --profile pr-gate # writes a CI-shaped fermut.toml (needs git + coverage.json)
It scopes mutation to lines changed vs main, so run it inside a git
checkout with that base available — see
CI quickstart.
Install paths. Prebuilt wheels ship to PyPI, so
uv tool install fermut(orpipx/pip install fermut) is the no-Rust path. Thecargo install --gitpath (Rust required) builds from source — for hacking on fermut or platforms without a prebuilt wheel. Full prerequisites in Installation.
Exit code is non-zero when any mutant survives — wire that into CI to gate on mutation score.
Status
fermut is pre-1.0. The CLI, config schema, and JSON report shape may
change between 0.MINOR releases. See
VERSIONING.md for the full contract.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fermut-0.3.0.tar.gz.
File metadata
- Download URL: fermut-0.3.0.tar.gz
- Upload date:
- Size: 324.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a027a375d8be7678b22fb399fc20e7aaa920c283a56c6a0034159b0118f14d04
|
|
| MD5 |
d04349325f2b4462747dea1401615b9a
|
|
| BLAKE2b-256 |
a1dac2327e0762511c90f1c8a57b231902c3c6e6637410e4586903a92a1a5627
|
Provenance
The following attestation bundles were made for fermut-0.3.0.tar.gz:
Publisher:
release.yml on KovantAI/fermut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fermut-0.3.0.tar.gz -
Subject digest:
a027a375d8be7678b22fb399fc20e7aaa920c283a56c6a0034159b0118f14d04 - Sigstore transparency entry: 2668221592
- Sigstore integration time:
-
Permalink:
KovantAI/fermut@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KovantAI
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Trigger Event:
push
-
Statement type:
File details
Details for the file fermut-0.3.0-py3-none-win_amd64.whl.
File metadata
- Download URL: fermut-0.3.0-py3-none-win_amd64.whl
- Upload date:
- Size: 12.4 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57e9e23313922b8edc089b9a50108c72f064d83f2726428f4791d8abb65a4c7f
|
|
| MD5 |
6232b4cb2132bfcff80fdd07d2b35cd6
|
|
| BLAKE2b-256 |
42b57d93403088209aba910975d19a1eccc686af8eaaa5c7dc5ed75c61fd1743
|
Provenance
The following attestation bundles were made for fermut-0.3.0-py3-none-win_amd64.whl:
Publisher:
release.yml on KovantAI/fermut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fermut-0.3.0-py3-none-win_amd64.whl -
Subject digest:
57e9e23313922b8edc089b9a50108c72f064d83f2726428f4791d8abb65a4c7f - Sigstore transparency entry: 2668221833
- Sigstore integration time:
-
Permalink:
KovantAI/fermut@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KovantAI
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Trigger Event:
push
-
Statement type:
File details
Details for the file fermut-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: fermut-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 12.3 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef41f1d74966a7c44518541ee7ce03c7eb9e9c3a5a5f8fb948fcb5a24bffd9e0
|
|
| MD5 |
563c4e321d412842174c92baf72b6c41
|
|
| BLAKE2b-256 |
2ff0ad59b9bf3be9d6be1167daeeadeb541a67bb30a88b1ae0068365058b1495
|
Provenance
The following attestation bundles were made for fermut-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on KovantAI/fermut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fermut-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
ef41f1d74966a7c44518541ee7ce03c7eb9e9c3a5a5f8fb948fcb5a24bffd9e0 - Sigstore transparency entry: 2668221876
- Sigstore integration time:
-
Permalink:
KovantAI/fermut@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KovantAI
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Trigger Event:
push
-
Statement type:
File details
Details for the file fermut-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: fermut-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 11.7 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7603982b4e049c2cf16728781accd90bb1f203e1318db501fc56837d25b349b2
|
|
| MD5 |
788cea89593ef1acb43fc587a1671c1a
|
|
| BLAKE2b-256 |
adc4820f1ee6456ffc98362c0d73208da023aad52d4a2df3d6f3b0ba9c727537
|
Provenance
The following attestation bundles were made for fermut-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on KovantAI/fermut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fermut-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
7603982b4e049c2cf16728781accd90bb1f203e1318db501fc56837d25b349b2 - Sigstore transparency entry: 2668221922
- Sigstore integration time:
-
Permalink:
KovantAI/fermut@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KovantAI
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Trigger Event:
push
-
Statement type:
File details
Details for the file fermut-0.3.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: fermut-0.3.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 11.5 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30f965818fb1324f594150e7640f559c93e2787f962aa961e964d70c18e628a2
|
|
| MD5 |
3927377e513be51b621e451b012a84e4
|
|
| BLAKE2b-256 |
820940c5b3885ac6918795b2f4542b810fbf699b6aab3a808ea3d2be86cb2ed4
|
Provenance
The following attestation bundles were made for fermut-0.3.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yml on KovantAI/fermut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fermut-0.3.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
30f965818fb1324f594150e7640f559c93e2787f962aa961e964d70c18e628a2 - Sigstore transparency entry: 2668221787
- Sigstore integration time:
-
Permalink:
KovantAI/fermut@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KovantAI
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Trigger Event:
push
-
Statement type:
File details
Details for the file fermut-0.3.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: fermut-0.3.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 12.0 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e323e740a6fc49ae7a0c662a6e0daa905dc70863cb77d87e77026c842386eb03
|
|
| MD5 |
366d36d51e972966a596fc3dac92e756
|
|
| BLAKE2b-256 |
10fc08229ed6903dbeed217e3eafa2ce6a1c0b413963753a6d35c3fccc41a4eb
|
Provenance
The following attestation bundles were made for fermut-0.3.0-py3-none-macosx_10_12_x86_64.whl:
Publisher:
release.yml on KovantAI/fermut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fermut-0.3.0-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
e323e740a6fc49ae7a0c662a6e0daa905dc70863cb77d87e77026c842386eb03 - Sigstore transparency entry: 2668221735
- Sigstore integration time:
-
Permalink:
KovantAI/fermut@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/KovantAI
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c87641cae2d71bc838dd458cf83ad341e43cd9e -
Trigger Event:
push
-
Statement type: