Skip to content

Commit 72d9312

Browse files
authored
fix FFI definition of PyDictObject on PyPy (#5653)
* fix FFI definition of `PyDictObject` on PyPy * newsfragments * don't add additional definitions on PyPy * cfg gate unused imports * disable dict inheritance test on graalpy * another GraalPy fixup
1 parent 1a3945c commit 72d9312

7 files changed

Lines changed: 27 additions & 4 deletions

File tree

newsfragments/5653.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Disable subclassing `PyDict` on GraalPy (unsupported for now).

newsfragments/5653.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix FFI definition of `PyDictObject` on PyPy.

pyo3-ffi/src/cpython/dictobject.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
use crate::object::*;
2+
#[cfg(not(PyPy))]
23
use crate::pyport::Py_ssize_t;
4+
#[cfg(not(PyPy))]
35
use std::ffi::c_int;
46

7+
#[cfg(not(PyPy))]
58
opaque_struct!(pub PyDictKeysObject);
69

710
#[cfg(Py_3_11)]
11+
#[cfg(not(PyPy))]
812
opaque_struct!(pub PyDictValues);
913

10-
#[cfg(not(GraalPy))]
14+
#[cfg(not(any(GraalPy, PyPy)))]
1115
#[repr(C)]
1216
#[derive(Debug)]
1317
pub struct PyDictObject {
@@ -28,11 +32,20 @@ pub struct PyDictObject {
2832
pub ma_values: *mut PyDictValues,
2933
}
3034

35+
#[cfg(PyPy)]
36+
#[repr(C)]
37+
#[derive(Debug)]
38+
pub struct PyDictObject {
39+
pub ob_base: PyObject,
40+
_tmpkeys: *mut PyObject,
41+
}
42+
3143
extern "C" {
3244
// skipped _PyDict_GetItem_KnownHash
3345
// skipped _PyDict_GetItemIdWithError
3446
// skipped _PyDict_GetItemStringWithError
3547
// skipped PyDict_SetDefault
48+
#[cfg(not(PyPy))]
3649
pub fn _PyDict_SetItem_KnownHash(
3750
mp: *mut PyObject,
3851
key: *mut PyObject,
@@ -42,6 +55,7 @@ extern "C" {
4255
// skipped _PyDict_DelItem_KnownHash
4356
// skipped _PyDict_DelItemIf
4457
// skipped _PyDict_NewKeysForClass
58+
#[cfg(not(PyPy))]
4559
pub fn _PyDict_Next(
4660
mp: *mut PyObject,
4761
pos: *mut Py_ssize_t,
@@ -51,6 +65,7 @@ extern "C" {
5165
) -> c_int;
5266
// skipped PyDict_GET_SIZE
5367
// skipped _PyDict_ContainsId
68+
#[cfg(not(PyPy))]
5469
pub fn _PyDict_NewPresized(minused: Py_ssize_t) -> *mut PyObject;
5570
// skipped _PyDict_MaybeUntrack
5671
// skipped _PyDict_HasOnlyStringKeys
@@ -72,12 +87,14 @@ extern "C" {
7287
// skipped _PyDictView_Intersect
7388

7489
#[cfg(Py_3_10)]
90+
#[cfg(not(PyPy))]
7591
pub fn _PyDict_Contains_KnownHash(
7692
op: *mut PyObject,
7793
key: *mut PyObject,
7894
hash: crate::Py_hash_t,
7995
) -> c_int;
8096

8197
#[cfg(not(Py_3_10))]
98+
#[cfg(not(PyPy))]
8299
pub fn _PyDict_Contains(mp: *mut PyObject, key: *mut PyObject, hash: Py_ssize_t) -> c_int;
83100
}

pyo3-ffi/src/cpython/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ pub(crate) mod complexobject;
99
#[cfg(Py_3_13)]
1010
pub(crate) mod critical_section;
1111
pub(crate) mod descrobject;
12-
#[cfg(not(PyPy))]
1312
pub(crate) mod dictobject;
1413
// skipped fileobject.h
1514
// skipped fileutils.h
@@ -53,7 +52,6 @@ pub use self::complexobject::*;
5352
#[cfg(Py_3_13)]
5453
pub use self::critical_section::*;
5554
pub use self::descrobject::*;
56-
#[cfg(not(PyPy))]
5755
pub use self::dictobject::*;
5856
pub use self::floatobject::*;
5957
pub use self::frameobject::*;

pyo3-ffi/src/dictobject.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,6 @@ extern "C" {
116116
pub static mut PyDictRevIterItem_Type: PyTypeObject;
117117
}
118118

119-
#[cfg(any(PyPy, GraalPy, Py_LIMITED_API))]
119+
#[cfg(any(GraalPy, Py_LIMITED_API))]
120120
// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985)
121121
opaque_struct!(pub PyDictObject);

src/types/dict.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::{ffi, BoundObject, IntoPyObject, IntoPyObjectExt, Python};
1616
#[repr(transparent)]
1717
pub struct PyDict(PyAny);
1818

19+
#[cfg(not(GraalPy))]
1920
pyobject_subclassable_native_type!(PyDict, crate::ffi::PyDictObject);
2021

2122
pyobject_native_type!(

tests/test_inheritance.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ except Exception as e:
177177
mod inheriting_native_type {
178178
use super::*;
179179
use pyo3::exceptions::PyException;
180+
#[cfg(not(GraalPy))]
180181
use pyo3::types::PyDict;
181182

182183
#[cfg(not(any(PyPy, GraalPy)))]
@@ -209,13 +210,15 @@ mod inheriting_native_type {
209210
});
210211
}
211212

213+
#[cfg(not(GraalPy))]
212214
#[pyclass(extends=PyDict)]
213215
#[derive(Debug)]
214216
struct DictWithName {
215217
#[pyo3(get, name = "name")]
216218
_name: &'static str,
217219
}
218220

221+
#[cfg(not(GraalPy))]
219222
#[pymethods]
220223
impl DictWithName {
221224
#[new]
@@ -224,6 +227,7 @@ mod inheriting_native_type {
224227
}
225228
}
226229

230+
#[cfg(not(GraalPy))]
227231
#[test]
228232
fn inherit_dict() {
229233
Python::attach(|py| {
@@ -236,6 +240,7 @@ mod inheriting_native_type {
236240
});
237241
}
238242

243+
#[cfg(not(GraalPy))]
239244
#[test]
240245
fn inherit_dict_drop() {
241246
Python::attach(|py| {

0 commit comments

Comments
 (0)