Skip to content
Merged
Show file tree
Hide file tree
Changes from 187 commits
Commits
Show all changes
249 commits
Select commit Hold shift + click to select a range
eb53c2d
Use PyModExport and PyABIInfo APIs in pymodule implementation
ngoldbaum Jan 26, 2026
e41b509
Add PyModExport function
ngoldbaum Jan 26, 2026
91becaf
DNM: temporarily disable append_to_inittab doctest
ngoldbaum Jan 26, 2026
1020688
fix issues seen on older pythons in CI
ngoldbaum Jan 26, 2026
3afa9ae
fix incorrect ModuleDef setup on 3.15
ngoldbaum Jan 26, 2026
f8d6cae
Expose both the PyInit and PyModExport initialization hooks
ngoldbaum Jan 27, 2026
a590874
fix clippy
ngoldbaum Jan 27, 2026
a96219f
add changelog entry
ngoldbaum Jan 27, 2026
e7ac9c0
try use only slots for both init hooks on 3.15
ngoldbaum Jan 29, 2026
d981be7
Always pass m_name and m_doc, following cpython-gh-144340
ngoldbaum Jan 30, 2026
55b6acd
WIP: opaque pyobject support (without Py_GIL_DISABLED)
ngoldbaum Feb 13, 2026
733aa82
delete debug prints
ngoldbaum Feb 13, 2026
c43061e
WIP: fix segfault
ngoldbaum Feb 13, 2026
3812a64
disable append_to_inittab tests
ngoldbaum Feb 13, 2026
25a65a6
fix clippy
ngoldbaum Feb 13, 2026
4a83024
fix ruff
ngoldbaum Feb 13, 2026
9d0e2ed
implement David's suggestion for pyobject_subclassable_native_type
ngoldbaum Feb 13, 2026
a78b5df
replace skipped test with real test
ngoldbaum Feb 13, 2026
42a73e1
fix check-feature-powerset
ngoldbaum Feb 13, 2026
060c3ca
fix clippy-all
ngoldbaum Feb 13, 2026
c1bd2c7
skip test that depend on struct layout on opaque pyobject builds
ngoldbaum Feb 13, 2026
ba8b09a
Expose PyModuleDef as an opaque pointer on opaque PyObject builds
ngoldbaum Feb 16, 2026
f15a7fc
add comments about location of opaque pointers in CPython headers
ngoldbaum Feb 16, 2026
3fa17d0
fix test_inherited_size
ngoldbaum Feb 16, 2026
1970421
Fix doctest on _Py_OPAQUE_PYOBJECT builds
ngoldbaum Feb 17, 2026
57c2045
Merge branch 'main' into opaque-pyobject
ngoldbaum Mar 3, 2026
f80849e
fix build error on non-opaque builds
ngoldbaum Mar 3, 2026
c0805a9
mark BaseWithoutData as subclassable
ngoldbaum Mar 3, 2026
719cef5
relax assert for Windows
ngoldbaum Mar 3, 2026
072ef0a
Make PyAny a PyVarObject only on the opaque PyObject build
ngoldbaum Mar 4, 2026
0b743b6
Merge branch 'main' into opaque-pyobject
ngoldbaum Mar 24, 2026
264307f
fix merge conflict resolution error
ngoldbaum Mar 24, 2026
ed48e75
fix buggy assertion
ngoldbaum Mar 24, 2026
b4138c4
Expose critical section in the limited API starting in Python 3.15
ngoldbaum Mar 24, 2026
f3ee6af
expose critical section API in limited API
ngoldbaum Mar 24, 2026
ba47f50
disable warning in pyo3-ffi build script on sufficiently new Pythons
ngoldbaum Mar 25, 2026
e52cb59
fixup features
ngoldbaum Mar 26, 2026
3cf60b1
Add missing error handling for `PyModule_FromSlotsAndSpec`
ngoldbaum Mar 26, 2026
607e4b0
Merge branch 'main' into expose-critical-section
ngoldbaum Mar 26, 2026
449eb8a
passes cargo tests with the abi3t feature enabled
ngoldbaum Mar 26, 2026
5371fd8
passes unit tests on GIL-enabled build with abi3t feature
ngoldbaum Mar 26, 2026
19d78d2
fix merge mistake
ngoldbaum Mar 26, 2026
14bf4d1
rustfmt
ngoldbaum Mar 27, 2026
91a0419
fix FIXME
ngoldbaum Mar 27, 2026
285e79c
Merge branch 'main' into opaque-pyobject
ngoldbaum Apr 3, 2026
9f23720
replace extern "C" with extern_libpython!
ngoldbaum Apr 3, 2026
d38c274
fix test
ngoldbaum Apr 3, 2026
e2d8f8c
Merge branch 'opaque-pyobject' into expose-critical-section
ngoldbaum Apr 6, 2026
15ff21c
fix merge error
ngoldbaum Apr 6, 2026
930e1a9
Allow abi3t builds without critical section bindings
ngoldbaum Apr 6, 2026
a609f8c
add FIXME
ngoldbaum Apr 6, 2026
dd5b3a9
remove default feature
ngoldbaum Apr 6, 2026
7419b86
fix syntax error in noxfile
ngoldbaum Apr 6, 2026
603aaf9
fix issues spotted by clippy
ngoldbaum Apr 6, 2026
c9b9157
bring over refactoring from PyO3 PR
ngoldbaum Apr 7, 2026
7560348
working!
ngoldbaum Apr 7, 2026
becc8af
Fix memory leak of iterator
ngoldbaum Apr 8, 2026
b734e77
fix size hints
ngoldbaum Apr 8, 2026
a6c8710
delete debug statement
ngoldbaum Apr 8, 2026
a827be9
Use Py_TARGET_ABI3T
ngoldbaum Apr 8, 2026
0ceda48
run formatter
ngoldbaum Apr 8, 2026
d1ef669
fix check-feature-powerset
ngoldbaum Apr 8, 2026
26c7dc0
increment SUPPORTED_VERSIONS_CPYTHON.max
ngoldbaum Apr 8, 2026
95ca7d2
fix conditional compilation for critical section API
ngoldbaum Apr 8, 2026
b596885
fix ruff
ngoldbaum Apr 8, 2026
22a5332
fix incorrect conditional compilation guargs
ngoldbaum Apr 8, 2026
ec1269a
fix noxfile and ban abi3t builds on 3.14 and older
ngoldbaum Apr 8, 2026
04eb8bb
ruff format
ngoldbaum Apr 8, 2026
101949c
attempt to fix semver-checks
ngoldbaum Apr 8, 2026
828afdd
fix test-version-limits
ngoldbaum Apr 8, 2026
cd78153
fix issues spotted by claude
ngoldbaum Apr 8, 2026
5e5671e
strip 't' for version parsing
ngoldbaum Apr 8, 2026
266527f
Adjust comments and error messages
ngoldbaum Apr 8, 2026
294a4f0
fix compiler warning
ngoldbaum Apr 8, 2026
b37445d
more noxfile fixes
ngoldbaum Apr 8, 2026
a2584f5
fix ruff
ngoldbaum Apr 8, 2026
1b5ec7a
use a 3.15 interpreter to run the feature-powerset tests
ngoldbaum Apr 8, 2026
553ef54
fix a few more issues caught by claude
ngoldbaum Apr 8, 2026
2f755ae
add comment
ngoldbaum Apr 8, 2026
f326c74
Merge branch 'main' into opaque-pyobject
ngoldbaum Apr 15, 2026
710e835
use correct windows library name for abi3t
ngoldbaum Apr 16, 2026
861edd8
try to fix linking
ngoldbaum Apr 16, 2026
c8e40b9
add CPythonABI enum for pyo3-build-config InterpreterConfig
ngoldbaum Mar 30, 2026
45d5cc1
add release note
ngoldbaum Mar 30, 2026
e3dc133
store ABI details in a new PythonAbi struct
ngoldbaum Apr 15, 2026
966a82f
fix nox config file
ngoldbaum Apr 15, 2026
9d9a0e2
fix ffi-check
ngoldbaum Apr 17, 2026
f52f1d8
Refactor to use the builder pattern for InterpreterConfig
ngoldbaum Apr 24, 2026
77039d2
revert noxfile change
ngoldbaum Apr 24, 2026
0765953
fix clippy-all
ngoldbaum Apr 24, 2026
cde688c
fix build-config test
ngoldbaum Apr 24, 2026
b11b262
Fix issues linking against onld stable ABI versions
ngoldbaum Apr 24, 2026
9cb420a
remove load-bearing debug impls
ngoldbaum Apr 28, 2026
7fe98ab
fix issue with InterpreterConfig::from_interpreter never returning an…
ngoldbaum Apr 28, 2026
41be837
fix clippy lint
ngoldbaum Apr 28, 2026
58162a4
fix PythonAbiBuilder::from_build_env
ngoldbaum Apr 28, 2026
48a7d20
Only target abi3 for non-free-threaded builds
ngoldbaum Apr 28, 2026
c899390
fix logic error in InterpreterConfig::from_reader
ngoldbaum Apr 28, 2026
e0c8826
Merge branch 'abi-tag-refactor' into opaque-pyobject
ngoldbaum Apr 30, 2026
942ecc9
smooth over merge
ngoldbaum Apr 30, 2026
90bef3c
tests pass
ngoldbaum Apr 30, 2026
ea2eab7
Add stub abi3t implementation
ngoldbaum Apr 30, 2026
8354ef7
Improve test coverage
ngoldbaum Apr 30, 2026
6854756
fix clippy
ngoldbaum Apr 30, 2026
3a21665
fix 3.14t abi3 builds being a no-op
ngoldbaum Apr 30, 2026
97087aa
fix ffi-check to account for private _tp_iteritem PyTypeObject slot
ngoldbaum May 2, 2026
80a591c
expose the critical section API
ngoldbaum May 3, 2026
be1b77f
Add initial support for Python 3.15.0b1
ngoldbaum May 3, 2026
090d11d
fix ffi docstring example
ngoldbaum May 3, 2026
81daf34
typo fix
ngoldbaum May 3, 2026
3ce9275
fix ffi-check macro
ngoldbaum May 4, 2026
4763179
fix ffi examples
ngoldbaum May 4, 2026
b6d6f99
make PySlot_FUNC a Rust macro
ngoldbaum May 4, 2026
4828759
fix clippy
ngoldbaum May 4, 2026
1e2a2c3
keep macros version-independent
ngoldbaum May 4, 2026
ecc365a
format extern_libpython blocks
ngoldbaum May 5, 2026
14c80db
use an explicit type in the PySlot_FUNC macro
ngoldbaum May 5, 2026
af92c51
fix issues seen in CI builds on older Pythons
ngoldbaum May 5, 2026
17583a8
fix one more spot in the ffi tests
ngoldbaum May 5, 2026
1caf685
fix type error in string-sum implementation
ngoldbaum May 5, 2026
85bc302
add changelog entries
ngoldbaum May 5, 2026
75b8962
remove unnecessary PartialEq implementation
ngoldbaum May 5, 2026
cbedefc
use std::slice::from_raw_parts instead of libc::memcmp
ngoldbaum May 5, 2026
ec46a20
re-add incorrectly deleted end slot
ngoldbaum May 5, 2026
63486a3
Use PartialEq on Python 3.14 and older
ngoldbaum May 5, 2026
f4e86f7
fix compiler error due to missing Debug impl
ngoldbaum May 5, 2026
ee68ff0
Finish updating slots_generated and adjust types for slot IDs
ngoldbaum May 5, 2026
816fd56
add missing cfg gate
ngoldbaum May 5, 2026
8e04584
remove unused import
ngoldbaum May 5, 2026
1e073e7
Merge branch 'main' into abi-tag-refactor
ngoldbaum May 6, 2026
8fd0acb
make InterpreterConfigBuilder.extra_build_script_lines a Vec
ngoldbaum May 6, 2026
7d5881c
Add an abi3 version sanitization function, adjust error handling
ngoldbaum May 6, 2026
5c73549
Adjust comment fragment, add TODO
ngoldbaum May 6, 2026
1e71ed4
apply focused comments from self-review
ngoldbaum May 6, 2026
b3ef667
simplify modeling of free-threaded builds and Py_GIL_DISABLED build flag
ngoldbaum May 6, 2026
df3bf04
fix clippy
ngoldbaum May 6, 2026
fbacc26
relax accepting Py_GIL_DISABLED in build_flags if no target ABI is set
ngoldbaum May 6, 2026
0efa792
more fixes and suggestions from claude
ngoldbaum May 6, 2026
766ecbf
fix fallback to version-specific builds for free-threaded abi3 builds
ngoldbaum May 6, 2026
deb83a7
More minor fixes
ngoldbaum May 6, 2026
9174ca7
expand test coverage
ngoldbaum May 6, 2026
01a6b0a
more fixes
ngoldbaum May 6, 2026
b8b5bff
update changelog entries
ngoldbaum May 6, 2026
285eb19
Add missing exports to public pyo3-build-config API
ngoldbaum May 6, 2026
95be8d0
fix linux test
ngoldbaum May 6, 2026
9a33592
minor touch-ups
ngoldbaum May 7, 2026
0c7b53a
minor touch-ups
ngoldbaum May 7, 2026
505d9e1
skip redundant test
ngoldbaum May 7, 2026
20c8f57
whitespace
ngoldbaum May 7, 2026
afd0eec
more tweaks
ngoldbaum May 7, 2026
b40805a
grammar in comment
ngoldbaum May 7, 2026
4dba451
Merge branch 'pep-820' into opaque-pyobject
ngoldbaum May 7, 2026
107ab27
fix cfg gating
ngoldbaum May 7, 2026
5334eaa
activate abi3t builds
ngoldbaum May 8, 2026
92ad56c
Merge branch 'abi-tag-refactor' into opaque-pyobject
ngoldbaum May 11, 2026
12fa458
fix PyMutex gating
ngoldbaum May 11, 2026
9337202
simplify windows stable ABI lib name text manipulation
ngoldbaum May 11, 2026
f76a5c8
Merge branch 'main' into opaque-pyobject
ngoldbaum May 11, 2026
ab1333b
Merge branch 'main' into opaque-pyobject
ngoldbaum May 11, 2026
52124f8
fix ruff
ngoldbaum May 11, 2026
d9133fe
fix cfg gating for critical section API
ngoldbaum May 11, 2026
87d6ae4
Merge branch 'main' into opaque-pyobject
ngoldbaum May 12, 2026
1aea9b0
adjust PyMutex cfg gating
ngoldbaum May 12, 2026
4bb2202
attempt to fix abi3 feature for free-threaded targets from a config file
ngoldbaum May 12, 2026
3e1ec34
introduce a builder for InterpreterConfig
ngoldbaum Apr 24, 2026
781648b
newsfragments
davidhewitt May 12, 2026
f091c9a
fixup ubuntu test
davidhewitt May 12, 2026
ef4fb92
fixup
davidhewitt May 12, 2026
7ee1ed0
fix missing `mut`
davidhewitt May 12, 2026
0709d59
Merge remote-tracking branch 'origin/main' into opaque-pyobject
davidhewitt May 12, 2026
f509e72
fix merge error
ngoldbaum May 12, 2026
f8aa9a5
fix incorrect merge conflict resolution
ngoldbaum May 12, 2026
037563a
refactor is_abi3(t) in get_abit3(t)_version.is_some()
ngoldbaum May 12, 2026
23bf337
apply suggestions from icxolu
ngoldbaum May 12, 2026
14c2d9f
Make PythonAbi fields private, replace with accessor methods
ngoldbaum May 12, 2026
9af08e1
fix test-version-limits
ngoldbaum May 12, 2026
13448e3
Apply suggestions from code review
davidhewitt May 12, 2026
7ba3daf
review feedback
davidhewitt May 12, 2026
a59f8dc
Merge branch 'interpreter-builder' into opaque-pyobject
ngoldbaum May 12, 2026
4bcd9fa
fix merge conflicts
ngoldbaum May 12, 2026
5a47645
Merge branch 'interpreter-builder' into opaque-pyobject
ngoldbaum May 12, 2026
9a32727
fix clippy
ngoldbaum May 12, 2026
c536ebe
re-enable functionality that depends on critical sections
ngoldbaum May 12, 2026
53014c0
revert more unnecessary changes
ngoldbaum May 12, 2026
208fe8f
reduce diff further
ngoldbaum May 13, 2026
3b32ea1
Merge branch 'main' into opaque-pyobject
ngoldbaum May 13, 2026
d9ade28
fix cfg gating for critical section guards
ngoldbaum May 13, 2026
dab0337
Merge branch 'main' into opaque-pyobject
ngoldbaum May 14, 2026
0e4d6d8
Merging with David's default_lib_name_for_config_file branch
ngoldbaum May 14, 2026
c85c89c
Merge branch 'main' into opaque-pyobject
ngoldbaum May 14, 2026
6c514fb
remove unnecessary get_abi3_version().is_some()
ngoldbaum May 14, 2026
5518b84
bring back Option
ngoldbaum May 14, 2026
0123231
fix comparison for ABI3T_FORWARD_COMPATIBILITY
ngoldbaum May 14, 2026
ed9807c
Apply minor suggestions from code review
ngoldbaum May 14, 2026
2b8d7a2
delete docs for non-pub field
ngoldbaum May 14, 2026
b772cf3
Don't define a Py_TARGET_ABI3T cfg check
ngoldbaum May 14, 2026
c345a0d
fix merge errors
ngoldbaum May 14, 2026
caf1af8
implement Icxolu's suggestion to get rid of is_abi3 and is_abi3t
ngoldbaum May 14, 2026
2531c96
fix clippy-all
ngoldbaum May 14, 2026
1908b69
delete unnecessary get_abit3_version() check
ngoldbaum May 14, 2026
d232ac7
Allow simultaneously enabling abi3 and abi3t features
ngoldbaum May 14, 2026
941aca4
add release notes
ngoldbaum May 14, 2026
4d38642
fix ruff
ngoldbaum May 14, 2026
dd200da
really fix ruff
ngoldbaum May 14, 2026
fd0f14f
don't run abi3-py38 tests on pypy
ngoldbaum May 15, 2026
13e04c7
add docs
ngoldbaum May 15, 2026
ebc99b9
disable windows gil-enabled abi3t builds to work around upstream bug
ngoldbaum May 15, 2026
6214c3d
fix guide formatting
ngoldbaum May 15, 2026
7725030
fix internal links in guide
ngoldbaum May 15, 2026
303877a
fix typo in noxfile
ngoldbaum May 15, 2026
cb5a464
Merge branch 'main' into opaque-pyobject
ngoldbaum May 16, 2026
607f8bc
fix release notes
ngoldbaum May 16, 2026
335fa8a
revert now-unnecessary CI configuration change
ngoldbaum May 16, 2026
be8b1a1
fix abi3t-py315 feature not re-exporting pyo3-ffi feature
ngoldbaum May 18, 2026
68ffca0
fix typos in comments
ngoldbaum May 18, 2026
f9b50b7
make get_host_interpreter accept explicit abi3_version and abi3t_vers…
ngoldbaum May 25, 2026
6419422
never use an abi3 version on the free-threaded build
ngoldbaum May 26, 2026
f85c163
make build-config tests pass on 3.14t
ngoldbaum May 26, 2026
fd01447
version-gate build-config test
ngoldbaum May 26, 2026
0e945b3
fix logic error in get_host_interpreter
ngoldbaum May 26, 2026
c9c3b01
skip build-config tests for stable ABI lowering on 3.14t, which doesn…
ngoldbaum May 26, 2026
abaf0e0
further gate test
ngoldbaum May 26, 2026
a49e696
attempt to fix cross-compilation issue in maturin
ngoldbaum May 26, 2026
1cf8751
only use abi3 version for non-free-threaded cross-compile
ngoldbaum May 26, 2026
e6d31b9
fix incorrect version gate
ngoldbaum May 26, 2026
5502313
further gate test onolder python versions
ngoldbaum May 26, 2026
3c25970
expand test-version-limits tests to cover pyo3-ffi build script logic
ngoldbaum May 26, 2026
f49ee61
Apply David's review comments
ngoldbaum May 26, 2026
854062d
expand cross-compilation tests
ngoldbaum May 26, 2026
7b3da72
fix ruff
ngoldbaum May 27, 2026
91c7db3
don't lower to abi3 on pypy or graalpy
ngoldbaum May 27, 2026
afd124c
fix cross-compiling from PyPy
ngoldbaum May 27, 2026
5d9afb9
skip stable abi lowering test on graalpy and pypy
ngoldbaum May 27, 2026
dac521d
fix logic error
ngoldbaum May 27, 2026
4be2121
simplify skipping logic
ngoldbaum May 27, 2026
88d34b3
Fix Py_UNICODE_TODECIMAL definition for PyPy
ngoldbaum May 28, 2026
46b1d50
Merge branch 'fix-todecimal-pypy' into opaque-pyobject
ngoldbaum May 28, 2026
e573a16
rename USE_ABI3T_FORWARD_COMPATIBILITY to USE_STABLE_ABI_FORWARD_COMP…
ngoldbaum May 28, 2026
fbefb3b
format
ngoldbaum May 28, 2026
89fd8de
Merge branch 'main' into opaque-pyobject
ngoldbaum Jun 1, 2026
8e2cd4f
Always target abi3 on rustpython
ngoldbaum Jun 1, 2026
2118eec
fix clippy
ngoldbaum Jun 1, 2026
9e0c3e0
Apply suggestions from code review
ngoldbaum Jun 2, 2026
917df5c
internal: use `hashbrown` internally if it's enabled (#6055)
Person-93 Jun 2, 2026
b1f0c67
ci: install debug interpreter with uv (#5447)
davidhewitt Jun 2, 2026
dba8a3a
fix reference count leak in `PyFrame::new` (#6094)
davidhewitt Jun 2, 2026
0463e6f
regenerate PYO3_PRINT_CONFIG example output
ngoldbaum Jun 2, 2026
9362e8a
delete documentation line that links to PRs
ngoldbaum Jun 2, 2026
a1a089e
fix build error from github suggestion
ngoldbaum Jun 2, 2026
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
10 changes: 9 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ jobs:
- uses: obi1kenobi/cargo-semver-checks-action@v2
with:
baseline-rev: ${{ steps.fetch_merge_base.outputs.merge_base }}
feature-group: "only-explicit-features"
features: "full"
- uses: obi1kenobi/cargo-semver-checks-action@v2
with:
baseline-rev: ${{ steps.fetch_merge_base.outputs.merge_base }}
feature-group: "only-explicit-features"
features: "full,abi3"
Comment thread
ngoldbaum marked this conversation as resolved.
Outdated


check-msrv:
needs: [fmt, resolve]
Expand Down Expand Up @@ -648,7 +656,7 @@ jobs:
- uses: actions/checkout@v6.0.2
- uses: actions/setup-python@v6
with:
python-version: "3.14"
python-version: "3.15-dev"
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'CI-save-pr-cache') }}
Expand Down
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ abi3-py313 = ["abi3-py314", "pyo3-ffi/abi3-py313"]
abi3-py314 = ["abi3-py315", "pyo3-ffi/abi3-py314"]
abi3-py315 = ["abi3", "pyo3-ffi/abi3-py315"]

