Skip to main content

pin-versions

A CLI tool and pre-commit hook that pins all unpinned dependencies in pyproject.toml to their currently installed versions.

Why pin versions?

Unpinned dependencies (e.g. requests instead of requests==2.31.0) mean your project silently picks up whatever version happens to be newest at install time. This causes real problems:

  • Broken builds -- a new release of a dependency can introduce breaking changes or bugs that suddenly fail your CI or production deploys, even though your code hasn't changed.
  • "Works on my machine" -- different team members install at different times and get different versions, leading to bugs that are impossible to reproduce.
  • Non-reproducible deployments -- deploying the same commit twice can produce different behavior if a dependency was updated between deploys.
  • Silent security risk -- without knowing exactly what you're running, auditing your dependency tree for vulnerabilities is guesswork.

Pinning gives you control: upgrades happen when you choose, not when a package author publishes.

How versions are resolved

pin-versions first checks what is currently installed in your virtual environment. For any unpinned package that isn't installed locally, the latest version is automatically fetched from PyPI.

A dependency will remain unpinned if:

  • The package name doesn't match -- the name in pyproject.toml differs from the distribution name (underscores vs hyphens, etc.) and can't be matched to an installed package.
  • PyPI lookup fails -- if the network request to PyPI errors out, the package is left as-is rather than guessing.

In all of these cases, pin-versions reports the unpinned packages so you can address them.

Pre-release versions

When fetching versions from PyPI, only stable (non-pre-release) versions are considered by default. Pre-release versions (alpha, beta, release candidates, dev builds) are filtered out. If you need to pin to a pre-release version, pass the --prereleases flag:

pin-versions --prereleases --fix

If a package has only pre-release versions on PyPI, pin-versions will fall back to the latest available version regardless of the --prereleases flag.

Installation

pip install pin-versions

Or with uv:

uv add pin-versions

Usage

Run in a project directory with a pyproject.toml and a virtual environment:

pin-versions

This pins dependencies in [project].dependencies, [project.optional-dependencies], and [dependency-groups].

By default, pin-versions runs in dry-run mode — it shows what would change without modifying the file. Use --fix to apply the pins.

Options

Flag Description
--fix Apply changes to pyproject.toml (default is dry run)
--operator, -o Version pin operator (default: ==). Supports >=, ~=, etc.
--pyproject, -p Path to pyproject.toml (default: ./pyproject.toml)
--venv Path to the virtual environment (default: .venv)
--prereleases Include pre-release versions when fetching from PyPI

Pre-commit hook

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/kjaymiller/pin-versions
    rev: v0.1.0
    hooks:
      - id: pin-versions

Contributing

  1. Fork the repo and clone it locally.
  2. Create a virtual environment and install the project in editable mode:
    uv venv && uv pip install -e ".[dev]"
    
  3. Create a branch for your changes:
    git checkout -b my-feature
    
  4. Make your changes and ensure they work by running:
    pin-versions --dry-run
    
  5. Open a pull request against main.

Metadata

Release files for pin-versions 2026.3.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pin-versions 2026.3.6
File Size Uploaded Provenance
pin_versions-2026.3.6.tar.gz 23.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pin-versions 2026.3.6
File Interpreter ABI Platform
pin_versions-2026.3.6-py3-none-any.whl Python 3 none any Details

Total release size: 30.8 kB

Release files / pin_versions-2026.3.6.tar.gz

Download URL pin_versions-2026.3.6.tar.gz
Size 23.6 kB
Tags Source
SHA-256 checksum
How to use checksums
27084daf47f8a078c860a0ae3e701ad62cc350028d878002b2882a8a2fed5a13
BLAKE2b-256 checksum
How to use checksums
91e42aa002d9c6353125df7fa80bf1874dd680e41c76802e22ffe165d0d66007
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 22, 2026.

Transparency log

Release files / pin_versions-2026.3.6-py3-none-any.whl

Download URL pin_versions-2026.3.6-py3-none-any.whl
Size 7.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1548224ca29ed66aad8468fe787311646cdfa253c7942b1777faa83ae2912f9e
BLAKE2b-256 checksum
How to use checksums
f6d4db231ddf8f7b90178b65bb63bb608820395feb3d9505fbcddd20cbdedf85
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 22, 2026.

Transparency log

Security for pin-versions 2026.3.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pin_versions-2026.3.6.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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