@@ -228,25 +228,28 @@ pub mod _detail {
228
228
handle_callback, py_fn_impl, AbortOnDrop , PyObjectCallbackConverter ,
229
229
PythonObjectCallbackConverter ,
230
230
} ;
231
+ pub use paste;
231
232
}
232
233
233
234
/// Expands to an `extern "C"` function that allows Python to load
234
235
/// the rust code as a Python extension module.
235
236
///
236
- /// Macro syntax: `py_module_initializer!($name, $py2_init, $py3_init, |$py, $m| $body)`
237
+ /// Macro syntax: `py_module_initializer!($name, |$py, $m| $body)`
237
238
///
238
239
/// 1. `name`: The module name as a Rust identifier.
239
- /// 2. `py2_init`: "init" + $name. Necessary because macros can't use concat_idents!().
240
- /// 3. `py3_init`: "PyInit_" + $name. Necessary because macros can't use concat_idents!().
241
- /// 4. A lambda of type `Fn(Python, &PyModule) -> PyResult<()>`.
240
+ /// 2. A lambda of type `Fn(Python, &PyModule) -> PyResult<()>`.
242
241
/// This function will be called when the module is imported, and is responsible
243
242
/// for adding the module's members.
244
243
///
244
+ /// For backwards compatibilty with older versions of rust-cpython,
245
+ /// two additional name identifiers (for py2 and py3 initializer names)
246
+ /// can be provided, but they will be ignored.
247
+ ///
245
248
/// # Example
246
249
/// ```
247
250
/// use cpython::{Python, PyResult, PyObject, py_module_initializer, py_fn};
248
251
///
249
- /// py_module_initializer!(hello, inithello, PyInit_hello, |py, m| {
252
+ /// py_module_initializer!(hello, |py, m| {
250
253
/// m.add(py, "__doc__", "Module documentation string")?;
251
254
/// m.add(py, "run", py_fn!(py, run()))?;
252
255
/// Ok(())
@@ -287,16 +290,18 @@ pub mod _detail {
287
290
#[ macro_export]
288
291
#[ cfg( feature = "python27-sys" ) ]
289
292
macro_rules! py_module_initializer {
290
- ( $name: ident, $py2: ident, $py3: ident, |$py_id: ident, $m_id: ident| $body: expr) => {
291
- #[ no_mangle]
292
- #[ allow( non_snake_case) ]
293
- pub unsafe extern "C" fn $py2( ) {
294
- // Nest init function so that $body isn't in unsafe context
295
- fn init( $py_id: $crate:: Python , $m_id: & $crate:: PyModule ) -> $crate:: PyResult <( ) > {
296
- $body
293
+ ( $name: ident, $( $_py2: ident, $_py3: ident, ) ? |$py_id: ident, $m_id: ident| $body: tt) => {
294
+ $crate:: _detail:: paste:: item! {
295
+ #[ no_mangle]
296
+ #[ allow( non_snake_case) ]
297
+ pub unsafe extern "C" fn [ < init $name >] ( ) {
298
+ // Nest init function so that $body isn't in unsafe context
299
+ fn init( $py_id: $crate:: Python , $m_id: & $crate:: PyModule ) -> $crate:: PyResult <( ) > {
300
+ $body
301
+ }
302
+ let name = concat!( stringify!( $name) , "\0 " ) . as_ptr( ) as * const _;
303
+ $crate:: py_module_initializer_impl( name, init)
297
304
}
298
- let name = concat!( stringify!( $name) , "\0 " ) . as_ptr( ) as * const _;
299
- $crate:: py_module_initializer_impl( name, init)
300
305
}
301
306
} ;
302
307
}
@@ -335,20 +340,22 @@ pub unsafe fn py_module_initializer_impl(
335
340
#[ macro_export]
336
341
#[ cfg( feature = "python3-sys" ) ]
337
342
macro_rules! py_module_initializer {
338
- ( $name: ident, $py2: ident, $py3: ident, |$py_id: ident, $m_id: ident| $body: expr) => {
339
- #[ no_mangle]
340
- #[ allow( non_snake_case) ]
341
- pub unsafe extern "C" fn $py3( ) -> * mut $crate:: _detail:: ffi:: PyObject {
342
- // Nest init function so that $body isn't in unsafe context
343
- fn init( $py_id: $crate:: Python , $m_id: & $crate:: PyModule ) -> $crate:: PyResult <( ) > {
344
- $body
343
+ ( $name: ident, $( $_py2: ident, $_py3: ident, ) ? |$py_id: ident, $m_id: ident| $body: tt) => {
344
+ $crate:: _detail:: paste:: item! {
345
+ #[ no_mangle]
346
+ #[ allow( non_snake_case) ]
347
+ pub unsafe extern "C" fn [ < PyInit_ $name >] ( ) -> * mut $crate:: _detail:: ffi:: PyObject {
348
+ // Nest init function so that $body isn't in unsafe context
349
+ fn init( $py_id: $crate:: Python , $m_id: & $crate:: PyModule ) -> $crate:: PyResult <( ) > {
350
+ $body
351
+ }
352
+ static mut MODULE_DEF : $crate:: _detail:: ffi:: PyModuleDef =
353
+ $crate:: _detail:: ffi:: PyModuleDef_INIT ;
354
+ // We can't convert &'static str to *const c_char within a static initializer,
355
+ // so we'll do it here in the module initialization:
356
+ MODULE_DEF . m_name = concat!( stringify!( $name) , "\0 " ) . as_ptr( ) as * const _;
357
+ $crate:: py_module_initializer_impl( & mut MODULE_DEF , init)
345
358
}
346
- static mut MODULE_DEF : $crate:: _detail:: ffi:: PyModuleDef =
347
- $crate:: _detail:: ffi:: PyModuleDef_INIT ;
348
- // We can't convert &'static str to *const c_char within a static initializer,
349
- // so we'll do it here in the module initialization:
350
- MODULE_DEF . m_name = concat!( stringify!( $name) , "\0 " ) . as_ptr( ) as * const _;
351
- $crate:: py_module_initializer_impl( & mut MODULE_DEF , init)
352
359
}
353
360
} ;
354
361
}
0 commit comments