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::*;