abi3t = ["pyo3-ffi/abi3t"]

# With abi3t, we can manually set the minimum Python version.
abi3t-py315 = ["abi3t"]

# deprecated: no longer needed, raw-dylib is used instead
generate-import-lib = ["pyo3-ffi/generate-import-lib"]

Expand Down
3 changes: 3 additions & 0 deletions guide/src/python-from-rust/calling-existing-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,13 @@ mod foo {
}
}

# #[cfg(not(Py_TARGET_ABI3T))]
fn main() -> PyResult<()> {
pyo3::append_to_inittab!(foo);
Python::attach(|py| Python::run(py, c"import foo; foo.add_one(6)", None, None))
}
# #[cfg(Py_TARGET_ABI3T)]
# fn main() -> () {}
```

If `append_to_inittab` cannot be used due to constraints in the program, an alternative is to create a module using [`PyModule::new`] and insert it manually into `sys.modules`:
Expand Down
7 changes: 7 additions & 0 deletions newsfragments/5924.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* Added a PythonAbi struct, along with PythonAbiKind, StableAbi, and GilUsed
enums to pyo3-build-config. These types allow specifying the Python ABI to use
for a build. You can construct a PythonAbi struct using a PythonAbiBuilder
struct.

* Added an InterpreterConfigBuilder struct for building InterpreterConfig
structs with a more ergonomic syntax.
6 changes: 6 additions & 0 deletions newsfragments/5924.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
* The boolean `abi3` field of `pyo3_build_config::impl_::InterpreterConfig` is now
deprecated and has been replaced by a target_abi field, which is a `PythonAbi`
struct.
* The InterpreterConfig::from_interpreter function now accepts a second
`abi3_version` argument. The old behavior is the same as passing
`abi3_version = None` .
121 changes: 97 additions & 24 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ def _supported_interpreter_versions(

PY_VERSIONS = _supported_interpreter_versions("cpython")
ABI3_PY_VERSIONS = [p for p in PY_VERSIONS if not p.endswith("t")]
ABI3T_PY_VERSIONS = [
p for p in PY_VERSIONS if p.endswith("t") and int(p.split(".")[1].strip("t")) > 14
]
PYPY_VERSIONS = _supported_interpreter_versions("pypy")


Expand All @@ -97,7 +100,7 @@ def test(session: nox.Session) -> None:

@nox.session(name="test-rust", venv_backend="none")
def test_rust(session: nox.Session):
_run_cargo_test(session, package="pyo3-build-config")
_run_cargo_test(session, package="pyo3-build-config", features="resolve-config")
Comment thread
ngoldbaum marked this conversation as resolved.
Outdated
_run_cargo_test(session, package="pyo3-macros-backend")
_run_cargo_test(session, package="pyo3-macros")

Expand All @@ -124,15 +127,11 @@ def test_rust(session: nox.Session):
# We need to pass the feature set to the test command
# so that it can be used in the test code
# (e.g. for `#[cfg(feature = "abi3-py38")]`)
if feature_set and "abi3" in feature_set and FREE_THREADED_BUILD:
# free-threaded builds don't support abi3 yet
continue

