Skip to content

Commit 1a3945c

Browse files
docs: note of multi-phase init change, better slots handling (#5587)
* docs: note of multi-phase init change, better slots handling * Update guide/src/migration.md Co-authored-by: Marcin <marcinsere@gmail.com> --------- Co-authored-by: Marcin <marcinsere@gmail.com>
1 parent 545a527 commit 1a3945c

File tree

4 files changed

+20
-5
lines changed

4 files changed

+20
-5
lines changed

guide/src/migration.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ let _: Bound<'_, PyNone> = unsafe { Bound::from_owned_ptr(py, raw_ptr).cast_into
5959
# })
6060
```
6161

62+
### Internal change to use multi-phase initialization
63+
64+
[PEP 489](https://peps.python.org/pep-0489/) introduced "multi-phase initialization" for extension modules which provides ways to allocate and clean up per-module state.
65+
This is a necessary step towards supporting Python "subinterpreters" which run on their own copy of state.
66+
67+
Starting in PyO3 0.28, the `#[pymodule]` macro machinery has been reworked to use multi-phase initialization.
68+
The possibility of creating and consuming per-module state (and supporting subinterpreters) is left for a future PyO3 version.
69+
This should not require migration, nor is there expected to be breakage caused by the change.
70+
71+
Nevertheless, this affects the order of initialization so seemed worth noting in this guide.
72+
6273
## from 0.26.* to 0.27
6374

6475
### `FromPyObject` reworked for flexibility and efficiency

pyo3-ffi/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static mut MODULE_DEF: PyModuleDef = PyModuleDef {
7777
m_doc: c"A Python module written in Rust.".as_ptr(),
7878
m_size: 0,
7979
m_methods: std::ptr::addr_of_mut!(METHODS).cast(),
80-
m_slots: unsafe { SLOTS as *const [PyModuleDef_Slot] as *mut PyModuleDef_Slot },
80+
m_slots: std::ptr::addr_of_mut!(SLOTS).cast(),
8181
m_traverse: None,
8282
m_clear: None,
8383
m_free: None,
@@ -96,7 +96,8 @@ static mut METHODS: [PyMethodDef; 2] = [
9696
PyMethodDef::zeroed(),
9797
];
9898
99-
static mut SLOTS: &[PyModuleDef_Slot] = &[
99+
const SLOTS_LEN: usize = 1 + if cfg!(Py_3_12) { 1 } else { 0 } + if cfg!(Py_GIL_DISABLED) { 1 } else { 0 };
100+
static mut SLOTS: [PyModuleDef_Slot; SLOTS_LEN] = [
100101
// NB: only include this slot if the module does not store any global state in `static` variables
101102
// or other data which could cross between subinterpreters
102103
#[cfg(Py_3_12)]

pyo3-ffi/examples/sequential/src/module.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ pub static mut MODULE_DEF: PyModuleDef = PyModuleDef {
1414
m_free: Some(sequential_free),
1515
};
1616

17-
const SEQUENTIAL_SLOTS_LEN: usize = 3 + if cfg!(Py_GIL_DISABLED) { 1 } else { 0 };
17+
const SEQUENTIAL_SLOTS_LEN: usize =
18+
2 + if cfg!(Py_3_12) { 1 } else { 0 } + if cfg!(Py_GIL_DISABLED) { 1 } else { 0 };
1819
static mut SEQUENTIAL_SLOTS: [PyModuleDef_Slot; SEQUENTIAL_SLOTS_LEN] = [
1920
PyModuleDef_Slot {
2021
slot: Py_mod_exec,

pyo3-ffi/examples/string-sum/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ static mut MODULE_DEF: PyModuleDef = PyModuleDef {
99
m_doc: c"A Python module written in Rust.".as_ptr(),
1010
m_size: 0,
1111
m_methods: std::ptr::addr_of_mut!(METHODS).cast(),
12-
m_slots: unsafe { SLOTS as *const [PyModuleDef_Slot] as *mut PyModuleDef_Slot },
12+
m_slots: std::ptr::addr_of_mut!(SLOTS).cast(),
1313
m_traverse: None,
1414
m_clear: None,
1515
m_free: None,
@@ -28,7 +28,9 @@ static mut METHODS: [PyMethodDef; 2] = [
2828
PyMethodDef::zeroed(),
2929
];
3030

31-
static mut SLOTS: &[PyModuleDef_Slot] = &[
31+
const SLOTS_LEN: usize =
32+
1 + if cfg!(Py_3_12) { 1 } else { 0 } + if cfg!(Py_GIL_DISABLED) { 1 } else { 0 };
33+
static mut SLOTS: [PyModuleDef_Slot; SLOTS_LEN] = [
3234
#[cfg(Py_3_12)]
3335
PyModuleDef_Slot {
3436
slot: Py_mod_multiple_interpreters,

0 commit comments

Comments
 (0)