Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-24.04]
python-version: ["3.11", "3.12", "3.13"]
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand Down Expand Up @@ -101,6 +101,40 @@ jobs:
continue-on-error: true
run: pytest -q tests/test_matrix_hardening.py -m "race and no_gil"

tests-subinterpreter:
name: sub-interpreter cells / py3.14t
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.14t"
- name: Install dependencies
# Same shape as the 3.13t job: install without the runtime deps that
# may not have free-threaded wheels yet, then re-add the pure-Python
# ones the import path needs. The suite's crypto stub (tests/conftest.py)
# covers the rest, and nothing in this job's scope needs real crypto.
run: |
python -m pip install -e . --no-deps
python -m pip install pytest pyyaml platformdirs
- name: Verify this build actually has sub-interpreters
# Every sub-interpreter test skips itself when the build cannot run it.
# That is right for the 3.11-3.13 matrix, but it means this job would
# report green on a runner that silently resolved to an older Python
# while testing nothing. Fail loudly instead.
run: |
python - <<'PY'
import sys
from pyisolate.runtime import subinterpreter as s
assert s.is_available(), f"no concurrent.interpreters on {sys.version}"
assert not sys._is_gil_enabled(), "expected a free-threaded build"
print("ok:", sys.version)
PY
- name: Run the sub-interpreter backend suite
run: pytest -q tests/test_subinterpreter_backend.py tests/test_supervisor.py
- name: Validate the no-GIL readiness axis on 3.14t
run: pytest -q tests/test_nogil.py

tests-soak:
name: soak / 2k spawn-kill cycles
if: github.event_name == 'schedule'
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ guarantees; **no release should be treated as a hardened security boundary**.
- `pyisolate[operator]` optional-dependency group for the Kubernetes operator.

### Changed
- CI covers CPython 3.14: the unit matrix gains `3.14`, and a new
`sub-interpreter cells / py3.14t` job runs the sub-interpreter backend on a
free-threaded build. That job asserts the interpreter really is a
free-threaded 3.14 before running anything, because every sub-interpreter
test skips itself when the build cannot run it -- correct for the 3.11-3.13
matrix, but it would otherwise let the job report green having tested
nothing.
- `backend="subinterpreter"` is renamed to `backend="thread"`, which is what it
has always run, and the `subinterpreter` name now selects the real
sub-interpreter backend. `DEPRECATED_BACKEND_ALIASES` is exported alongside
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Security",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Systems Administration",
Expand Down
Loading