-
Notifications
You must be signed in to change notification settings - Fork 770
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update dict.get_item binding to use PyDict_GetItemRef (#4355)
* Update dict.get_item binding to use PyDict_GetItemRef Refs #4265 * test: add test for dict.get_item error path * test: add test for dict.get_item error path * test: add test for dict.get_item error path * fix: fix logic error in dict.get_item bindings * update: apply david's review suggestions for dict.get_item bindings * update: create ffi::compat to store compatibility shims * update: move PyDict_GetItemRef bindings to spot in order from dictobject.h * build: fix build warning with --no-default-features * doc: expand release note fragments * fix: fix clippy warnings * respond to review comments * Apply suggestion from @mejrs * refactor so cfg is applied to functions * properly set cfgs * fix clippy lints * Apply @davidhewitt's suggestion * deal with upstream deprecation of new_bound
- Loading branch information
1 parent
cd70cec
commit 6710dcd
Showing
6 changed files
with
106 additions
and
5 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,10 @@ | ||
* Added an `ffi::compat` namespace to store compatibility shims for C API | ||
functions added in recent versions of Python. | ||
|
||
* Added bindings for `PyDict_GetItemRef` on Python 3.13 and newer. Also added | ||
`ffi::compat::PyDict_GetItemRef` which re-exports the FFI binding on Python | ||
3.13 or newer and defines a compatibility version on older versions of | ||
Python. This function is inherently safer to use than `PyDict_GetItem` and has | ||
an API that is easier to use than `PyDict_GetItemWithError`. It returns a | ||
strong reference to value, as opposed to the two older functions which return | ||
a possibly unsafe borrowed reference. |
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,2 @@ | ||
Avoid creating temporary borrowed reference in dict.get_item bindings. Borrowed | ||
references like this are unsafe in the free-threading build. |
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,44 @@ | ||
//! 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 | ||
|
||
#[cfg(not(Py_3_13))] | ||
use crate::object::PyObject; | ||
#[cfg(not(Py_3_13))] | ||
use std::os::raw::c_int; | ||
|
||
#[cfg_attr(docsrs, doc(cfg(all)))] | ||
#[cfg(Py_3_13)] | ||
pub use crate::dictobject::PyDict_GetItemRef; | ||
|
||
#[cfg_attr(docsrs, doc(cfg(all)))] | ||
#[cfg(not(Py_3_13))] | ||
pub unsafe fn PyDict_GetItemRef( | ||
dp: *mut PyObject, | ||
key: *mut PyObject, | ||
result: *mut *mut PyObject, | ||
) -> c_int { | ||
{ | ||
use crate::dictobject::PyDict_GetItemWithError; | ||
use crate::object::_Py_NewRef; | ||
use crate::pyerrors::PyErr_Occurred; | ||
|
||
let item: *mut PyObject = 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 | ||
} | ||
} |
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
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