_run_cargo_test(session, features=feature_set, extra_flags=flags)

if (
feature_set
and "abi3" in feature_set
and "abi3t" not in feature_set
and "full" in feature_set
and sys.version_info >= (3, 9)
):
Expand All @@ -143,6 +142,20 @@ def test_rust(session: nox.Session):
extra_flags=flags,
)

if (
feature_set
and "abi3t" in feature_set
and "full" in feature_set
and sys.version_info >= (3, 16)
):
# run abi3t-py315 tests to check for abi3t forward
# compatibility
_run_cargo_test(
session,
features=feature_set.replace("abi3t", "abi3t-py315"),
extra_flags=flags,
)


@nox.session(name="test-py", venv_backend="none")
def test_py(session: nox.Session) -> None:
Expand Down Expand Up @@ -1194,7 +1207,7 @@ def test_version_limits(session: nox.Session):
with _config_file() as config_file:
env["PYO3_CONFIG_FILE"] = config_file.name

assert "3.6" not in PY_VERSIONS
assert "3.7" not in PY_VERSIONS
Comment thread
ngoldbaum marked this conversation as resolved.
config_file.set("CPython", "3.6")
_run_cargo(session, "check", env=env, expect_error=True)

Expand All @@ -1216,6 +1229,7 @@ def test_version_limits(session: nox.Session):
config_file.set("CPython", "3.16")
env["PYO3_USE_ABI3_FORWARD_COMPATIBILITY"] = "1"
_run_cargo(session, "check", env=env)
del env["PYO3_USE_ABI3_FORWARD_COMPATIBILITY"]

