Skip to main content

Parity

PyPI CI Python License

Run old and new code on the same calls. Keep reproducible evidence of what changed.

Parity checks dependency upgrades, backend replacements and rewrites when the old implementation still exists. Targets run in separate processes and can use different Python environments, checkouts or languages. It compares returned values, exceptions and input mutation, then saves confirmed differences for exact replay.

Try a real behaviour difference

Install the controller with Python 3.11 or later:

python -m pip install parity-check

Save these requests as calls.jsonl:

{"args":["hello"]}
{"args":["hello world"]}
{"args":["a/b"]}

Compare two standard-library URL encoders:

parity compare urllib.parse:quote urllib.parse:quote_plus --calls calls.jsonl

The ordinary word matches. Spaces and slashes expose a behavioural difference. Parity exits 1, identifies the first differing call and retains an exact replay artifact. This example needs no application code or configuration.

For your code, supply importable functions and representative requests:

parity compare old_orders:quote new_orders:quote --calls tests/orders.jsonl \
  --json .parity/report.json --junit .parity/junit.xml
parity evidence verify .parity/report.json

Each line is {"args": [...], "kwargs": {...}}; either field may be omitted. Whole calls stay together, including correlated arguments. Exit codes are 0 for matching behaviour, 1 for differences and 2 for invalid or unreliable execution. Numbers compare exactly by default; set --rtol or --atol to accept a tolerance.

A pass covers the supplied calls, not every possible input. Direct comparisons do not generate or shrink inputs. Empty and malformed corpora fail before targets run. See the direct comparison guide for the full contract.

When to use it

Situation Best starting point
Two simple functions in one environment pytest, with Hypothesis if you need generated inputs
An upgrade needs conflicting dependencies Parity with separate target environments
Existing requests must survive a rewrite parity compare --calls
A dataframe migration needs order, dtype, null or numeric policies A configured Parity campaign
Differences need repeatable CI evidence and exact replay Parity reports and retained findings
No examples, reference or agreed behaviour exist Define the contract first; Parity cannot infer it

The value is the integrated isolation, comparison policy and evidence workflow. It does not determine business intent or replace ordinary tests. The usefulness review records the evidence and limitations.

Dependency versions and checkouts

Run an unchanged wrapper in two existing environments:

parity compare migration:run migration:run --calls calls.jsonl \
  --reference-python .venv-old/bin/python \
  --candidate-python .venv-new/bin/python \
  --record-distribution your-library

Each target environment needs its application dependencies and PyArrow, not the full Parity installation. For different source checkouts, add --reference-workdir ../before and --candidate-workdir ../after. The same module name can resolve to different source on each side. Small wrappers can map different APIs into a shared input/output contract.

To have Parity prepare independently locked environments:

parity migration init \
  --reference-path ../before-upgrade \
  --candidate-path ../after-upgrade

Released targets use --reference-package 'your-library==1.2.3' and --candidate-package 'your-library==2.0.0'. See the user guide for setup, review and execution.

Search beyond known examples

parity init
parity check

This creates a runnable example campaign. Replace its functions and input domain with the behaviour you are migrating. Configured campaigns support Hypothesis search, shrinking, dataframe schemas, relational inputs, multiple findings and optional performance measurements after semantic success.

Parity's unit of work is an explicit callable(*args, **kwargs) contract. A complete call can combine ordinary JSON, frames and project-generated structures such as recursive programs and event streams. Install parity-check[pandas] or parity-check[polars] when the controller needs those dataframe adapters.

Use parity.verify for live functions and a Hypothesis strategy. Cross-language targets use the adapter SDK.

For a configured campaign in GitHub Actions:

- uses: leighshepperson/parity@v0
  with:
    config: parity.toml
    performance: "false"

Python and pytest

from parity import compare

result = compare("old_orders:quote", "new_orders:quote", calls="calls.jsonl")
assert result.passed

The pytest fixture adds a readable failure summary:

def test_upgrade(parity):
    parity.compare("old_orders:quote", "new_orders:quote", calls="tests/orders.jsonl")

Executable evidence

Case What it establishes
Pydantic order requests Five supplied calls expose four documented changes; control passes and all findings replay
Generated Pydantic campaign Search and shrinking across conflicting dependency environments
pandas 2.3 → 3.0 An unchanged group-by callable exposes a changed default
PyTimeTK pandas → Polars Five public API comparisons with stock and repaired candidates
JavaScript → Python Recursive programs, domain exceptions and minimized defects
C++ → Python Stateful event streams and replay

These are bounded engineering studies using synthetic inputs, not evidence that every application is compatible or that independent teams have adopted Parity. More studies are listed in the external validation log.

Evidence and boundaries

Terminal, JSON and JUnit reports omit compared values. Finding directories contain actual inputs and outputs; keep them private. parity replay <artifact-directory> reproduces a saved comparison and still exits 1 when the difference remains. parity evidence verify .parity/report.json exits 0 when all findings reproduce. Direct-comparison findings do not need the original calls file to replay.

Targets must be trusted and repeatable. Process isolation handles failures and dependency conflicts; it is not a security sandbox. Wrappers own filesystem, database and network cleanup. For stateful behaviour, pass a complete event stream and reset state within the wrapper. Parity does not capture production traffic.

Need Documentation
Compare existing calls Direct comparison
Build a generated campaign User guide
Look up TOML fields Configuration reference
Integrate with CI GitHub Action
Review intentional differences Compatibility budgets
Retire the old implementation Distilled contracts
Understand execution and evidence Architecture, security

Apache-2.0 licensed and pre-1.0. The current minor release is the supported line; minor releases may change public contracts.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

parity_check-0.21.0.tar.gz (811.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

parity_check-0.21.0-py3-none-any.whl (263.5 kB view details)

Uploaded Python 3

File details

Details for the file parity_check-0.21.0.tar.gz.

File metadata

  • Download URL: parity_check-0.21.0.tar.gz
  • Upload date:
  • Size: 811.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for parity_check-0.21.0.tar.gz
Algorithm Hash digest
SHA256 5ba840b173a6e6fc55a635319c3d3cc98b45783082473be12672cc390c01f89f
MD5 7891735085db2f821c24e0efa032e42d
BLAKE2b-256 dde5664c9044ceffdd9589b3181d092ffc4445959221a8ccef4730b9d1ca30f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for parity_check-0.21.0.tar.gz:

Publisher: release.yml on leighshepperson/parity

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file parity_check-0.21.0-py3-none-any.whl.

File metadata

  • Download URL: parity_check-0.21.0-py3-none-any.whl
  • Upload date:
  • Size: 263.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for parity_check-0.21.0-py3-none-any.whl
Algorithm Hash digest
SHA256 64be26942c73d6619693733ac9a92e36d4744390dd17f61a31c57c563d5ea86b
MD5 98fbb7ef32c3d78e6185f725612439af
BLAKE2b-256 c52985c44b7efc864fe6b6f6646c22f972d0b706ab74b78fec91a487fc21d1ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for parity_check-0.21.0-py3-none-any.whl:

Publisher: release.yml on leighshepperson/parity

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.21.0 This release

2 files

0.20.1

2 files

0.20.0

2 files

0.19.1

2 files

0.19.0

2 files

0.18.1

2 files

0.18.0

2 files

0.17.0

2 files

0.16.0

2 files

0.14.3

2 files

0.14.2

2 files

0.14.1

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.10.0

2 files

0.9.2

2 files

0.9.1

2 files

0.8.0

2 files

0.1.0

2 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