Skip to main content

Bisect package versions in PEP 723 Python scripts using git bisect and uv

Project description

script-bisect

Python 3.11+ License: MIT

Bisect package versions in PEP 723 Python scripts using git bisect and uv.

Overview

script-bisect combines the power of git bisect with PEP 723 inline script metadata to automatically find the commit that introduced a regression in a Python package dependency. It works by:

  1. 📄 Parsing your PEP 723 script to extract dependency information
  2. 📥 Cloning the package repository automatically
  3. 🔄 Running git bisect with intelligent test automation
  4. ✏️ Updating package references for each commit tested
  5. 🎯 Finding the exact commit that caused the issue

Perfect for debugging package regressions, testing new features, and creating reliable bug reports.

Super Quick Start 🚀

Point script-bisect directly at a real GitHub issue:

# Bisect a real xarray issue directly from GitHub
uvx script-bisect https://github.com/pydata/xarray/issues/10712 xarray v2025.07.1 v2025.08.0

That's it! script-bisect will:

  1. Extract the code from the GitHub issue
  2. Create a test script automatically
  3. Detect the package and repository
  4. Run the bisection to find the problematic commit

For xarray issue #10712, this will show you exactly which commit introduced the regression!

You can also omit the REFs and fill them in using using the UI

# Bisect a real xarray issue directly from GitHub
uvx script-bisect https://github.com/pydata/xarray/issues/10712 xarray

Installation

Using uvx (Recommended)

uvx script-bisect script.py package_name good_ref bad_ref

Using uv

uv tool install script-bisect
script-bisect script.py package_name good_ref bad_ref

Development Installation

git clone https://github.com/user/script-bisect.git
cd script-bisect
uv sync --extra dev
uv run script-bisect --help

Quick Start

Try It Now! 🚀

Manual Script Method

You can also create your own test script:

1. Create Your Own Script

Create a script that demonstrates your issue:

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "xarray@git+https://github.com/pydata/xarray.git@main",
# ]
# ///

import xarray as xr
import numpy as np

# Your reproducer code here
data = xr.Dataset({'temp': (['time'], np.random.randn(10))})
result = data.some_method()  # This might fail in certain versions
print("✅ Test passed!")

2. Run the Bisection

# Find when something broke
script-bisect bug_report.py xarray v2024.01.0 v2024.03.0

# Find when something was fixed (inverse mode)
script-bisect bug_report.py pandas v1.5.0 v2.0.0 --inverse

3. Get Results

🔍 script-bisect v0.1.0
Bisect package versions in PEP 723 Python scripts

📦 Package: xarray
🔗 Repository: https://github.com/pydata/xarray.git
✅ Good ref: v2024.01.0 (commit: abc123...)
❌ Bad ref: v2024.03.0 (commit: def456...)

🔄 Starting bisection (approximately 7 steps)...

✨ Found first bad commit:

Commit: 234pqr890...
Author: John Doe <john@example.com>
Date: 2024-02-15 10:30:00
Message: Refactor array indexing logic

View on GitHub: https://github.com/pydata/xarray/commit/234pqr890

Usage

Basic Usage

script-bisect SCRIPT PACKAGE GOOD_REF BAD_REF
  • SCRIPT: Path to your PEP 723 Python script
  • PACKAGE: Name of the package to bisect
  • GOOD_REF: Git reference (tag/commit/branch) where it works
  • BAD_REF: Git reference where it's broken

Options

  • --repo-url URL: Override repository URL (auto-detected from git dependencies)
  • --test-command CMD: Custom test command (default: uv run SCRIPT)
  • --inverse: Find when something was fixed (not broken)
  • --keep-clone: Keep cloned repository for inspection
  • --dry-run: Show what would be done without executing
  • --verbose: Enable detailed logging
  • --yes: Auto-confirm all prompts for automated usage
  • --verify-endpoints: Verify good/bad references before starting
  • --refresh-cache: Force refresh of cached repositories and metadata
  • --full-traceback: Show full Python tracebacks on errors

Examples

Basic Package Regression

# Your script has: numpy>=1.24.0
script-bisect reproducer.py numpy 1.24.0 1.26.0

Git Dependency Already Present

# Your script has: xarray@git+https://github.com/pydata/xarray.git@main
script-bisect bug_report.py xarray v2024.01.0 main

Custom Repository

script-bisect test.py numpy v1.24.0 main \\
    --repo-url https://github.com/numpy/numpy.git

Custom Test Command

script-bisect test.py pandas v2.0.0 main \\
    --test-command "python -m pytest {script}"

Finding Fixes (Inverse Mode)

# Find when a bug was fixed
script-bisect regression_test.py scipy v1.10.0 v1.11.0 --inverse

Automated Usage

# Auto-confirm all prompts for CI/automated use
script-bisect test.py numpy v1.24.0 v1.26.0 --yes --verbose

# Force refresh cached data and verify endpoints
script-bisect test.py xarray v2024.01.0 main --refresh-cache --verify-endpoints

Advanced Examples

# Full automation with error details
script-bisect regression.py pandas v1.5.0 v2.0.0 \\
    --yes --full-traceback --keep-clone

# Interactive mode with custom test command
script-bisect integration_test.py requests v2.28.0 v2.31.0 \\
    --test-command "python -m pytest {script} -v"

Requirements

System Requirements

Script Requirements

Your Python script must contain PEP 723 inline metadata with dependencies:

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "package_name>=1.0",
#   # OR for git dependencies:
#   "package_name@git+https://github.com/org/repo.git@ref",
# ]
# ///

