every-python 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- every_python-0.2.0/.github/workflows/build.yml +33 -0
- every_python-0.2.0/.github/workflows/integration.yml +77 -0
- every_python-0.2.0/.github/workflows/lint.yml +40 -0
- every_python-0.2.0/.github/workflows/test.yml +59 -0
- every_python-0.2.0/.github/workflows/typecheck.yml +39 -0
- every_python-0.2.0/.gitignore +32 -0
- every_python-0.2.0/.pre-commit-config.yaml +28 -0
- every_python-0.2.0/.python-version +1 -0
- every_python-0.2.0/LICENSE +21 -0
- every_python-0.2.0/PKG-INFO +198 -0
- every_python-0.2.0/README.md +172 -0
- every_python-0.2.0/every_python/__init__.py +3 -0
- every_python-0.2.0/every_python/main.py +666 -0
- every_python-0.2.0/every_python/output.py +150 -0
- every_python-0.2.0/every_python/runner.py +78 -0
- every_python-0.2.0/every_python/utils.py +275 -0
- every_python-0.2.0/pyproject.toml +70 -0
- every_python-0.2.0/pytest.ini +9 -0
- every_python-0.2.0/tests/__init__.py +1 -0
- every_python-0.2.0/tests/test_main.py +417 -0
- every_python-0.2.0/tests/test_utils.py +361 -0
- every_python-0.2.0/uv.lock +233 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build-and-publish:
|
|
14
|
+
name: Build and publish Python distribution to PyPI
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v5
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v7
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v6
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.14"
|
|
28
|
+
|
|
29
|
+
- name: Build package
|
|
30
|
+
run: uv build
|
|
31
|
+
|
|
32
|
+
- name: Publish to PyPI
|
|
33
|
+
run: uv publish
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: Integration Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches: [ main ]
|
|
7
|
+
paths:
|
|
8
|
+
- 'every_python/**'
|
|
9
|
+
- '.github/workflows/integration.yml'
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [ main ]
|
|
12
|
+
paths:
|
|
13
|
+
- 'every_python/**'
|
|
14
|
+
- '.github/workflows/integration.yml'
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
integration:
|
|
18
|
+
runs-on: ${{ matrix.runner }}
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: false
|
|
21
|
+
matrix:
|
|
22
|
+
include:
|
|
23
|
+
- runner: ubuntu-24.04
|
|
24
|
+
os: Linux
|
|
25
|
+
- runner: windows-2022
|
|
26
|
+
os: Windows
|
|
27
|
+
- runner: macos-14
|
|
28
|
+
os: macOS
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v5
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.14"
|
|
36
|
+
|
|
37
|
+
- name: Install system dependencies (Linux)
|
|
38
|
+
if: runner.os == 'Linux'
|
|
39
|
+
run: |
|
|
40
|
+
sudo apt-get update
|
|
41
|
+
sudo apt-get install -y lsof
|
|
42
|
+
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh 20
|
|
43
|
+
echo "$(llvm-config-20 --bindir)" >> $GITHUB_PATH
|
|
44
|
+
|
|
45
|
+
- name: Install LLVM (macOS)
|
|
46
|
+
if: runner.os == 'macOS'
|
|
47
|
+
run: brew install llvm@20
|
|
48
|
+
|
|
49
|
+
- name: Install uv
|
|
50
|
+
uses: astral-sh/setup-uv@v7
|
|
51
|
+
with:
|
|
52
|
+
enable-cache: true
|
|
53
|
+
|
|
54
|
+
- name: Install dependencies
|
|
55
|
+
run: uv sync --all-groups
|
|
56
|
+
|
|
57
|
+
- name: Install package in editable mode
|
|
58
|
+
run: uv pip install -e .
|
|
59
|
+
|
|
60
|
+
- name: Test LLVM detection (Linux/macOS)
|
|
61
|
+
if: runner.os != 'Windows'
|
|
62
|
+
run: |
|
|
63
|
+
uv run python -c "from every_python.utils import check_llvm_available; import sys; sys.exit(0 if check_llvm_available('20') else 1)"
|
|
64
|
+
|
|
65
|
+
- name: Test build without JIT
|
|
66
|
+
run: uv run every-python install v3.13.0 --verbose
|
|
67
|
+
|
|
68
|
+
- name: Verify non-JIT build works
|
|
69
|
+
run: uv run every-python run v3.13.0 -- --version
|
|
70
|
+
|
|
71
|
+
- name: Test build with JIT
|
|
72
|
+
# Use commit that I know has JIT support with LLVM 20
|
|
73
|
+
run: uv run every-python install 42d014086098d3d70cacb4d8993f04cace120c12 --jit --verbose
|
|
74
|
+
|
|
75
|
+
- name: Verify JIT build works
|
|
76
|
+
# Use commit that I know has JIT support with LLVM 20
|
|
77
|
+
run: uv run every-python run 42d014086098d3d70cacb4d8993f04cace120c12 --jit -- --version
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
paths:
|
|
7
|
+
- 'every_python/**'
|
|
8
|
+
- 'tests/**'
|
|
9
|
+
- '.github/workflows/lint.yml'
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [ main ]
|
|
12
|
+
paths:
|
|
13
|
+
- 'every_python/**'
|
|
14
|
+
- 'tests/**'
|
|
15
|
+
- '.github/workflows/lint.yml'
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
ruff:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Install uv
|
|
24
|
+
uses: astral-sh/setup-uv@v7
|
|
25
|
+
with:
|
|
26
|
+
enable-cache: true
|
|
27
|
+
|
|
28
|
+
- name: Set up Python
|
|
29
|
+
uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.14"
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: uv sync
|
|
35
|
+
|
|
36
|
+
- name: Run Ruff linter
|
|
37
|
+
run: uv run ruff check every_python/
|
|
38
|
+
|
|
39
|
+
- name: Run Ruff formatter
|
|
40
|
+
run: uv run ruff format --check every_python/
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
paths:
|
|
7
|
+
- 'every_python/**'
|
|
8
|
+
- 'tests/**'
|
|
9
|
+
- 'pyproject.toml'
|
|
10
|
+
- '.github/workflows/test.yml'
|
|
11
|
+
pull_request:
|
|
12
|
+
branches: [ main ]
|
|
13
|
+
paths:
|
|
14
|
+
- 'every_python/**'
|
|
15
|
+
- 'tests/**'
|
|
16
|
+
- 'pyproject.toml'
|
|
17
|
+
- '.github/workflows/test.yml'
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ${{ matrix.runner }}
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
include:
|
|
26
|
+
- target: x86_64-unknown-linux-gnu/gcc
|
|
27
|
+
architecture: x86_64
|
|
28
|
+
runner: ubuntu-24.04
|
|
29
|
+
- target: aarch64-unknown-linux-gnu/gcc
|
|
30
|
+
architecture: aarch64
|
|
31
|
+
runner: ubuntu-24.04-arm
|
|
32
|
+
- target: x86_64-pc-windows-msvc/msvc
|
|
33
|
+
architecture: x64
|
|
34
|
+
runner: windows-2022
|
|
35
|
+
- target: aarch64-pc-windows-msvc/msvc
|
|
36
|
+
architecture: ARM64
|
|
37
|
+
runner: windows-11-arm
|
|
38
|
+
- target: x86_64-apple-darwin/clang
|
|
39
|
+
architecture: x86_64
|
|
40
|
+
runner: macos-15-intel
|
|
41
|
+
- target: aarch64-apple-darwin/clang
|
|
42
|
+
architecture: aarch64
|
|
43
|
+
runner: macos-14
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v5
|
|
46
|
+
|
|
47
|
+
- name: Set up Python
|
|
48
|
+
uses: actions/setup-python@v5
|
|
49
|
+
with:
|
|
50
|
+
python-version: "3.14"
|
|
51
|
+
|
|
52
|
+
- name: Install uv
|
|
53
|
+
uses: astral-sh/setup-uv@v7
|
|
54
|
+
with:
|
|
55
|
+
enable-cache: true
|
|
56
|
+
- name: Install dependencies
|
|
57
|
+
run: uv sync
|
|
58
|
+
- name: Run tests
|
|
59
|
+
run: uv run pytest -v
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Type Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
paths:
|
|
7
|
+
- 'every_python/**'
|
|
8
|
+
- 'tests/**'
|
|
9
|
+
- 'pyproject.toml'
|
|
10
|
+
- '.github/workflows/typecheck.yml'
|
|
11
|
+
pull_request:
|
|
12
|
+
branches: [ main ]
|
|
13
|
+
paths:
|
|
14
|
+
- 'every_python/**'
|
|
15
|
+
- 'tests/**'
|
|
16
|
+
- 'pyproject.toml'
|
|
17
|
+
- '.github/workflows/typecheck.yml'
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
pyright:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v5
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v7
|
|
27
|
+
with:
|
|
28
|
+
enable-cache: true
|
|
29
|
+
|
|
30
|
+
- name: Set up Python
|
|
31
|
+
uses: actions/setup-python@v6
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.14"
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: uv sync --all-groups
|
|
37
|
+
|
|
38
|
+
- name: Run Pyright
|
|
39
|
+
run: uv run pyright
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.egg
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
|
|
15
|
+
# IDEs
|
|
16
|
+
.vscode/
|
|
17
|
+
.idea/
|
|
18
|
+
*.swp
|
|
19
|
+
*.swo
|
|
20
|
+
|
|
21
|
+
# Ruff
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
|
|
24
|
+
# OS
|
|
25
|
+
.DS_Store
|
|
26
|
+
*.log
|
|
27
|
+
|
|
28
|
+
# Pytest
|
|
29
|
+
.cache/
|
|
30
|
+
.pytest_cache/
|
|
31
|
+
|
|
32
|
+
test_jit_api.py
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.8.4
|
|
4
|
+
hooks:
|
|
5
|
+
# Run the linter
|
|
6
|
+
- id: ruff
|
|
7
|
+
args: [--fix]
|
|
8
|
+
files: '^every_python/.*\.py$'
|
|
9
|
+
# Run the formatter
|
|
10
|
+
- id: ruff-format
|
|
11
|
+
files: '^every_python/.*\.py$'
|
|
12
|
+
|
|
13
|
+
- repo: local
|
|
14
|
+
hooks:
|
|
15
|
+
- id: pytest
|
|
16
|
+
name: pytest
|
|
17
|
+
entry: uv run --frozen --group dev pytest
|
|
18
|
+
language: system
|
|
19
|
+
pass_filenames: false
|
|
20
|
+
always_run: true
|
|
21
|
+
stages: [commit]
|
|
22
|
+
- id: pyright
|
|
23
|
+
name: pyright
|
|
24
|
+
entry: uv run pyright every_python/
|
|
25
|
+
language: system
|
|
26
|
+
pass_filenames: false
|
|
27
|
+
types: [python]
|
|
28
|
+
stages: [commit]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Savannah Ostrowski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: every-python
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Build and run any commit of CPython
|
|
5
|
+
Project-URL: Homepage, https://github.com/savannahostrowski/every-python
|
|
6
|
+
Project-URL: Repository, https://github.com/savannahostrowski/every-python
|
|
7
|
+
Project-URL: Issues, https://github.com/savannahostrowski/gruyere/issues
|
|
8
|
+
Author-email: Savannah Ostrowski <savannah@python.org>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ports,processes,tui
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.14
|
|
23
|
+
Requires-Dist: rich>=13.0.0
|
|
24
|
+
Requires-Dist: typer>=0.20.0
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# every-python
|
|
28
|
+
|
|
29
|
+
Build and run any commit of CPython, inspired by [every-ts](https://github.com/jakebailey/every-ts).
|
|
30
|
+
|
|
31
|
+
## Why does this exist?
|
|
32
|
+
|
|
33
|
+
Building CPython from source is time-consuming. `every-python` makes it easy to:
|
|
34
|
+
- Test your code against different Python versions
|
|
35
|
+
- Reproduce bugs in specific commits
|
|
36
|
+
- Test experimental features like the JIT compiler
|
|
37
|
+
- Bisect to find which commit introduced a regression
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- **Build any CPython commit** - main, release tags, or specific commits
|
|
42
|
+
- **Build with experimental JIT support** - Build with `--enable-experimental-jit` (includes LLVM version detection)
|
|
43
|
+
- **Smart caching** - Builds cached in `~/.every-python/builds/` for instant reuse
|
|
44
|
+
- **Git bisect integration** - Automatically find which commit introduced a bug
|
|
45
|
+
|
|
46
|
+
## How it works
|
|
47
|
+
|
|
48
|
+
`every-python` makes a [blobless clone](https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/) of the CPython repository (~200MB), checks out the version you want, and builds it locally with `--with-pydebug`. Built versions are cached in `~/.every-python/builds/` for reuse.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# From PyPI (once published)
|
|
54
|
+
uv tool install every-python
|
|
55
|
+
# or
|
|
56
|
+
pipx install every-python
|
|
57
|
+
# or
|
|
58
|
+
pip install every-python
|
|
59
|
+
|
|
60
|
+
# Development install from source
|
|
61
|
+
git clone https://github.com/yourusername/every-python.git
|
|
62
|
+
cd every-python
|
|
63
|
+
uv sync
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
- Git
|
|
69
|
+
- [CPython build dependencies](https://devguide.python.org/getting-started/setup-building/)
|
|
70
|
+
- [LLVM](https://github.com/python/cpython/blob/main/Tools/jit/README.md), for JIT builds
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
### Build and install a Python version
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Build from main branch
|
|
78
|
+
every-python install main
|
|
79
|
+
|
|
80
|
+
# Build from a release tag
|
|
81
|
+
every-python install v3.13.0
|
|
82
|
+
|
|
83
|
+
# Build from a specific commit
|
|
84
|
+
every-python install abc123d
|
|
85
|
+
|
|
86
|
+
# Show build output (useful for debugging build failures)
|
|
87
|
+
every-python install main --verbose
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Run Python with a specific version
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Run Python REPL
|
|
94
|
+
every-python run main -- python
|
|
95
|
+
|
|
96
|
+
# Run a script
|
|
97
|
+
every-python run v3.13.0 -- python your_script.py
|
|
98
|
+
|
|
99
|
+
# Run with arguments
|
|
100
|
+
every-python run main -- python -c "print('Hello!')"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
If the version isn't built yet, it will build it automatically.
|
|
104
|
+
|
|
105
|
+
### Build with JIT compiler (experimental)
|
|
106
|
+
|
|
107
|
+
Build Python with the experimental JIT compiler:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Build with JIT enabled
|
|
111
|
+
every-python install main --jit
|
|
112
|
+
|
|
113
|
+
# Run with JIT-enabled build
|
|
114
|
+
every-python run main --jit -- python -c "print('Hello from JIT!')"
|
|
115
|
+
|
|
116
|
+
# Bisect with JIT to find JIT-specific bugs
|
|
117
|
+
every-python bisect --good v3.13.0 --bad main --jit --run "python test.py"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**JIT Requirements:**
|
|
121
|
+
`every-python` will attempt to detect the correct version of LLVM for the commit being built from `LLVM_VERSION` specified in `Tools/jit/_llvm.py` at the time of the commit. If you are missing the required LLVM version, you will see an error during the build. For more information on installing LLVM, see [CPython JIT documentation](https://github.com/python/cpython/blob/main/Tools/jit/README.md).
|
|
122
|
+
|
|
123
|
+
Note: LLVM is only needed at build time, not at runtime. JIT and non-JIT builds are stored separately.
|
|
124
|
+
|
|
125
|
+
### List built versions
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
every-python list-builds
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Clean up builds
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Remove a specific build
|
|
135
|
+
every-python clean v3.13.0
|
|
136
|
+
|
|
137
|
+
# Remove all builds
|
|
138
|
+
every-python clean --all
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Bisect to find bugs
|
|
142
|
+
|
|
143
|
+
Use git bisect to automatically find which commit introduced a bug:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Find when a test started failing
|
|
147
|
+
# Exit with code 0 = good commit, 1 = bad commit
|
|
148
|
+
every-python bisect \
|
|
149
|
+
--good v3.13.0 \
|
|
150
|
+
--bad main \
|
|
151
|
+
--run "python test_my_feature.py"
|
|
152
|
+
|
|
153
|
+
# Bisect with JIT-enabled builds
|
|
154
|
+
every-python bisect \
|
|
155
|
+
--good v3.12.0 \
|
|
156
|
+
--bad main \
|
|
157
|
+
--jit \
|
|
158
|
+
--run "python test_jit_api.py"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
This will:
|
|
162
|
+
1. Resolve the good and bad commits
|
|
163
|
+
2. Start a git bisect
|
|
164
|
+
3. Build each commit that git bisect tests
|
|
165
|
+
4. Run your test command
|
|
166
|
+
5. Automatically mark commits as good/bad based on exit code:
|
|
167
|
+
- Exit 0 = good commit
|
|
168
|
+
- Exit 1-127 (except 125) = bad commit
|
|
169
|
+
- Exit 125 = skip this commit (can't test it)
|
|
170
|
+
6. Find the exact commit that introduced the change
|
|
171
|
+
|
|
172
|
+
**Note on bisecting across branches:** Bisecting between release tags and main can be tricky due to backporting. For best results, bisect within a single branch (e.g., use commit hashes on main instead of crossing from v3.12.0 to main).
|
|
173
|
+
|
|
174
|
+
**Writing test scripts for bisect:** Your test script should exit with code 0 for "good" (old/expected behavior) and 1 for "bad" (new/broken behavior). For example, if I wanted to find when `_jit` was added to the `sys` module, I could use this script:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
import sys
|
|
178
|
+
# Exit 0 (good) = feature doesn't exist yet
|
|
179
|
+
# Exit 1 (bad) = feature exists
|
|
180
|
+
if hasattr(sys, "_jit"):
|
|
181
|
+
sys.exit(1) # Feature exists - mark as "bad"
|
|
182
|
+
sys.exit(0) # Feature doesn't exist - mark as "good"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Project Structure
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
~/.every-python/
|
|
189
|
+
├── cpython/ # Blobless clone of CPython repository
|
|
190
|
+
└── builds/ # Cached builds
|
|
191
|
+
├── abc123d/ # Build for commit abc123d
|
|
192
|
+
├── abc123d-jit/ # JIT build for commit abc123d
|
|
193
|
+
└── def456e/ # Build for commit def456e
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
MIT
|