opt: remove some generic code bloat

This commit is contained in:
David Hewitt 2022-06-22 20:40:00 +01:00
parent cdb3b6ff32
commit 3d9b78062e
5 changed files with 56 additions and 63 deletions

View File

@ -552,15 +552,14 @@ impl<'a> FnSpec<'a> {
_kwargs: *mut _pyo3::ffi::PyObject) -> *mut _pyo3::ffi::PyObject
{
#deprecations
use _pyo3::callback::IntoPyCallbackOutput;
use _pyo3::{callback::IntoPyCallbackOutput, pyclass_init::PyObjectInit};
let gil = _pyo3::GILPool::new();
let #py = gil.python();
_pyo3::callback::panic_result_into_callback_output(#py, ::std::panic::catch_unwind(move || -> _pyo3::PyResult<_> {
#arg_convert
let result = #rust_call;
let initializer: _pyo3::PyClassInitializer::<#cls> = result.convert(#py)?;
let cell = initializer.create_cell_from_subtype(#py, subtype)?;
::std::result::Result::Ok(cell as *mut _pyo3::ffi::PyObject)
initializer.into_new_object(#py, subtype)
}))
}
}

View File

@ -46,7 +46,7 @@ where
T: FromPyObject<'py>,
{
match obj.extract() {
ok @ Ok(_) => ok,
Ok(value) => Ok(value),
Err(err) => Err(failed_to_extract_struct_field(
obj.py(),
err,
@ -63,7 +63,7 @@ pub fn extract_struct_field_with<'py, T>(
field_name: &str,
) -> PyResult<T> {
match extractor(obj) {
ok @ Ok(_) => ok,
Ok(value) => Ok(value),
Err(err) => Err(failed_to_extract_struct_field(
obj.py(),
err,
@ -97,7 +97,7 @@ where
T: FromPyObject<'py>,
{
match obj.extract() {
ok @ Ok(_) => ok,
Ok(value) => Ok(value),
Err(err) => Err(failed_to_extract_tuple_struct_field(
obj.py(),
err,
@ -114,7 +114,7 @@ pub fn extract_tuple_struct_field_with<'py, T>(
index: usize,
) -> PyResult<T> {
match extractor(obj) {
ok @ Ok(_) => ok,
Ok(value) => Ok(value),
Err(err) => Err(failed_to_extract_tuple_struct_field(
obj.py(),
err,

View File

@ -28,8 +28,8 @@ pub fn weaklist_offset<T: PyClass>() -> ffi::Py_ssize_t {
/// Represents the `__dict__` field for `#[pyclass]`.
pub trait PyClassDict {
/// Initializes a [PyObject](crate::ffi::PyObject) `__dict__` reference.
fn new() -> Self;
/// Initial form of a [PyObject](crate::ffi::PyObject) `__dict__` reference.
const INIT: Self;
/// Empties the dictionary of its key-value pairs.
#[inline]
fn clear_dict(&mut self, _py: Python<'_>) {}
@ -39,7 +39,7 @@ pub trait PyClassDict {
/// Represents the `__weakref__` field for `#[pyclass]`.
pub trait PyClassWeakRef {
/// Initializes a `weakref` instance.
fn new() -> Self;
const INIT: Self;
/// Clears the weak references to the given object.
///
/// # Safety
@ -55,18 +55,12 @@ pub struct PyClassDummySlot;
impl PyClassDict for PyClassDummySlot {
private_impl! {}
#[inline]
fn new() -> Self {
PyClassDummySlot
}
const INIT: Self = PyClassDummySlot;
}
impl PyClassWeakRef for PyClassDummySlot {
private_impl! {}
#[inline]
fn new() -> Self {
PyClassDummySlot
}
const INIT: Self = PyClassDummySlot;
}
/// Actual dict field, which holds the pointer to `__dict__`.
@ -77,10 +71,7 @@ pub struct PyClassDictSlot(*mut ffi::PyObject);
impl PyClassDict for PyClassDictSlot {
private_impl! {}
#[inline]
fn new() -> Self {
Self(std::ptr::null_mut())
}
const INIT: Self = Self(std::ptr::null_mut());
#[inline]
fn clear_dict(&mut self, _py: Python<'_>) {
if !self.0.is_null() {
@ -97,10 +88,7 @@ pub struct PyClassWeakRefSlot(*mut ffi::PyObject);
impl PyClassWeakRef for PyClassWeakRefSlot {
private_impl! {}
#[inline]
fn new() -> Self {
Self(std::ptr::null_mut())
}
const INIT: Self = Self(std::ptr::null_mut());
#[inline]
unsafe fn clear_weakrefs(&mut self, obj: *mut ffi::PyObject, _py: Python<'_>) {
if !self.0.is_null() {

View File

@ -225,6 +225,7 @@ pub struct EmptySlot(());
pub struct BorrowChecker(Cell<BorrowFlag>);
pub trait PyClassBorrowChecker {
/// Initial value for self
fn new() -> Self;
/// Increments immutable borrow count, if possible
@ -243,7 +244,7 @@ pub trait PyClassBorrowChecker {
impl PyClassBorrowChecker for EmptySlot {
#[inline]
fn new() -> Self {
Self(())
EmptySlot(())
}
#[inline]

View File

@ -37,43 +37,49 @@ impl<T: PyTypeInfo> PyObjectInit<T> for PyNativeTypeInitializer<T> {
py: Python<'_>,
subtype: *mut PyTypeObject,
) -> PyResult<*mut ffi::PyObject> {
let type_object = T::type_object_raw(py);
unsafe fn inner(
py: Python<'_>,
type_object: *mut PyTypeObject,
subtype: *mut PyTypeObject,
) -> PyResult<*mut ffi::PyObject> {
// HACK (due to FIXME below): PyBaseObject_Type's tp_new isn't happy with NULL arguments
#[cfg(addr_of)]
let is_base_object = type_object == std::ptr::addr_of_mut!(ffi::PyBaseObject_Type);
#[cfg(not(addr_of))]
let is_base_object = type_object == &mut ffi::PyBaseObject_Type as _;
if is_base_object {
let alloc = get_tp_alloc(subtype).unwrap_or(ffi::PyType_GenericAlloc);
let obj = alloc(subtype, 0);
return if obj.is_null() {
Err(PyErr::fetch(py))
} else {
Ok(obj)
};
}
// HACK (due to FIXME below): PyBaseObject_Type's tp_new isn't happy with NULL arguments
#[cfg(addr_of)]
let is_base_object = type_object == std::ptr::addr_of_mut!(ffi::PyBaseObject_Type);
#[cfg(not(addr_of))]
let is_base_object = type_object == &mut ffi::PyBaseObject_Type as _;
if is_base_object {
let alloc = get_tp_alloc(subtype).unwrap_or(ffi::PyType_GenericAlloc);
let obj = alloc(subtype, 0);
return if obj.is_null() {
Err(PyErr::fetch(py))
} else {
Ok(obj)
};
}
#[cfg(Py_LIMITED_API)]
unreachable!("subclassing native types is not possible with the `abi3` feature");
#[cfg(Py_LIMITED_API)]
unreachable!("subclassing native types is not possible with the `abi3` feature");
#[cfg(not(Py_LIMITED_API))]
{
match (*type_object).tp_new {
// FIXME: Call __new__ with actual arguments
Some(newfunc) => {
let obj = newfunc(subtype, std::ptr::null_mut(), std::ptr::null_mut());
if obj.is_null() {
Err(PyErr::fetch(py))
} else {
Ok(obj)
#[cfg(not(Py_LIMITED_API))]
{
match (*type_object).tp_new {
// FIXME: Call __new__ with actual arguments
Some(newfunc) => {
let obj = newfunc(subtype, std::ptr::null_mut(), std::ptr::null_mut());
if obj.is_null() {
Err(PyErr::fetch(py))
} else {
Ok(obj)
}
}
None => Err(crate::exceptions::PyTypeError::new_err(
"base type without tp_new",
)),
}
None => Err(crate::exceptions::PyTypeError::new_err(
"base type without tp_new",
)),
}
}
let type_object = T::type_object_raw(py);
inner(py, type_object, subtype)
}
private_impl! {}
@ -236,18 +242,17 @@ impl<T: PyClass> PyObjectInit<T> for PyClassInitializer<T> {
contents: MaybeUninit<PyCellContents<T>>,
}
let Self { init, super_init } = self;
let obj = super_init.into_new_object(py, subtype)?;
let obj = self.super_init.into_new_object(py, subtype)?;
let cell: *mut PartiallyInitializedPyCell<T> = obj as _;
std::ptr::write(
(*cell).contents.as_mut_ptr(),
PyCellContents {
value: ManuallyDrop::new(UnsafeCell::new(init)),
value: ManuallyDrop::new(UnsafeCell::new(self.init)),
borrow_checker: <T::PyClassMutability as PyClassMutability>::Storage::new(),
thread_checker: T::ThreadChecker::new(),
dict: T::Dict::new(),
weakref: T::WeakRef::new(),
dict: T::Dict::INIT,
weakref: T::WeakRef::INIT,
},
);
Ok(obj)