Skip to content

Commit a4dcf08

Browse files
committed
PEP 489 Multi-phase extension module initialization
1 parent d7f9acc commit a4dcf08

1 file changed

Lines changed: 44 additions & 22 deletions

File tree

src/lib.rs

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ mod unicode;
2222
use pyo3_ffi::*;
2323
use std::borrow::Cow;
2424
use std::os::raw::c_char;
25+
use std::os::raw::c_int;
26+
use std::os::raw::c_void;
2527

2628
#[allow(unused_imports)]
2729
use core::ptr::{null, null_mut, NonNull};
2830

29-
const DUMPS_DOC: &str =
30-
"dumps(obj, /, default=None, option=None)\n--\n\nSerialize Python objects to JSON.\0";
31-
const LOADS_DOC: &str = "loads(obj, /)\n--\n\nDeserialize JSON to Python objects.\0";
32-
3331
macro_rules! opt {
3432
($mptr:expr, $name:expr, $opt:expr) => {
3533
unsafe {
@@ -47,20 +45,7 @@ macro_rules! opt {
4745
#[no_mangle]
4846
#[cold]
4947
#[cfg_attr(feature = "unstable-simd", optimize(size))]
50-
pub unsafe extern "C" fn PyInit_orjson() -> *mut PyObject {
51-
let init = PyModuleDef {
52-
m_base: PyModuleDef_HEAD_INIT,
53-
m_name: "orjson\0".as_ptr() as *const c_char,
54-
m_doc: null(),
55-
m_size: 0,
56-
m_methods: null_mut(),
57-
m_slots: null_mut(),
58-
m_traverse: None,
59-
m_clear: None,
60-
m_free: None,
61-
};
62-
let mptr = PyModule_Create(Box::into_raw(Box::new(init)));
63-
48+
pub unsafe extern "C" fn orjson_init_exec(mptr: *mut PyObject) -> c_int {
6449
let version = env!("CARGO_PKG_VERSION");
6550
unsafe {
6651
PyModule_AddObject(
@@ -70,6 +55,9 @@ pub unsafe extern "C" fn PyInit_orjson() -> *mut PyObject {
7055
)
7156
};
7257

58+
let dumps_doc =
59+
"dumps(obj, /, default=None, option=None)\n--\n\nSerialize Python objects to JSON.\0";
60+
7361
let wrapped_dumps: PyMethodDef;
7462

7563
#[cfg(Py_3_8)]
@@ -80,7 +68,7 @@ pub unsafe extern "C" fn PyInit_orjson() -> *mut PyObject {
8068
_PyCFunctionFastWithKeywords: dumps,
8169
},
8270
ml_flags: pyo3_ffi::METH_FASTCALL | METH_KEYWORDS,
83-
ml_doc: DUMPS_DOC.as_ptr() as *const c_char,
71+
ml_doc: dumps_doc.as_ptr() as *const c_char,
8472
};
8573
}
8674
#[cfg(not(Py_3_8))]
@@ -91,9 +79,10 @@ pub unsafe extern "C" fn PyInit_orjson() -> *mut PyObject {
9179
PyCFunctionWithKeywords: dumps,
9280
},
9381
ml_flags: METH_VARARGS | METH_KEYWORDS,
94-
ml_doc: DUMPS_DOC.as_ptr() as *const c_char,
82+
ml_doc: dumps_doc.as_ptr() as *const c_char,
9583
};
9684
}
85+
9786
unsafe {
9887
PyModule_AddObject(
9988
mptr,
@@ -106,11 +95,13 @@ pub unsafe extern "C" fn PyInit_orjson() -> *mut PyObject {
10695
)
10796
};
10897

98+
let loads_doc = "loads(obj, /)\n--\n\nDeserialize JSON to Python objects.\0";
99+
109100
let wrapped_loads = PyMethodDef {
110101
ml_name: "loads\0".as_ptr() as *const c_char,
111102
ml_meth: PyMethodDefPointer { PyCFunction: loads },
112103
ml_flags: METH_O,
113-
ml_doc: LOADS_DOC.as_ptr() as *const c_char,
104+
ml_doc: loads_doc.as_ptr() as *const c_char,
114105
};
115106

116107
unsafe {
@@ -203,8 +194,39 @@ pub unsafe extern "C" fn PyInit_orjson() -> *mut PyObject {
203194
unsafe {
204195
PyModule_AddObject(mptr, "__all__\0".as_ptr() as *const c_char, pyall);
205196
};
197+
0
198+
}
206199

207-
mptr
200+
#[allow(non_snake_case)]
201+
#[no_mangle]
202+
#[cold]
203+
#[cfg_attr(feature = "unstable-simd", optimize(size))]
204+
pub unsafe extern "C" fn PyInit_orjson() -> *mut PyModuleDef {
205+
let mod_slots: Box<[PyModuleDef_Slot; 2]> = Box::new([
206+
PyModuleDef_Slot {
207+
slot: Py_mod_exec,
208+
value: orjson_init_exec as *mut c_void,
209+
},
210+
PyModuleDef_Slot {
211+
slot: 0,
212+
value: null_mut(),
213+
},
214+
]);
215+
216+
let init = Box::new(PyModuleDef {
217+
m_base: PyModuleDef_HEAD_INIT,
218+
m_name: "orjson\0".as_ptr() as *const c_char,
219+
m_doc: null(),
220+
m_size: 0,
221+
m_methods: null_mut(),
222+
m_slots: Box::into_raw(mod_slots) as *mut PyModuleDef_Slot,
223+
m_traverse: None,
224+
m_clear: None,
225+
m_free: None,
226+
});
227+
let init_ptr = Box::into_raw(init);
228+
PyModuleDef_Init(init_ptr);
229+
init_ptr
208230
}
209231

210232
#[cold]

0 commit comments

Comments
 (0)