PyPy: the PyList_GET/SET macros are defined as functions, the PyTuple_ ones do not exist

This commit is contained in:
Georg Brandl 2021-07-04 11:03:45 +02:00
parent 9cdb6a0d63
commit f7235482eb
5 changed files with 27 additions and 9 deletions

View File

@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Implement `IntoPy<PyObject>` for `&PathBuf` and `&OsString`. [#1721](https://github.com/PyO3/pyo3/pull/1712)
### Fixed
- Fix crashes on PyPy due to incorrect definitions of `PyList_SET_ITEM`. [#1713](https://github.com/PyO3/pyo3/pull/1713)
## [0.14.0] - 2021-07-03
### Packaging

View File

@ -15,17 +15,20 @@ pub struct PyListObject {
/// Macro, trading safety for speed
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
*(*(op as *mut PyListObject)).ob_item.offset(i as isize)
}
/// Macro, *only* to be used to fill in brand new lists
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) {
*(*(op as *mut PyListObject)).ob_item.offset(i as isize) = v;
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
Py_SIZE(op)
}

View File

@ -52,4 +52,15 @@ extern "C" {
pub fn PyList_Reverse(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_AsTuple")]
pub fn PyList_AsTuple(arg1: *mut PyObject) -> *mut PyObject;
// CPython macros exported as functions on PyPy
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyList_GET_ITEM")]
pub fn PyList_GET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject;
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyList_GET_SIZE")]
pub fn PyList_GET_SIZE(arg1: *mut PyObject) -> Py_ssize_t;
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyList_SET_ITEM")]
pub fn PyList_SET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject);
}

View File

@ -47,7 +47,7 @@ extern "C" {
/// Macro, trading safety for speed
#[inline]
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
*(*(op as *mut PyTupleObject))
.ob_item
@ -56,14 +56,14 @@ pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObjec
}
#[inline]
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub unsafe fn PyTuple_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
Py_SIZE(op)
}
/// Macro, *only* to be used to fill in brand new tuples
#[inline]
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub unsafe fn PyTuple_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) {
*(*(op as *mut PyTupleObject))
.ob_item

View File

@ -26,9 +26,9 @@ impl PyTuple {
unsafe {
let ptr = ffi::PyTuple_New(len as Py_ssize_t);
for (i, e) in elements_iter.enumerate() {
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
ffi::PyTuple_SET_ITEM(ptr, i as Py_ssize_t, e.to_object(py).into_ptr());
#[cfg(Py_LIMITED_API)]
#[cfg(any(Py_LIMITED_API, PyPy))]
ffi::PyTuple_SetItem(ptr, i as Py_ssize_t, e.to_object(py).into_ptr());
}
py.from_owned_ptr(ptr)
@ -43,9 +43,9 @@ impl PyTuple {
/// Gets the length of the tuple.
pub fn len(&self) -> usize {
unsafe {
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
let size = ffi::PyTuple_GET_SIZE(self.as_ptr());
#[cfg(Py_LIMITED_API)]
#[cfg(any(Py_LIMITED_API, PyPy))]
let size = ffi::PyTuple_Size(self.as_ptr());
// non-negative Py_ssize_t should always fit into Rust uint
size as usize
@ -79,9 +79,9 @@ impl PyTuple {
pub fn get_item(&self, index: usize) -> &PyAny {
assert!(index < self.len());
unsafe {
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
let item = ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t);
#[cfg(Py_LIMITED_API)]
#[cfg(any(Py_LIMITED_API, PyPy))]
let item = ffi::PyTuple_GetItem(self.as_ptr(), index as Py_ssize_t);
self.py().from_borrowed_ptr(item)