pyo3_ffi/compat/mod.rs
1//! C API Compatibility Shims
2//!
3//! Some CPython C API functions added in recent versions of Python are
4//! inherently safer to use than older C API constructs. This module
5//! exposes functions available on all Python versions that wrap the
6//! old C API on old Python versions and wrap the function directly
7//! on newer Python versions.
8
9// Unless otherwise noted, the compatibility shims are adapted from
10// the pythoncapi-compat project: https://github.com/python/pythoncapi-compat
11
12/// Internal helper macro which defines compatibility shims for C API functions, deferring to a
13/// re-export when that's available.
14macro_rules! compat_function {
15 (
16 originally_defined_for($cfg:meta);
17
18 $(#[$attrs:meta])*
19 pub unsafe fn $name:ident($($arg_names:ident: $arg_types:ty),* $(,)?) -> $ret:ty $body:block
20 ) => {
21 // Define as a standalone function under docsrs cfg so that this shows as a unique function in the docs,
22 // not a re-export (the re-export has the wrong visibility)
23 #[cfg(any(docsrs, not($cfg)))]
24 #[cfg_attr(docsrs, doc(cfg(all())))]
25 $(#[$attrs])*
26 pub unsafe fn $name(
27 $($arg_names: $arg_types,)*
28 ) -> $ret $body
29
30 #[cfg(all($cfg, not(docsrs)))]
31 pub use $crate::$name;
32
33 #[cfg(test)]
34 paste::paste! {
35 // Test that the compat function does not overlap with the original function. If the
36 // cfgs line up, then the the two glob imports will resolve to the same item via the
37 // re-export. If the cfgs mismatch, then the use of $name will be ambiguous in cases
38 // where the function is defined twice, and the test will fail to compile.
39 #[allow(unused_imports)]
40 mod [<test_ $name _export>] {
41 use $crate::*;
42 use $crate::compat::*;
43
44 #[test]
45 fn test_export() {
46 let _ = $name;
47 }
48 }
49 }
50 };
51}
52
53mod py_3_10;
54mod py_3_13;
55mod py_3_9;
56
57pub use self::py_3_10::*;
58pub use self::py_3_13::*;
59pub use self::py_3_9::*;