# we only support 3.11 PyPy
assert "3.10" not in PYPY_VERSIONS
Expand All @@ -1230,6 +1244,23 @@ def test_version_limits(session: nox.Session):
config_file.set("CPython", "3.14t")
_run_cargo(session, "check", env=env)

# 3.15t is PyO3's maximum version of free-threaded Python
config_file.set("CPython", "3.15t")
_run_cargo(session, "check", env=env)

# 3.16t should build with abi3t forward compatibility
config_file.set("CPython", "3.16t")
env["PYO3_USE_ABI3T_FORWARD_COMPATIBILITY"] = "1"
_run_cargo(session, "check", env=env)
del env["PYO3_USE_ABI3T_FORWARD_COMPATIBILITY"]

# 3.17t isn't supported
config_file.set("CPython", "3.17t")
_run_cargo(session, "check", env=env, expect_error=True)

# 3.17t CPython should build if abi3 is explicitly requested
_run_cargo(session, "check", "--features=pyo3/abi3t", env=env)

# attempt to build with latest version and check that abi3 version
# configured matches the feature
max_minor_version = max(int(v.split(".")[1]) for v in ABI3_PY_VERSIONS)
Expand All @@ -1251,7 +1282,7 @@ def test_version_limits(session: nox.Session):
# "An abi3-py3* feature must be specified when compiling without a Python
# interpreter."
#
# then `ABI3_MAX_MINOR` in `pyo3-build-config/src/impl_.rs` is probably outdated.
# then `STABLE_ABI_MAX_MINOR` in `pyo3-build-config/src/impl_.rs` is probably outdated.
assert f"version=3.{max_minor_version}" in stderr, (
f"Expected to see version=3.{max_minor_version}, got: \n\n{stderr}"
)
Expand All @@ -1271,6 +1302,9 @@ def _check_raw_dylib_macro(session: nox.Session):
if minor >= 13:
expected_dlls.add(f"python3{minor}t")
expected_dlls.add(f"python3{minor}t_d")
if minor >= 15:
expected_dlls.add("python3t")
expected_dlls.add("python3t_d")

# PyPy DLL names (libpypy3.X-c.dll)
pypy_min, pypy_max = _parse_supported_interpreter_version("pypy")
Expand Down Expand Up @@ -1415,6 +1449,10 @@ def check_feature_powerset(session: nox.Session):
f"abi3-py3{ver.split('.')[1]}" for ver in ABI3_PY_VERSIONS
}

EXPECTED_ABI3T_FEATURES = {
f"abi3t-py3{ver.split('.')[1].strip('t')}" for ver in ABI3T_PY_VERSIONS
}

EXCLUDED_FROM_FULL = {
"nightly",
"extension-module",
Expand All @@ -1428,20 +1466,37 @@ def check_feature_powerset(session: nox.Session):
features = cargo_toml["features"]

full_feature = set(features["full"])
abi3_features = {feature for feature in features if feature.startswith("abi3")}
abi3_features = {
feature
for feature in features
if feature.startswith("abi3") and not feature.startswith("abi3t")
}
abi3_version_features = abi3_features - {"abi3"}

unexpected_abi3_features = abi3_version_features - EXPECTED_ABI3_FEATURES
if unexpected_abi3_features:
abi3t_features = {feature for feature in features if feature.startswith("abi3t")}
abi3t_version_features = abi3t_features - {"abi3t"}

unexpected_stable_abi_features = (
abi3_version_features - EXPECTED_ABI3_FEATURES - EXPECTED_ABI3T_FEATURES
)
if unexpected_stable_abi_features:
session.error(
f"unexpected `abi3` features found in Cargo.toml: {unexpected_abi3_features}"
f"unexpected `abi3` or `abi3t` features found in Cargo.toml: {unexpected_stable_abi_features}"
)

missing_abi3_features = EXPECTED_ABI3_FEATURES - abi3_version_features
if missing_abi3_features:
session.error(f"missing `abi3` features in Cargo.toml: {missing_abi3_features}")

expected_full_feature = features.keys() - EXCLUDED_FROM_FULL - abi3_features
missing_abi3t_features = EXPECTED_ABI3T_FEATURES - abi3t_version_features
if missing_abi3t_features:
session.error(
f"missing `abi3t` features in Cargo.toml: {missing_abi3t_features}"
)

expected_full_feature = (
features.keys() - EXCLUDED_FROM_FULL - abi3_features - abi3t_features
)

uncovered_features = expected_full_feature - full_feature
if uncovered_features:
Expand Down Expand Up @@ -1470,6 +1525,7 @@ def check_feature_powerset(session: nox.Session):
features_to_skip = [
*(EXCLUDED_FROM_FULL),
*abi3_version_features,
*abi3t_version_features,
]

# deny warnings
Expand All @@ -1482,17 +1538,18 @@ def check_feature_powerset(session: nox.Session):
subcommand = "minimal-versions"

comma_join = ",".join
_run_cargo(
session,
subcommand,
"--feature-powerset",
'--optional-deps=""',
f'--skip="{comma_join(features_to_skip)}"',
*(f"--group-features={comma_join(group)}" for group in features_to_group),
"check",
"--all-targets",
env=env,
)
for abi_name in ["abi3", "abi3t"]:
_run_cargo(
session,
subcommand,
"--feature-powerset",
'--optional-deps=""',
f'--skip="{comma_join(features_to_skip + [abi_name])}"',
*(f"--group-features={comma_join(group)}" for group in features_to_group),
"check",
"--all-targets",
env=env,
)


@nox.session(name="update-ui-tests", venv_backend="none")
Expand Down Expand Up @@ -1608,6 +1665,22 @@ def _get_feature_sets() -> Tuple[Optional[str], ...]:
if is_rust_nightly():
features += ",nightly"

if FREE_THREADED_BUILD:
if sys.version_info >= (3, 15):
return (None, "abi3t", features, f"abi3t,{features}")
else:
return (None, features)

# do fewer abi3t builds?
if sys.version_info >= (3, 15):
return (
None,
"abi3",
"abi3t",
features,
f"abi3,{features}",
f"abi3t,{features}",
)
return (None, "abi3", features, f"abi3,{features}")


Expand Down
Loading
Loading