mutaprobe
Detect silent data mutations when values cross format boundaries. Zero false positives by construction.
When you serialize, deserialize, cast, transfer, or convert data, some values silently change — precision loss, type coercion, sign-bit collapse, range overflow. These mutations don't crash; they corrupt data quietly. mutaprobe finds them.
How it works
mutaprobe generates a fixed set of adversarial edge-case values (IEEE 754 specials, precision boundaries, arbitrary-precision integers, Unicode variants, NULL-vs-empty, types serializers reject), pushes each through your conversion function, and flags any value whose type or value changed — by exact comparison.
Every flag is a real mutation. There is no probabilistic detection, no threshold tuning, no false positives. The comparison is deterministic and type-strict; the flag fires if and only if strict_equal(input, output) is False.
Install
pip install mutaprobe
Use
Probe a conversion function:
from mutaprobe import probe
def my_conversion(v):
# serialize -> deserialize, cast, transfer, etc.
return v
mutations = probe(my_conversion)
for m in mutations:
print(m)
Or via CLI:
# Exit 0 = clean, exit 1 = mutations found
mutaprobe probe mymodule:convert_function
# CI mode (exit code only, no output)
mutaprobe probe mymodule:convert_function --quiet
Example
import json
from mutaprobe import probe
def json_roundtrip(v):
return json.loads(json.dumps({"v": v}))["v"]
for m in probe(json_roundtrip):
print(m)
Output:
[type-change] tuple: (1, 2, 3) -> [1, 2, 3] (tuple became list)
[crash] decimal: Decimal('99999999999999999999.999999') -> TypeError: ... (conversion raised an exception)
[crash] bytes: b'hello' -> TypeError: ... (conversion raised an exception)
What it catches
- Type mutations —
tuple→list,int→float,Decimal→float - Silent value changes —
0.1→0.10000000149011612(float64 → float32), precision loss - Range overflow — finite →
infwhen a value exceeds the target's range - Sign-bit collapse —
-0.0→0.0(the sign bit is data) - Crashes on edge values —
Decimal,bytes,NaNthat serializers reject
What it does NOT catch
- Semantic drift — a column keeping its name/type but changing meaning. That requires probabilistic reasoning (NLP/LLM-as-judge), which is inherently false-positive-prone and outside mutaprobe's zero-FP class.
- Distribution shifts — value distributions changing over time. Use a data observability tool.
- Logic errors in your conversion — if your function is wrong but consistent, mutaprobe won't flag it (it detects mutations, not bugs).
The zero-FP guarantee
The flag fires iff strict_equal(input, output) is False. strict_equal is:
- Type-strict —
1 != 1.0,True != 1 - NaN-aware —
NaN → NaNis "survived" (IEEE 754NaN != NaNspecial-cased) - Sign-aware —
-0.0 != 0.0(the sign bit is data) - Code-point-exact — no Unicode normalization
Because the comparison is deterministic, every flag corresponds to a real type or value difference. There is no tuning, no threshold, no "maybe."
Scope
mutaprobe probes one conversion function at a time. It does not generate schema-aware values (pass a conversion that takes dicts if you want to probe structured data). It does not test pipelines (wrap your pipeline as a single function). Keeping the scope narrow is the point — one feature, done precisely.
License
MIT
Metadata
Release files for mutaprobe 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mutaprobe-0.1.0.tar.gz | 9.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mutaprobe-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.5 kB
Release files / mutaprobe-0.1.0.tar.gz
| Download URL | mutaprobe-0.1.0.tar.gz |
|---|---|
| Size | 9.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a58a787c3c9eca32a0229b7a907a2b87b5362c96215f6c5a87e0020c86871337
|
|
BLAKE2b-256 checksum How to use checksums |
c5ac914259e44d7a96c81470444867fd5e8810d2459da08cc9cd5430e180bbb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / mutaprobe-0.1.0-py3-none-any.whl
| Download URL | mutaprobe-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
83782c44c66d78147caa5cebff948e399e7a47799de833ddb15bbf8b900e676a
|
|
BLAKE2b-256 checksum How to use checksums |
631d95c19a055ce4a271615670f30f7ab77fc07ab451f0b2ecf6e079869ab3d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|