PEP 829 replaces import lines in .pth.
🤖 Plan summary based on PEP 829
Problem
Implement PEP 829 support for scikit-build-core's editable install startup mechanism. Today redirect editable wheels write _<name>_editable.py plus _<name>_editable.pth containing an import _<name>_editable line; inplace editable writes only a path-only .pth. PEP 829 changes startup code execution to paired .start files on Python 3.15+, while keeping import lines in .pth for path extensions and for straddling older Pythons.
Current state
- Redirect editable startup artifacts are produced in
src/scikit_build_core/build/wheel.py::_make_editable.
- The callable bootstrap implementation already exists in
src/scikit_build_core/resources/_editable_redirect.py; today it is invoked through import _<name>_editable from the .pth.
- Redirect editable wheel coverage exists in
tests/test_pyproject_pep660.py; low-level redirect content coverage exists in tests/test_editable_unit.py and tests/test_editable_redirect.py.
- Inplace editable mode only writes package paths into
_<name>_editable.pth, so PEP 829 startup-entry changes should only affect redirect mode.
- Stable ABI / cross-version intent is represented through
wheel.py-api (for example cp39, cp315t, py3) and tag computation in builder/wheel_tag.py.
Proposed approach
- Add a small helper in the editable wheel-writing path that decides which startup artifacts to emit for redirect editable wheels:
- always keep
_<name>_editable.py
- keep
_<name>_editable.pth import statements for older Python compatibility and Cython path injection
- add
_<name>_editable.start pointing at a zero-argument callable inside _<name>_editable.py
- gate
.start emission so it is always written on Python 3.15+, and also written on older builders for non-version-specific tags (Stable ABI cp3x / cp3xxt and Pythonless py3 / py2.py3) because those wheels may later be installed on Python 3.15+
- Refactor the generated editable bootstrap so the startup action can be referenced as a PEP 829 entry point such as
_<name>_editable:install.
- Keep inplace editable behavior unchanged unless investigation during implementation shows a compatibility reason to touch it.
- Extend tests around editable wheel contents and generated bootstrap text to cover:
- redirect wheels on Python 3.15+ producing
.start
- redirect wheels on Python < 3.15 keeping compatibility behavior
- Stable ABI / non-version-specific cases that must still emit
.start
- inplace wheels continuing to avoid executable startup artifacts
- Update user-facing docs if editable wheel artifact behavior or compatibility guidance is documented.
Notes / considerations
- PEP 829 requires
.start files to contain pkg.mod:callable entries, so the generated redirect module likely needs a dedicated zero-argument entry-point wrapper instead of relying on side effects at import time.
- The existing
.pth also adds package source paths for Cython support; the plan should preserve those path lines regardless of .start handling.
- Scope decision: treat Pythonless tags like Stable ABI tag
PEP 829 replaces import lines in
.pth.🤖 Plan summary based on PEP 829
Problem
Implement PEP 829 support for scikit-build-core's editable install startup mechanism. Today redirect editable wheels write
_<name>_editable.pyplus_<name>_editable.pthcontaining animport _<name>_editableline; inplace editable writes only a path-only.pth. PEP 829 changes startup code execution to paired.startfiles on Python 3.15+, while keeping import lines in.pthfor path extensions and for straddling older Pythons.Current state
src/scikit_build_core/build/wheel.py::_make_editable.src/scikit_build_core/resources/_editable_redirect.py; today it is invoked throughimport _<name>_editablefrom the.pth.tests/test_pyproject_pep660.py; low-level redirect content coverage exists intests/test_editable_unit.pyandtests/test_editable_redirect.py._<name>_editable.pth, so PEP 829 startup-entry changes should only affect redirect mode.wheel.py-api(for examplecp39,cp315t,py3) and tag computation inbuilder/wheel_tag.py.Proposed approach
_<name>_editable.py_<name>_editable.pthimport statements for older Python compatibility and Cython path injection_<name>_editable.startpointing at a zero-argument callable inside_<name>_editable.py.startemission so it is always written on Python 3.15+, and also written on older builders for non-version-specific tags (Stable ABIcp3x/cp3xxtand Pythonlesspy3/py2.py3) because those wheels may later be installed on Python 3.15+_<name>_editable:install..start.startNotes / considerations
.startfiles to containpkg.mod:callableentries, so the generated redirect module likely needs a dedicated zero-argument entry-point wrapper instead of relying on side effects at import time..pthalso adds package source paths for Cython support; the plan should preserve those path lines regardless of.starthandling.