Skip to main content

Bumpcheck

Catch Pydantic runtime behavior changes before a dependency bump.

Bumpcheck runs one small application contract in two isolated Python environments and compares what users can observe: returned JSON, Pydantic validation errors, warnings, and captured output.

Quickstart

Install uv, then install Bumpcheck:

uv tool install bumpcheck

Create contract.py:

from collections.abc import Mapping
from typing import Annotated

from pydantic import BaseModel, ConfigDict, Field

MetadataKey = Annotated[str, Field(max_length=3)]


class Model(BaseModel):
    model_config = ConfigDict(strict=True)
    metadata: Mapping[MetadataKey, str]


def run():
    return Model(metadata={"toolong": "b"}).model_dump(mode="json")

Run it against two versions:

$ bumpcheck check contract.py \
    --baseline pydantic==2.10.6 \
    --candidate pydantic==2.11.1 \
    --python-version 3.12
BASELINE pydantic=2.10.6 @ .../pydantic/__init__.py
CANDIDATE pydantic=2.11.1 @ .../pydantic/__init__.py
CHANGED contract: ValidationError[string_too_long] -> return {"metadata":{"toolong":"b"}}

Exit code 0 means unchanged, 1 means behavior changed, and 2 means the capture was not trustworthy. This makes the command usable as a CI gate.

Check your application

A contract is a normal Python file exposing either run() or run(value). Return a JSON-compatible value that represents the behavior your application depends on.

Use --with . to install the current project into both isolated environments:

bumpcheck check contract.py \
  --baseline pydantic==2.10.6 \
  --candidate pydantic==2.11.1 \
  --with .

Repeat --with for shared dependencies. Use --watch DIST[:MODULE] to record their exact versions and import locations alongside the default pydantic and pydantic-core records.

For real payloads, define run(value) and pass --inputs. Bumpcheck accepts a JSON array, .jsonl or .ndjson, or a Pydantic Evals JSON document containing a cases array. It preserves case names or JSON Lines source line numbers and hashes the case and input bytes before comparing results.

If environments already exist, use --baseline-python and --candidate-python instead of requirement targets. Use --json for a machine-readable report and --exact when warning messages, exception messages, stdout, and stderr must also match.

Scope and limits

Bumpcheck is a focused pre-upgrade gate, not a test runner or an API/schema diff. It is useful for data-dependent validation and serialization behavior that ordinary dependency tooling does not observe.

Cases are trusted code. The subprocess boundary enforces a timeout but is not a security sandbox. Receipts contain local interpreter and module paths, so review JSON output before sharing it. Imported project files are not hashed; run from an immutable revision when they are part of the contract.

Migration

Bumpcheck was previously named Pydantic Canary. The bumpcheck distribution installs a temporary pydantic-canary command alias, but new code should import bumpcheck and use the bumpcheck command.

Development

uv run --isolated --no-project --no-config --no-cache --with . -- \
  python -B -m unittest discover -s tests -v
uv run --isolated --no-project --no-config --with ruff==0.16.4 -- ruff check .
uv build

Download files

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

Source Distribution

bumpcheck-0.2.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

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

bumpcheck-0.2.0-py3-none-any.whl (13.4 kB view details)

Uploaded Python 3

File details

Details for the file bumpcheck-0.2.0.tar.gz.

File metadata

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

File hashes

Hashes for bumpcheck-0.2.0.tar.gz
Algorithm Hash digest
SHA256 81b8e597fde9e5b20188fc8a82fb6e8d06bf677d07e40512362842854e0f625b
MD5 8c164006c3bbacbcb9295bc59809c49a
BLAKE2b-256 7da786d4088db7136b492140c6e030a8884a75196962fafd40a7b30dc8fee73a

See more details on using hashes here.

Provenance

The following attestation bundles were made for bumpcheck-0.2.0.tar.gz:

Publisher: release.yml on smigolsmigol/bumpcheck

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

File details

Details for the file bumpcheck-0.2.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for bumpcheck-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a4e48b6aaefd8d0f6a8debbb51f5ed725ea801baf5f6aec7098c1f70ac6067e4
MD5 f17fcff44cdb070bc251a655ed67ad19
BLAKE2b-256 66d44034a5241af5de5c45ceea4b2f070031a9ee6aefd164fca460d36dcdc067

See more details on using hashes here.

Provenance

The following attestation bundles were made for bumpcheck-0.2.0-py3-none-any.whl:

Publisher: release.yml on smigolsmigol/bumpcheck

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

Release history Release notifications | RSS feed

0.2.1

2 files

This release

0.2.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page