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.
@@ -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