@@ -214,6 +214,10 @@ mod pythonrun;
214
214
pub mod py_class;
215
215
mod sharedref;
216
216
217
+ // Re-export paste so it can be used in macros.
218
+ #[ doc( hidden) ]
219
+ pub use paste;
220
+
217
221
/// Private re-exports for macros. Do not use.
218
222
#[ doc( hidden) ]
219
223
pub mod _detail {
@@ -233,20 +237,22 @@ pub mod _detail {
233
237
/// Expands to an `extern "C"` function that allows Python to load
234
238
/// the rust code as a Python extension module.
235
239
///
236
- /// Macro syntax: `py_module_initializer!($name, $py2_init, $py3_init, |$py, $m| $body)`
240
+ /// Macro syntax: `py_module_initializer!($name, |$py, $m| $body)`
237
241
///
238
242
/// 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<()>`.
243
+ /// 2. A lambda of type `Fn(Python, &PyModule) -> PyResult<()>`.
242
244
/// This function will be called when the module is imported, and is responsible
243
245
/// for adding the module's members.
244
246
///
247
+ /// For backwards compatibilty with older versions of rust-cpython,
248
+ /// two additional name identifiers (for py2 and py3 initializer names)
249
+ /// can be provided, but they will be ignored.
250
+ ///
245
251
/// # Example
246
252
/// ```
247
253
/// use cpython::{Python, PyResult, PyObject, py_module_initializer, py_fn};
248
254
///
249
- /// py_module_initializer!(hello, inithello, PyInit_hello, |py, m| {
255
+ /// py_module_initializer!(hello, |py, m| {
250
256
/// m.add(py, "__doc__", "Module documentation string")?;
251
257
/// m.add(py, "run", py_fn!(py, run()))?;
252
258
/// Ok(())
@@ -287,16 +293,18 @@ pub mod _detail {
287
293
#[ macro_export]
288
294
#[ cfg( feature = "python27-sys" ) ]
289
295
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
296
+ ( $name: ident, $( $_py2: ident, $_py3: ident, ) ? |$py_id: ident, $m_id: ident| $body: tt) => {
297
+ $crate:: paste:: item! {
298
+ #[ no_mangle]
299
+ #[ allow( non_snake_case) ]
300
+ pub unsafe extern "C" fn [ < init $name >] ( ) {
301
+ // Nest init function so that $body isn't in unsafe context
302
+ fn init( $py_id: $crate:: Python , $m_id: & $crate:: PyModule ) -> $crate:: PyResult <( ) > {
303
+ $body
304
+ }
305
+ let name = concat!( stringify!( $name) , "\0 " ) . as_ptr( ) as * const _;
306
+ $crate:: py_module_initializer_impl( name, init)
297
307
}
298
- let name = concat!( stringify!( $name) , "\0 " ) . as_ptr( ) as * const _;
299
- $crate:: py_module_initializer_impl( name, init)
300
308
}
301
309
} ;
302
310
}
@@ -335,20 +343,22 @@ pub unsafe fn py_module_initializer_impl(
335
343
#[ macro_export]
336
344
#[ cfg( feature = "python3-sys" ) ]
337
345
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
346
+ ( $name: ident, $( $_py2: ident, $_py3: ident, ) ? |$py_id: ident, $m_id: ident| $body: tt) => {
347
+ $crate:: paste:: item! {
348
+ #[ no_mangle]
349
+ #[ allow( non_snake_case) ]
350
+ pub unsafe extern "C" fn [ < PyInit_ $name >] ( ) -> * mut $crate:: _detail:: ffi:: PyObject {
351
+ // Nest init function so that $body isn't in unsafe context
352
+ fn init( $py_id: $crate:: Python , $m_id: & $crate:: PyModule ) -> $crate:: PyResult <( ) > {
353
+ $body
354
+ }
355
+ static mut MODULE_DEF : $crate:: _detail:: ffi:: PyModuleDef =
356
+ $crate:: _detail:: ffi:: PyModuleDef_INIT ;
357
+ // We can't convert &'static str to *const c_char within a static initializer,
358
+ // so we'll do it here in the module initialization:
359
+ MODULE_DEF . m_name = concat!( stringify!( $name) , "\0 " ) . as_ptr( ) as * const _;
360
+ $crate:: py_module_initializer_impl( & mut MODULE_DEF , init)
345
361
}
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
362
}
353
363
} ;
354
364
}
0 commit comments