Skip to content

Commit

Permalink
Fix struct layouts on GraalPy (PyO3#4802)
Browse files Browse the repository at this point in the history
* Fix struct layouts on GraalPy

* Add changelog item
  • Loading branch information
msimacek authored and clin1234 committed Dec 24, 2024
1 parent 44881c2 commit 2180b3b
Show file tree
Hide file tree
Showing 16 changed files with 46 additions and 56 deletions.
1 change: 1 addition & 0 deletions newsfragments/4802.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed missing struct fields on GraalPy when subclassing builtin classes
1 change: 0 additions & 1 deletion pyo3-ffi/src/abstract_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_
extern "C" {
#[cfg(all(
not(PyPy),
not(GraalPy),
any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10
))]
#[cfg_attr(PyPy, link_name = "PyPyObject_CallNoArgs")]
Expand Down
4 changes: 3 additions & 1 deletion pyo3-ffi/src/cpython/abstract_.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::{PyObject, Py_ssize_t};
use std::os::raw::{c_char, c_int};
#[cfg(not(all(Py_3_11, GraalPy)))]
use std::os::raw::c_char;
use std::os::raw::c_int;

#[cfg(not(Py_3_11))]
use crate::Py_buffer;
Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/cpython/complexobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ pub struct Py_complex {
#[repr(C)]
pub struct PyComplexObject {
pub ob_base: PyObject,
#[cfg(not(GraalPy))]
pub cval: Py_complex,
}

Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/cpython/floatobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::os::raw::c_double;
#[repr(C)]
pub struct PyFloatObject {
pub ob_base: PyObject,
#[cfg(not(GraalPy))]
pub ob_fval: c_double,
}

Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/genobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::object::*;
use crate::PyFrameObject;
#[cfg(not(any(PyPy, GraalPy)))]
use crate::_PyErr_StackItem;
#[cfg(Py_3_11)]
#[cfg(all(Py_3_11, not(GraalPy)))]
use std::os::raw::c_char;
use std::os::raw::c_int;
use std::ptr::addr_of_mut;
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/cpython/listobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ use crate::object::*;
#[cfg(not(PyPy))]
use crate::pyport::Py_ssize_t;

#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
#[repr(C)]
pub struct PyListObject {
pub ob_base: PyVarObject,
pub ob_item: *mut *mut PyObject,
pub allocated: Py_ssize_t,
}

#[cfg(any(PyPy, GraalPy))]
#[cfg(PyPy)]
pub struct PyListObject {
pub ob_base: PyObject,
}
Expand Down
2 changes: 0 additions & 2 deletions pyo3-ffi/src/cpython/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,6 @@ pub type printfunc =
#[derive(Debug)]
pub struct PyTypeObject {
pub ob_base: object::PyVarObject,
#[cfg(GraalPy)]
pub ob_size: Py_ssize_t,
pub tp_name: *const c_char,
pub tp_basicsize: Py_ssize_t,
pub tp_itemsize: Py_ssize_t,
Expand Down
1 change: 1 addition & 0 deletions pyo3-ffi/src/cpython/objimpl.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(not(all(Py_3_11, GraalPy)))]
use libc::size_t;
use std::os::raw::c_int;

Expand Down
28 changes: 14 additions & 14 deletions pyo3-ffi/src/cpython/pyerrors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ use crate::Py_ssize_t;
#[derive(Debug)]
pub struct PyBaseExceptionObject {
pub ob_base: PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub dict: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub args: *mut PyObject,
#[cfg(all(Py_3_11, not(any(PyPy, GraalPy))))]
#[cfg(all(Py_3_11, not(PyPy)))]
pub notes: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub traceback: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub context: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub cause: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub suppress_context: char,
}

Expand Down Expand Up @@ -134,19 +134,19 @@ pub struct PyOSErrorObject {
#[derive(Debug)]
pub struct PyStopIterationObject {
pub ob_base: PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub dict: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub args: *mut PyObject,
#[cfg(all(Py_3_11, not(any(PyPy, GraalPy))))]
#[cfg(all(Py_3_11, not(PyPy)))]
pub notes: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub traceback: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub context: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub cause: *mut PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub suppress_context: char,

pub value: *mut PyObject,
Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/cpython/tupleobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::pyport::Py_ssize_t;
#[repr(C)]
pub struct PyTupleObject {
pub ob_base: PyVarObject,
#[cfg(not(GraalPy))]
pub ob_item: [*mut PyObject; 1],
}

Expand Down
13 changes: 4 additions & 9 deletions pyo3-ffi/src/cpython/unicodeobject.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
use crate::Py_hash_t;
use crate::{PyObject, Py_UCS1, Py_UCS2, Py_UCS4, Py_ssize_t};
use libc::wchar_t;
Expand Down Expand Up @@ -250,9 +250,8 @@ impl From<PyASCIIObjectState> for u32 {
#[repr(C)]
pub struct PyASCIIObject {
pub ob_base: PyObject,
#[cfg(not(GraalPy))]
pub length: Py_ssize_t,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub hash: Py_hash_t,
/// A bit field with various properties.
///
Expand All @@ -265,9 +264,8 @@ pub struct PyASCIIObject {
/// unsigned int ascii:1;
/// unsigned int ready:1;
/// unsigned int :24;
#[cfg(not(GraalPy))]
pub state: u32,
#[cfg(not(any(Py_3_12, GraalPy)))]
#[cfg(not(Py_3_12))]
pub wstr: *mut wchar_t,
}

Expand Down Expand Up @@ -379,11 +377,9 @@ impl PyASCIIObject {
#[repr(C)]
pub struct PyCompactUnicodeObject {
pub _base: PyASCIIObject,
#[cfg(not(GraalPy))]
pub utf8_length: Py_ssize_t,
#[cfg(not(GraalPy))]
pub utf8: *mut c_char,
#[cfg(not(any(Py_3_12, GraalPy)))]
#[cfg(not(Py_3_12))]
pub wstr_length: Py_ssize_t,
}

Expand All @@ -398,7 +394,6 @@ pub union PyUnicodeObjectData {
#[repr(C)]
pub struct PyUnicodeObject {
pub _base: PyCompactUnicodeObject,
#[cfg(not(GraalPy))]
pub data: PyUnicodeObjectData,
}

Expand Down
30 changes: 11 additions & 19 deletions pyo3-ffi/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ use crate::PyCapsule_Import;
#[cfg(GraalPy)]
use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef};
use crate::{PyObject, PyObject_TypeCheck, PyTypeObject, Py_TYPE};
#[cfg(not(GraalPy))]
use std::os::raw::c_char;
use std::os::raw::c_int;
use std::ptr;
use std::sync::Once;
use std::{cell::UnsafeCell, ffi::CStr};
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
use {crate::Py_hash_t, std::os::raw::c_uchar};
// Type struct wrappers
const _PyDateTime_DATE_DATASIZE: usize = 4;
Expand All @@ -27,13 +26,10 @@ const _PyDateTime_DATETIME_DATASIZE: usize = 10;
/// Structure representing a `datetime.timedelta`.
pub struct PyDateTime_Delta {
pub ob_base: PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
#[cfg(not(GraalPy))]
pub days: c_int,
#[cfg(not(GraalPy))]
pub seconds: c_int,
#[cfg(not(GraalPy))]
pub microseconds: c_int,
}

Expand All @@ -56,19 +52,17 @@ pub struct _PyDateTime_BaseTime {
/// Structure representing a `datetime.time`.
pub struct PyDateTime_Time {
pub ob_base: PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
#[cfg(not(GraalPy))]
pub hastzinfo: c_char,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub fold: c_uchar,
/// # Safety
///
/// Care should be taken when reading this field. If the time does not have a
/// tzinfo then CPython may allocate as a `_PyDateTime_BaseTime` without this field.
#[cfg(not(GraalPy))]
pub tzinfo: *mut PyObject,
}

Expand All @@ -77,11 +71,11 @@ pub struct PyDateTime_Time {
/// Structure representing a `datetime.date`
pub struct PyDateTime_Date {
pub ob_base: PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub hastzinfo: c_char,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_DATE_DATASIZE],
}

Expand All @@ -101,19 +95,17 @@ pub struct _PyDateTime_BaseDateTime {
/// Structure representing a `datetime.datetime`.
pub struct PyDateTime_DateTime {
pub ob_base: PyObject,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
#[cfg(not(GraalPy))]
pub hastzinfo: c_char,
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE],
#[cfg(not(any(PyPy, GraalPy)))]
#[cfg(not(PyPy))]
pub fold: c_uchar,
/// # Safety
///
/// Care should be taken when reading this field. If the time does not have a
/// tzinfo then CPython may allocate as a `_PyDateTime_BaseDateTime` without this field.
#[cfg(not(GraalPy))]
pub tzinfo: *mut PyObject,
}

Expand Down
3 changes: 3 additions & 0 deletions pyo3-ffi/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ pub struct PyVarObject {
pub ob_base: PyObject,
#[cfg(not(GraalPy))]
pub ob_size: Py_ssize_t,
// On GraalPy the field is physically there, but not always populated. We hide it to prevent accidental misuse
#[cfg(GraalPy)]
pub _ob_size_graalpy: Py_ssize_t,
}

// skipped private _PyVarObject_CAST
Expand Down
8 changes: 5 additions & 3 deletions pyo3-ffi/src/pyhash.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
use crate::pyport::{Py_hash_t, Py_ssize_t};
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
use std::os::raw::{c_char, c_void};
use std::os::raw::c_char;
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
use std::os::raw::c_void;

use std::os::raw::{c_int, c_ulong};

Expand All @@ -10,7 +12,7 @@ extern "C" {
// skipped non-limited _Py_HashPointer
// skipped non-limited _Py_HashPointerRaw

#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub fn _Py_HashBytes(src: *const c_void, len: Py_ssize_t) -> Py_hash_t;
}

Expand Down
2 changes: 1 addition & 1 deletion src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use self::float::{PyFloat, PyFloatMethods};
pub use self::frame::PyFrame;
pub use self::frozenset::{PyFrozenSet, PyFrozenSetBuilder, PyFrozenSetMethods};
pub use self::function::PyCFunction;
#[cfg(all(not(Py_LIMITED_API), not(all(PyPy, not(Py_3_8))), not(GraalPy)))]
#[cfg(all(not(Py_LIMITED_API), not(all(PyPy, not(Py_3_8)))))]
pub use self::function::PyFunction;
pub use self::iterator::PyIterator;
pub use self::list::{PyList, PyListMethods};
Expand Down

0 comments on commit 2180b3b

Please sign in to comment.