-
Notifications
You must be signed in to change notification settings - Fork 758
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ffi: define compat for `Py_NewRef` and `Py_XNewRef` * add missing inline hint Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com> * don't use std::ffi::c_int (requires MSRV 1.64) * add test to guard against ambiguity * fix `Py_NewRef` cfg on PyPy --------- Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com>
- Loading branch information
1 parent
c2f8114
commit 8bdd76d
Showing
9 changed files
with
133 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add FFI definitions `compat::Py_NewRef` and `compat::Py_XNewRef`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Remove private FFI definitions `_Py_NewRef` and `_Py_XNewRef`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
//! C API Compatibility Shims | ||
//! | ||
//! Some CPython C API functions added in recent versions of Python are | ||
//! inherently safer to use than older C API constructs. This module | ||
//! exposes functions available on all Python versions that wrap the | ||
//! old C API on old Python versions and wrap the function directly | ||
//! on newer Python versions. | ||
|
||
// Unless otherwise noted, the compatibility shims are adapted from | ||
// the pythoncapi-compat project: https://github.com/python/pythoncapi-compat | ||
|
||
/// Internal helper macro which defines compatibility shims for C API functions, deferring to a | ||
/// re-export when that's available. | ||
macro_rules! compat_function { | ||
( | ||
originally_defined_for($cfg:meta); | ||
|
||
$(#[$attrs:meta])* | ||
pub unsafe fn $name:ident($($arg_names:ident: $arg_types:ty),* $(,)?) -> $ret:ty $body:block | ||
) => { | ||
// Define as a standalone function under docsrs cfg so that this shows as a unique function in the docs, | ||
// not a re-export (the re-export has the wrong visibility) | ||
#[cfg(any(docsrs, not($cfg)))] | ||
#[cfg_attr(docsrs, doc(cfg(all())))] | ||
$(#[$attrs])* | ||
pub unsafe fn $name( | ||
$($arg_names: $arg_types,)* | ||
) -> $ret $body | ||
|
||
#[cfg(all($cfg, not(docsrs)))] | ||
pub use $crate::$name; | ||
|
||
#[cfg(test)] | ||
paste::paste! { | ||
// Test that the compat function does not overlap with the original function. If the | ||
// cfgs line up, then the the two glob imports will resolve to the same item via the | ||
// re-export. If the cfgs mismatch, then the use of $name will be ambiguous in cases | ||
// where the function is defined twice, and the test will fail to compile. | ||
#[allow(unused_imports)] | ||
mod [<test_ $name _export>] { | ||
use $crate::*; | ||
use $crate::compat::*; | ||
|
||
#[test] | ||
fn test_export() { | ||
let _ = $name; | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
|
||
mod py_3_10; | ||
mod py_3_13; | ||
|
||
pub use self::py_3_10::*; | ||
pub use self::py_3_13::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
compat_function!( | ||
originally_defined_for(Py_3_10); | ||
|
||
#[inline] | ||
pub unsafe fn Py_NewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { | ||
crate::Py_INCREF(obj); | ||
obj | ||
} | ||
); | ||
|
||
compat_function!( | ||
originally_defined_for(Py_3_10); | ||
|
||
#[inline] | ||
pub unsafe fn Py_XNewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { | ||
crate::Py_XINCREF(obj); | ||
obj | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
compat_function!( | ||
originally_defined_for(Py_3_13); | ||
|
||
#[inline] | ||
pub unsafe fn PyDict_GetItemRef( | ||
dp: *mut crate::PyObject, | ||
key: *mut crate::PyObject, | ||
result: *mut *mut crate::PyObject, | ||
) -> std::os::raw::c_int { | ||
use crate::{compat::Py_NewRef, PyDict_GetItemWithError, PyErr_Occurred}; | ||
|
||
let item = PyDict_GetItemWithError(dp, key); | ||
if !item.is_null() { | ||
*result = Py_NewRef(item); | ||
return 1; // found | ||
} | ||
*result = std::ptr::null_mut(); | ||
if PyErr_Occurred().is_null() { | ||
return 0; // not found | ||
} | ||
-1 | ||
} | ||
); | ||
|
||
compat_function!( | ||
originally_defined_for(Py_3_13); | ||
|
||
#[inline] | ||
pub unsafe fn PyList_GetItemRef( | ||
arg1: *mut crate::PyObject, | ||
arg2: crate::Py_ssize_t, | ||
) -> *mut crate::PyObject { | ||
use crate::{PyList_GetItem, Py_XINCREF}; | ||
|
||
let item = PyList_GetItem(arg1, arg2); | ||
Py_XINCREF(item); | ||
item | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters