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. |
14 | macro_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 | |
53 | mod py_3_10; |
54 | mod py_3_13; |
55 | mod py_3_9; |
56 | |
57 | pub use self::py_3_10::*; |
58 | pub use self::py_3_13::*; |
59 | pub use self::py_3_9::*; |
60 | |