Revisions from PR#751
This commit is contained in:
parent
7531b9fb07
commit
04f30c5971
|
@ -44,22 +44,9 @@ unsafe impl pyo3::PyTypeInfo for MyClass {
|
|||
|
||||
#[inline]
|
||||
fn type_object() -> std::ptr::NonNull<pyo3::ffi::PyTypeObject> {
|
||||
use std::ptr::NonNull;
|
||||
use pyo3::type_object::LazyTypeObject;
|
||||
static TYPE_OBJECT: LazyTypeObject = LazyTypeObject::new();
|
||||
TYPE_OBJECT.get_or_init(|| {
|
||||
// automatically initialize the class on-demand
|
||||
let gil = pyo3::Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let boxed = pyo3::pyclass::create_type_object::<Self>(py, Self::MODULE)?;
|
||||
Ok(unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) })
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
e.print(py);
|
||||
panic!("An error occurred while initializing class {}", Self::NAME)
|
||||
})
|
||||
TYPE_OBJECT.get_pyclass_type::<Self>()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -383,22 +383,9 @@ fn impl_class(
|
|||
|
||||
#[inline]
|
||||
fn type_object() -> std::ptr::NonNull<pyo3::ffi::PyTypeObject> {
|
||||
use std::ptr::NonNull;
|
||||
use pyo3::type_object::LazyTypeObject;
|
||||
static TYPE_OBJECT: LazyTypeObject = LazyTypeObject::new();
|
||||
TYPE_OBJECT.get_or_init(|| {
|
||||
// automatically initialize the class on-demand
|
||||
let gil = pyo3::Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let boxed = pyo3::pyclass::create_type_object::<Self>(py, Self::MODULE)?;
|
||||
Ok(unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) })
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
e.print(py);
|
||||
panic!("An error occurred while initializing class {}", Self::NAME)
|
||||
})
|
||||
TYPE_OBJECT.get_pyclass_type::<Self>()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -253,13 +253,15 @@ where
|
|||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
pub fn create_type_object<T>(
|
||||
pub(crate) fn create_type_object<T>(
|
||||
py: Python,
|
||||
module_name: Option<&str>,
|
||||
) -> PyResult<Box<ffi::PyTypeObject>>
|
||||
where
|
||||
T: PyClass,
|
||||
{
|
||||
// Box (or some other heap allocation) is needed because PyType_Ready expects the type object
|
||||
// to have a permanent memory address.
|
||||
let mut boxed = Box::new(ffi::PyTypeObject_INIT);
|
||||
let mut type_object = boxed.as_mut();
|
||||
let base_type_object = <T::BaseType as PyTypeInfo>::type_object().as_ptr();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
use crate::err::PyResult;
|
||||
use crate::instance::Py;
|
||||
use crate::pyclass::{create_type_object, PyClass};
|
||||
use crate::pyclass_init::PyObjectInit;
|
||||
use crate::types::{PyAny, PyType};
|
||||
use crate::{ffi, AsPyPointer, Python};
|
||||
|
@ -127,7 +128,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Type used to store type objects
|
||||
/// Type used to store static type objects
|
||||
#[doc(hidden)]
|
||||
pub struct LazyTypeObject {
|
||||
cell: OnceCell<NonNull<ffi::PyTypeObject>>,
|
||||
}
|
||||
|
@ -145,6 +147,22 @@ impl LazyTypeObject {
|
|||
{
|
||||
Ok(*self.cell.get_or_try_init(constructor)?)
|
||||
}
|
||||
|
||||
pub fn get_pyclass_type<T: PyClass>(&self) -> NonNull<ffi::PyTypeObject> {
|
||||
self.get_or_init(|| {
|
||||
// automatically initialize the class on-demand
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let boxed = create_type_object::<T>(py, T::MODULE)?;
|
||||
Ok(unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) })
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
e.print(py);
|
||||
panic!("An error occurred while initializing class {}", T::NAME)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// This is necessary for making static `LazyTypeObject`s
|
||||
|
|
Loading…
Reference in New Issue