public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Fabio Valentini <decathorpe@gmail.com>
To: git-commits@fedoraproject.org
Subject: [rpms/rust-pyo3] rawhide: Include pending upstream fix for py315 on 32-bit / big-endian
Date: Sat, 27 Jun 2026 12:23:41 GMT	[thread overview]
Message-ID: <178256302172.1.6115223988669607526.rpms-rust-pyo3-68152293df19@fedoraproject.org> (raw)

A new commit has been pushed.

Repo   : rpms/rust-pyo3
Branch : rawhide
Commit : 68152293df196ab383e40d5b4f0bd5eecb68a9c5
Author : Fabio Valentini <decathorpe@gmail.com>
Date   : 2026-06-27T14:22:52+02:00
Stats  : +244/-0 in 2 file(s)
URL    : https://src.fedoraproject.org/rpms/rust-pyo3/c/68152293df196ab383e40d5b4f0bd5eecb68a9c5?branch=rawhide

Log:
Include pending upstream fix for py315 on 32-bit / big-endian

---
diff --git a/6150.patch b/6150.patch
new file mode 100644
index 0000000..a302712
--- /dev/null
+++ b/6150.patch
@@ -0,0 +1,242 @@
+From fe9022ff24f65b120a662199074048f031935732 Mon Sep 17 00:00:00 2001
+From: David Hewitt <mail@davidhewitt.dev>
+Date: Sun, 21 Jun 2026 21:31:16 +0100
+Subject: [PATCH 1/4] fix 3.15+ `append_to_inittab` on platforms which aren't
+ 64-bit little-endian
+
+---
+ src/impl_/pymodule.rs  | 51 +++++++++++++++++++++++++++++-------------
+ src/internal_tricks.rs |  7 ++++++
+ 2 files changed, 42 insertions(+), 16 deletions(-)
+
+diff --git a/src/impl_/pymodule.rs b/src/impl_/pymodule.rs
+index 25e7415fa61..47f5ef31993 100644
+--- a/src/impl_/pymodule.rs
++++ b/src/impl_/pymodule.rs
+@@ -30,6 +30,8 @@ use portable_atomic::AtomicI64;
+ 
+ #[cfg(not(any(PyPy, GraalPy)))]
+ use crate::exceptions::PyImportError;
++#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
++use crate::internal_tricks::array_ptr_as_mut;
+ use crate::prelude::PyTypeMethods;
+ use crate::{
+     ffi,
+@@ -94,9 +96,7 @@ impl ModuleDef {
+         let ffi_def = UnsafeCell::new(ffi::PyModuleDef {
+             m_name: name.as_ptr(),
+             m_doc: doc.as_ptr(),
+-            // TODO: would be slightly nicer to use `[T]::as_mut_ptr()` here,
+-            // but that requires mut ptr deref on MSRV.
+-            m_slots: slots.0.get() as _,
++            m_slots: array_ptr_as_mut(slots.pep_489_slots.get()),
+             ..INIT
+         });
+ 
+@@ -235,9 +235,10 @@ impl ModuleDef {
+                 .map(|py_module| py_module.clone_ref(py))
+         }
+     }
++
+     #[cfg(Py_3_15)]
+     pub fn get_slots(&'static self) -> *mut ffi::PySlot {
+-        self.slots.0.get() as *mut ffi::PySlot
++        array_ptr_as_mut(self.slots.pep_820_slots.get())
+     }
+ }
+ 
+@@ -307,10 +308,7 @@ const MAX_SLOTS_WITH_TRAILING_NULL: usize = MAX_SLOTS + 1;
+ /// actual slots pushed due to the need to have a zeroed element on the end.
+ pub struct PyModuleSlotsBuilder {
+     // values (initially all zeroed)
+-    #[cfg(not(Py_3_15))]
+-    values: [ffi::PyModuleDef_Slot; MAX_SLOTS_WITH_TRAILING_NULL],
+-    #[cfg(Py_3_15)]
+-    values: [ffi::PySlot; MAX_SLOTS_WITH_TRAILING_NULL],
++    slots: PyModuleSlots,
+     // current length
+     len: usize,
+ }
+@@ -325,7 +323,15 @@ impl PyModuleSlotsBuilder {
+     #[allow(clippy::new_without_default)]
+     pub const fn new() -> Self {
+         Self {
+-            values: [unsafe { core::mem::zeroed() }; MAX_SLOTS_WITH_TRAILING_NULL],
++            slots: PyModuleSlots {
++                #[cfg(Py_3_15)]
++                pep_820_slots: UnsafeCell::new(
++                    [unsafe { core::mem::zeroed() }; MAX_SLOTS_WITH_TRAILING_NULL],
++                ),
++                pep_489_slots: UnsafeCell::new(
++                    [unsafe { core::mem::zeroed() }; MAX_SLOTS_WITH_TRAILING_NULL],
++                ),
++            },
+             len: 0,
+         }
+     }
+@@ -426,7 +432,7 @@ impl PyModuleSlotsBuilder {
+     }
+ 
+     pub const fn build(self) -> PyModuleSlots {
+-        PyModuleSlots(UnsafeCell::new(self.values))
++        self.slots
+     }
+ 
+     #[cfg(not(Py_3_15))]
+@@ -437,7 +443,7 @@ impl PyModuleSlotsBuilder {
+             self.len < MAX_SLOTS,
+             "Cannot add more than MAX_SLOTS slots to a PyModuleSlots",
+         );
+-        self.values[self.len] = ffi::PyModuleDef_Slot { slot, value };
++        self.slots.pep_489_slots.get_mut()[self.len] = ffi::PyModuleDef_Slot { slot, value };
+         self.len += 1;
+         self
+     }
+@@ -448,17 +454,30 @@ impl PyModuleSlotsBuilder {
+             self.len < MAX_SLOTS,
+             "Cannot add more than MAX_SLOTS slots to a PyModuleSlots",
+         );
+-        self.values[self.len] = value;
++        self.slots.pep_820_slots.get_mut()[self.len] = value;
++        self.slots.pep_489_slots.get_mut()[self.len] = ffi::PyModuleDef_Slot {
++            slot: value.sl_id as c_int,
++            // SAFETY: interpreting the `PySlot` value as a void* for the slot
++            //
++            // This will need removing if any future `PySlot` values can't be
++            // represented in legacy slots.
++            value: unsafe { value.anon2.sl_ptr },
++        };
+         self.len += 1;
+         self
+     }
+ }
+ 
+ /// Wrapper to safely store module slots, to be used in a `ModuleDef`.
+-#[cfg(not(Py_3_15))]
+-pub struct PyModuleSlots(UnsafeCell<[ffi::PyModuleDef_Slot; MAX_SLOTS_WITH_TRAILING_NULL]>);
+-#[cfg(Py_3_15)]
+-pub struct PyModuleSlots(UnsafeCell<[ffi::PySlot; MAX_SLOTS_WITH_TRAILING_NULL]>);
++pub struct PyModuleSlots {
++    #[cfg(Py_3_15)]
++    pep_820_slots: UnsafeCell<[ffi::PySlot; MAX_SLOTS_WITH_TRAILING_NULL]>,
++    /// PEP 489 slots
++    ///
++    /// These are still needed on 3.15+ for `append_to_inittab` and for as long as
++    /// we continue to emit `PyInit_<name>` entry points on 3.15+.
++    pep_489_slots: UnsafeCell<[ffi::PyModuleDef_Slot; MAX_SLOTS_WITH_TRAILING_NULL]>,
++}
+ 
+ // It might be possible to avoid this with SyncUnsafeCell in the future
+ //
+diff --git a/src/internal_tricks.rs b/src/internal_tricks.rs
+index 0d21c69dcc7..04d6a8f56d7 100644
+--- a/src/internal_tricks.rs
++++ b/src/internal_tricks.rs
+@@ -55,3 +55,10 @@ pub(crate) fn box_into_non_null<T>(b: Box<T>) -> NonNull<T> {
+     // SAFETY: `Box::into_raw` guarantees an non-null pointer
+     unsafe { NonNull::new_unchecked(Box::into_raw(b)) }
+ }
++
++/// Replacement for the unstable `<*mut [T; N]>::as_mut_ptr` method, which avoids
++/// possibility of type getting lost from using e.g. `.cast()` to change array
++/// type to point to the data.
++pub(crate) const fn array_ptr_as_mut<T, const N: usize>(ptr: *mut [T; N]) -> *mut T {
++    ptr.cast()
++}
+
+From 272d8f12e57076b8bc052cb8a4cc7c45307b89e3 Mon Sep 17 00:00:00 2001
+From: David Hewitt <mail@davidhewitt.dev>
+Date: Fri, 26 Jun 2026 08:06:31 +0100
+Subject: [PATCH 2/4] fix test conditional code
+
+---
+ src/impl_/pymodule.rs | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/src/impl_/pymodule.rs b/src/impl_/pymodule.rs
+index 47f5ef31993..a207e48b01d 100644
+--- a/src/impl_/pymodule.rs
++++ b/src/impl_/pymodule.rs
+@@ -627,7 +627,10 @@ mod tests {
+ 
+         #[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
+         unsafe {
+-            assert_eq!((*module_def.ffi_def.get()).m_slots, SLOTS.0.get().cast());
++            assert_eq!(
++                (*module_def.ffi_def.get()).m_slots,
++                SLOTS.pep_489_slots.get().cast()
++            );
+         }
+         #[cfg(Py_3_15)]
+         {
+@@ -639,17 +642,17 @@ mod tests {
+     #[test]
+     #[cfg(panic = "unwind")]
+     fn test_build_maximal_slots() {
+-        let builder = PyModuleSlotsBuilder::new()
++        let mut builder = PyModuleSlotsBuilder::new()
+             .with_mod_exec(module_exec)
+             .with_name(c"test_module")
+             .with_doc(c"some doc")
+             .with_gil_used(false)
+             .with_abi_info();
+-        let second_last = builder.values[builder.len - 1];
+-        let last = builder.values[builder.len];
+ 
+         #[cfg(Py_3_15)]
+         {
++            let second_last = builder.slots.pep_820_slots.get_mut()[builder.len - 1];
++            let last = builder.slots.pep_820_slots.get_mut()[builder.len];
+             let zeroed = unsafe { core::mem::zeroed() };
+             fn raw_bytes(inst: &ffi::PySlot) -> &[u8] {
+                 unsafe {
+@@ -665,6 +668,8 @@ mod tests {
+         }
+         #[cfg(not(Py_3_15))]
+         {
++            let second_last = builder.slots.pep_489_slots.get_mut()[builder.len - 1];
++            let last = builder.slots.pep_489_slots.get_mut()[builder.len];
+             let zeroed = ffi::PyModuleDef_Slot::default();
+             assert!(last == zeroed);
+             assert!(second_last != zeroed);
+
+From a8a989e7875498187bc9a15942ddca301f6e24e4 Mon Sep 17 00:00:00 2001
+From: David Hewitt <mail@davidhewitt.dev>
+Date: Fri, 26 Jun 2026 08:53:54 +0100
+Subject: [PATCH 3/4] fix missing import
+
+---
+ src/impl_/pymodule.rs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/impl_/pymodule.rs b/src/impl_/pymodule.rs
+index a207e48b01d..9161d487cd6 100644
+--- a/src/impl_/pymodule.rs
++++ b/src/impl_/pymodule.rs
+@@ -30,7 +30,7 @@ use portable_atomic::AtomicI64;
+ 
+ #[cfg(not(any(PyPy, GraalPy)))]
+ use crate::exceptions::PyImportError;
+-#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
++#[cfg(any(not(all(Py_LIMITED_API, Py_GIL_DISABLED)), Py_3_15))]
+ use crate::internal_tricks::array_ptr_as_mut;
+ use crate::prelude::PyTypeMethods;
+ use crate::{
+
+From b41e08b3c260793473d8147aee8379245c9a00b5 Mon Sep 17 00:00:00 2001
+From: David Hewitt <mail@davidhewitt.dev>
+Date: Fri, 26 Jun 2026 11:46:30 +0100
+Subject: [PATCH 4/4] newsfragment
+
+---
+ newsfragments/6150.fixed.md | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 100644 newsfragments/6150.fixed.md
+
+diff --git a/newsfragments/6150.fixed.md b/newsfragments/6150.fixed.md
+new file mode 100644
+index 00000000000..9587b91d6dd
+--- /dev/null
++++ b/newsfragments/6150.fixed.md
+@@ -0,0 +1 @@
++Fix `append_to_inittab` and `PyInit_<module>` internal module definition corruption on 32-bit and big-endian platforms.

diff --git a/rust-pyo3.spec b/rust-pyo3.spec
index 1523486..4570151 100644
--- a/rust-pyo3.spec
+++ b/rust-pyo3.spec
@@ -21,6 +21,8 @@ Patch:          pyo3-fix-metadata.diff
 # * make unsafe subinterpreter support available via cfg flag:
 #   https://bugzilla.redhat.com/show_bug.cgi?id=2298403
 Patch2:         0001-Make-unsafe-subinterpreter-support-available-via-cfg.patch
+# * pending upstream fix for Python 3.15 on 32-bit / big-endian architectures
+Patch3:         https://github.com/PyO3/pyo3/pull/6150.patch
 
 BuildRequires:  cargo-rpm-macros >= 24
 BuildRequires:  dos2unix

                 reply	other threads:[~2026-06-27 12:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178256302172.1.6115223988669607526.rpms-rust-pyo3-68152293df19@fedoraproject.org \
    --to=decathorpe@gmail.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox