Skip to content

Python 3.15b1 ABI support#6014

Merged
ngoldbaum merged 17 commits into
PyO3:mainfrom
ngoldbaum:pep-820
May 12, 2026
Merged

Python 3.15b1 ABI support#6014
ngoldbaum merged 17 commits into
PyO3:mainfrom
ngoldbaum:pep-820

Conversation

@ngoldbaum
Copy link
Copy Markdown
Contributor

@ngoldbaum ngoldbaum commented May 4, 2026

towards fixing #6012.

Adds support for the PEP 820 PySlot API, updates the PEP 793 implementation, and adds the critical section API to the limited API. Also fixes a small change to PyTypeObject that crept in since alpha8.

Claude helped a bit for code review and to figure out the PySlot_FUNC and the __pyo3_pymodexport macros.

Ping @bschoenmaeckers because you asked in the issue what this would look like.

Comment thread pyo3-ffi/src/slots.rs Outdated
Comment thread pyo3-ffi/src/slots.rs Outdated
Comment thread pyo3-ffi/examples/sequential/src/module.rs
@ngoldbaum ngoldbaum marked this pull request as ready for review May 8, 2026 17:10
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 8, 2026

Merging this PR will not alter performance

✅ 125 untouched benchmarks


Comparing ngoldbaum:pep-820 (26809b9) with main (58d5a1e)

Open in CodSpeed

@ngoldbaum
Copy link
Copy Markdown
Contributor Author

ngoldbaum commented May 8, 2026

I added 3.15 and 3.15t CI to the PR CI builds and the new CI is passing. I just rebased and squashed to get a better coverage report. (EDIT: I guess it makes sense the coverage CI is failing, given the new untested FFI definitions)

That said, this is definitely ready for review. Please let me know if you'd prefer I do this in smaller chunks.

Copy link
Copy Markdown
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, overall looks good to me, a few small suggestions.

Comment thread pyo3-ffi/src/slots_generated.rs Outdated
Comment thread pyo3-ffi/src/typeslots.rs Outdated
Comment thread pyo3-ffi/src/slots.rs Outdated
Comment thread pyo3-ffi/src/slots.rs Outdated
if val >= 0 && val <= u16::MAX as c_int {
val as u16
} else {
panic!("Slot ID out of range for u16!");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
panic!("Slot ID out of range for u16!");
panic!("Slot ID out of range for u16");

Comment thread pyo3-ffi/src/slots.rs Outdated
Comment thread pyo3-ffi/src/slots.rs Outdated
Comment thread src/impl_/pymodule.rs Outdated
ngoldbaum and others added 2 commits May 9, 2026 10:16
Co-authored-by: David Hewitt <mail@davidhewitt.dev>
Comment thread pyo3-ffi/src/slots.rs Outdated
Comment thread pyo3-ffi/src/slots_generated.rs Outdated
Comment thread pyo3-ffi/src/typeslots.rs Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's just me, but perhaps we should maintain a PyO3-specific fork of bindgen to output better type names for anonymous unions and other kludges with for_all_fields...

Comment thread pyo3-ffi/src/typeslots.rs Outdated
Comment thread pyo3-ffi/src/slots.rs Outdated
Comment thread pyo3-ffi/src/slots.rs Outdated
@ngoldbaum
Copy link
Copy Markdown
Contributor Author

OK, ready for another review pass.

Comment thread pyo3-ffi/src/slots.rs
Comment on lines +116 to +122
pub const fn PySlot_STATIC_DATA(NAME: c_int, VALUE: *mut c_void) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_STATIC,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { sl_ptr: VALUE },
}
Copy link
Copy Markdown
Contributor

@clin1234 clin1234 May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn PySlot_STATIC_DATA(NAME: c_int, VALUE: *mut c_void) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_STATIC,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { sl_ptr: VALUE },
}
pub const fn PySlot_STATIC_DATA(NAME: c_int, VALUE: std::ptr::NonNull<*mut c_void>) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_STATIC,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { unsafe {
sl_ptr: (*VALUE).as_ptr()
} },
}

Comment thread pyo3-ffi/src/slots.rs
Comment on lines +126 to +132
pub const fn PySlot_PTR(NAME: c_int, VALUE: *mut c_void) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_INTPTR,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { sl_ptr: VALUE },
}
Copy link
Copy Markdown
Contributor

@clin1234 clin1234 May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn PySlot_PTR(NAME: c_int, VALUE: *mut c_void) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_INTPTR,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { sl_ptr: VALUE },
}
pub const fn PySlot_PTR(NAME: c_int, VALUE: std::ptr::NonNull<*mut c_void>) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_INTPTR,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { unsafe {
sl_ptr: (*VALUE).as_ptr()
} },
}

Comment thread pyo3-ffi/src/slots.rs
Comment on lines +136 to +143
pub const fn PySlot_PTR_STATIC(NAME: c_int, VALUE: *mut c_void) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_INTPTR | PySlot_STATIC,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { sl_ptr: VALUE },
}
}
Copy link
Copy Markdown
Contributor

@clin1234 clin1234 May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn PySlot_PTR_STATIC(NAME: c_int, VALUE: *mut c_void) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_INTPTR | PySlot_STATIC,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { sl_ptr: VALUE },
}
}
pub const fn PySlot_PTR_STATIC(NAME: c_int, VALUE: std::ptr::NonNull<*mut c_void>) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_INTPTR | PySlot_STATIC,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { unsafe {
sl_ptr: (*VALUE).as_ptr()
} },
}
}

Copy link
Copy Markdown
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just two minor things

Comment thread pyo3-ffi/src/slots_generated.rs Outdated
Comment thread pyo3-ffi/src/slots.rs Outdated
@ngoldbaum ngoldbaum enabled auto-merge May 11, 2026 20:47
Comment thread pyo3-ffi/src/slots.rs
Comment on lines +62 to +68
pub const fn PySlot_DATA(NAME: c_int, VALUE: *mut c_void) -> PySlot {
PySlot {
sl_id: safe_cast_c_int_to_u16(NAME),
sl_flags: PySlot_INTPTR,
anon1: _anon_union_32b { sl_reserved: 0 },
anon2: _anon_union_64b { sl_ptr: VALUE },
}

This comment was marked as resolved.

@ngoldbaum ngoldbaum added this pull request to the merge queue May 11, 2026
@ngoldbaum ngoldbaum removed this pull request from the merge queue due to a manual request May 11, 2026
@ngoldbaum
Copy link
Copy Markdown
Contributor Author

ngoldbaum commented May 11, 2026

I'm not sure whether it's correct to work around clippy warning that PySlot_FUNC should be marked unsafe because the NULL check happens conditionally. I just went ahead and marked PySlot_FUNC as unsafe for now. We can always relax that later.

@ngoldbaum ngoldbaum enabled auto-merge May 11, 2026 22:30
@ngoldbaum ngoldbaum added this pull request to the merge queue May 11, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 11, 2026
@ngoldbaum ngoldbaum enabled auto-merge May 12, 2026 00:18
@ngoldbaum ngoldbaum added this pull request to the merge queue May 12, 2026
Merged via the queue into PyO3:main with commit e742ed2 May 12, 2026
47 of 48 checks passed
@ngoldbaum ngoldbaum deleted the pep-820 branch May 12, 2026 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants