From def675442e0a3b1ee380c65568bb0de0302c8f6a Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Fri, 22 Nov 2024 23:20:32 +0000 Subject: [PATCH] fixes --- Cargo.toml | 4 ++-- newsfragments/4678.added.md | 2 +- pyo3-macros-backend/src/pyclass.rs | 2 +- src/exceptions.rs | 3 ++- src/internal_tricks.rs | 12 ++++++++++++ src/pycell/layout.rs | 17 ++++++++++++----- src/types/set.rs | 1 - 7 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d7eb03d55d4..42dad19ed8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyo3" -version = "0.23.1" +version = "0.24.0" description = "Bindings to Python interpreter" authors = ["PyO3 Project and Contributors "] readme = "README.md" @@ -12,7 +12,7 @@ categories = ["api-bindings", "development-tools::ffi"] license = "MIT OR Apache-2.0" exclude = ["/.gitignore", ".cargo/config", "/codecov.yml", "/Makefile", "/pyproject.toml", "/noxfile.py", "/.github", "/tests/test_compile_error.rs", "/tests/ui"] edition = "2021" -rust-version = "1.65" +rust-version = "1.63" [dependencies] cfg-if = "1.0" diff --git a/newsfragments/4678.added.md b/newsfragments/4678.added.md index 8520219a34f..1d8f3293133 100644 --- a/newsfragments/4678.added.md +++ b/newsfragments/4678.added.md @@ -1 +1 @@ -Add support for extending variable/unknown sized base classes (eg `type` to create metaclasses) \ No newline at end of file +Add support for opaque PyObjects allowing extending variable/unknown sized base classes (including `type` to create metaclasses) \ No newline at end of file diff --git a/pyo3-macros-backend/src/pyclass.rs b/pyo3-macros-backend/src/pyclass.rs index 06a39bab4c5..042b6ebb368 100644 --- a/pyo3-macros-backend/src/pyclass.rs +++ b/pyo3-macros-backend/src/pyclass.rs @@ -1198,7 +1198,7 @@ fn impl_complex_enum_variant_match_args( }); parse_quote! { #[allow(non_upper_case_globals)] - const __match_args__: ( #(#args_tp,)* ) = ( + const #ident: ( #(#args_tp,)* ) = ( #(stringify!(#field_names),)* ); } diff --git a/src/exceptions.rs b/src/exceptions.rs index 4f358ced1f7..d3766ad61f4 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -276,7 +276,8 @@ macro_rules! impl_windows_native_exception ( pub struct $name($crate::PyAny); $crate::impl_exception_boilerplate!($name); - $crate::pyobject_native_type!($name, $layout, |_py| unsafe { $crate::ffi::$exc_name as *mut $crate::ffi::PyTypeObject }); + $crate::pyobject_native_type!($name, $layout); + $crate::pyobject_native_type_object_methods!($name, #global_ptr=$crate::ffi::$exc_name); ); ($name:ident, $exc_name:ident, $doc:expr) => ( impl_windows_native_exception!($name, $exc_name, $doc, $crate::ffi::PyBaseExceptionObject); diff --git a/src/internal_tricks.rs b/src/internal_tricks.rs index 97b13aff2a8..d2e67326c11 100644 --- a/src/internal_tricks.rs +++ b/src/internal_tricks.rs @@ -47,3 +47,15 @@ pub(crate) const fn ptr_from_ref(t: &T) -> *const T { pub(crate) fn ptr_from_mut(t: &mut T) -> *mut T { t as *mut T } + +// TODO: use ptr::cast_mut on MSRV 1.65 +#[inline] +pub(crate) fn cast_mut(t: *const T) -> *mut T { + t as *mut T +} + +// TODO: use ptr::cast_const on MSRV 1.65 +#[inline] +pub(crate) fn cast_const(t: *mut T) -> *const T { + t as *const T +} diff --git a/src/pycell/layout.rs b/src/pycell/layout.rs index 6cd51963fc3..1f50e927a3e 100644 --- a/src/pycell/layout.rs +++ b/src/pycell/layout.rs @@ -6,10 +6,13 @@ use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::ptr::addr_of_mut; +use memoffset::offset_of; + use crate::impl_::pyclass::{ PyClassBaseType, PyClassDict, PyClassImpl, PyClassThreadChecker, PyClassWeakRef, PyObjectOffset, }; use crate::internal::get_slot::{TP_DEALLOC, TP_FREE}; +use crate::internal_tricks::{cast_const, cast_mut}; use crate::pycell::borrow_checker::{GetBorrowChecker, PyClassBorrowChecker}; use crate::type_object::PyNativeType; use crate::types::PyType; @@ -175,6 +178,7 @@ impl PyObjectRecursiveOperations .get_slot(TP_DEALLOC) .expect("PyType_Type should have tp_dealloc"); // `PyType_Type::dealloc` calls `Py_GC_UNTRACK` so we have to re-track before deallocating + #[cfg(not(PyPy))] ffi::PyObject_GC_Track(obj.cast()); return tp_dealloc(obj.cast()); } @@ -356,7 +360,7 @@ impl PyObjectLayout { let obj: *mut static_layout::PyStaticClassLayout = obj.cast(); // indicates `ob_base` has type InvalidBaseLayout debug_assert_ne!( - std::mem::offset_of!(static_layout::PyStaticClassLayout, contents), + offset_of!(static_layout::PyStaticClassLayout, contents), 0, "invalid ob_base found" ); @@ -373,8 +377,10 @@ impl PyObjectLayout { strategy: TypeObjectStrategy<'_>, ) -> &'a PyClassObjectContents { unsafe { - &*PyObjectLayout::get_contents_ptr::(ptr_from_ref(obj).cast_mut(), strategy) - .cast_const() + &*cast_const(PyObjectLayout::get_contents_ptr::( + cast_mut(ptr_from_ref(obj)), + strategy, + )) } } @@ -398,7 +404,7 @@ impl PyObjectLayout { obj: &'a ffi::PyObject, strategy: TypeObjectStrategy<'_>, ) -> &'a T { - unsafe { &*PyObjectLayout::get_data_ptr::(ptr_from_ref(obj).cast_mut(), strategy) } + unsafe { &*PyObjectLayout::get_data_ptr::(cast_mut(ptr_from_ref(obj)), strategy) } } /// Obtain a reference to the borrow checker for `obj` @@ -1041,7 +1047,7 @@ mod static_tests { contents: u8, } - assert_eq!(std::mem::offset_of!(InvalidLayout, contents), 0); + assert_eq!(offset_of!(InvalidLayout, contents), 0); } } @@ -1726,6 +1732,7 @@ mod test_utils { /// The size in bytes of a [ffi::PyObject] of the type `T` #[cfg(not(Py_LIMITED_API))] + #[allow(unused)] pub fn get_pyobject_size(py: Python<'_>) -> usize { let typ = ::type_object(py); let raw_typ = typ.as_ptr().cast::(); diff --git a/src/types/set.rs b/src/types/set.rs index 87f6749ab97..51ced5fac5b 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -29,7 +29,6 @@ pyobject_native_type!(PySet, ffi::PySetObject, #checkfunction=ffi::PySet_Check); #[cfg(any(PyPy, GraalPy))] pyobject_native_type_core!(PySet, #checkfunction=ffi::PySet_Check); -#[cfg(not(any(PyPy, GraalPy)))] pyobject_native_type_object_methods!(PySet, #global=ffi::PySet_Type); impl PySet {