Skip to main content

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 → inf when 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, NaN that 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 → NaN is "survived" (IEEE 754 NaN != NaN special-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)

Source distribution for mutaprobe 0.1.0
File Size Uploaded
mutaprobe-0.1.0.tar.gz 9.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mutaprobe 0.1.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page