The tool will automatically convert PyPI package specs to git dependencies during bisection.

Interactive Features

Parameter Editing

Before starting bisection, you can interactively modify parameters:

🔄 Bisection Summary
[s] 📄 Script     test_script.py
[p] 📦 Package    xarray
[r] 🔗 Repository https://github.com/pydata/xarray.git
[g] ✅ Good ref   v2024.01.0
[b] ❌ Bad ref    v2024.03.0
[t] 🧪 Test command uv run test_script.py
[i] 🔄 Mode       Normal (find when broken)

Press the highlighted key to edit that parameter, or:
  Enter/y - Start bisection
  n/q - Cancel
  • Press any highlighted key (s, p, r, g, b, t, i) to edit that parameter
  • Edit scripts directly in your configured editor (respects git config core.editor)
  • Toggle between normal and inverse bisection modes
  • Modify test commands and repository URLs on the fly

End State Options

After bisection completes, choose what to do next:

  1. Exit - Complete the bisection
  2. Re-run with different refs - Try different good/bad references
  3. Re-run with different script - Edit or change the test script
  4. Re-run with modified parameters - Change package, repo URL, or test command

Intelligent Caching

script-bisect includes a smart caching system for better performance:

  • Repository Caching: Cloned repositories are cached in ~/.cache/script-bisect/repos/
  • Metadata Caching: Package metadata is cached to avoid repeated PyPI lookups
  • Automatic Updates: Cached repos are updated with git fetch for new commits
  • Auto-cleanup: Expired cache entries are cleaned up automatically
  • Force Refresh: Use --refresh-cache to bypass cache and fetch fresh data

Cache locations follow XDG Base Directory standards:

  • Linux/macOS: ~/.cache/script-bisect/
  • Windows: %LOCALAPPDATA%\script-bisect\cache\

How It Works

1. Script Analysis

  • Parses PEP 723 metadata from your script
  • Validates package dependencies and requirements
  • Auto-detects repository URLs for PyPI packages using multiple sources

2. Repository Management

  • Clones the package repository (with intelligent caching)
  • Validates that good/bad references exist
  • Updates cached repositories with latest commits
  • Manages cleanup automatically (unless --keep-clone is used)

3. Bisection Process

  • Uses git bisect run with an automated test script
  • For each commit, updates your script's dependency reference
  • Runs uv run script.py to test the specific commit
  • Returns appropriate exit codes for git bisect (0=good, 1=bad, 125=skip)

4. Result Reporting

  • Identifies the exact problematic commit
  • Shows commit details (author, date, message)
  • Provides GitHub/GitLab links when possible
  • Offers interactive options for follow-up actions

Troubleshooting

Common Issues

"Package not found in dependencies"

  • Ensure the package name matches exactly what's in your dependencies list
  • Use --verbose to see available packages

"Could not auto-detect repository URL"

  • Use --repo-url to specify the repository manually
  • Ensure the package has repository metadata on PyPI

"uv not found"

  • Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh
  • Ensure uv is in your PATH

Test always fails/passes

  • Check your script logic with --dry-run
  • Use --verbose to see test output
  • Verify your script correctly demonstrates the issue

Getting Help

Future Features

Roadmap 🗺️

  • Multiple Package Bisection: Bisect multiple related packages simultaneously
  • PyPI Metadata Lookup: Automatic repository detection for more packages
  • Regression Test Suite: Generate test suites from bisection results
  • CI Integration: GitHub Actions and other CI platform support

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

Development Setup

git clone https://github.com/user/script-bisect.git
cd script-bisect
uv sync --extra dev
uv run pre-commit install

# Run tests
uv run pytest
uv run pytest --cov=script_bisect

# Format and lint
uv run ruff format
uv run ruff check --fix

License

MIT License - see LICENSE for details.

Acknowledgments

  • Built with uv for fast Python package management
  • Inspired by PEP 723 inline script metadata
  • Uses rich for beautiful terminal output

Project details


Download files

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

Source Distribution

script_bisect-0.1.2.tar.gz (5.1 MB view details)

Uploaded Source

Built Distribution

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

script_bisect-0.1.2-py3-none-any.whl (80.1 kB view details)

Uploaded Python 3

File details

Details for the file script_bisect-0.1.2.tar.gz.

File metadata

  • Download URL: script_bisect-0.1.2.tar.gz
  • Upload date:
  • Size: 5.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for script_bisect-0.1.2.tar.gz
Algorithm Hash digest
SHA256 5ee92c131dc7750dce34d12b1779cc00402a9b47c8562131393aa8c7d128621f
MD5 5daa79ebb2aa88cb083a0c765164224b
BLAKE2b-256 18acfbfd9ebaa219a1e198f51386c2cb4e561836edd68d566a47442340a78ca1

See more details on using hashes here.

Provenance

The following attestation bundles were made for script_bisect-0.1.2.tar.gz:

Publisher: publish.yml on ianhi/script-bisect

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

File details

Details for the file script_bisect-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: script_bisect-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 80.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for script_bisect-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e792db919631c6a121895403e3383f08e4eabec0a5572d1f8ace174eb09256f6
MD5 a5c9140c53b8fb15eadce0ba60b457d7
BLAKE2b-256 dc5dabdf542eecfcebb3ce034bc185e1f0a1d09504261fae91a07babe54e5ee9

See more details on using hashes here.

Provenance

The following attestation bundles were made for script_bisect-0.1.2-py3-none-any.whl:

Publisher: publish.yml on ianhi/script-bisect

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

Supported by

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