part1
This commit is contained in:
parent
a44e2f8eea
commit
5648815fff
|
@ -814,115 +814,7 @@ The `#[pyclass]` macro expands to roughly the code seen below. The `PyClassImplC
|
|||
|
||||
```rust
|
||||
# #[cfg(not(feature = "multiple-pymethods"))] {
|
||||
# use pyo3::prelude::*;
|
||||
// Note: the implementation differs slightly with the `multiple-pymethods` feature enabled.
|
||||
struct MyClass {
|
||||
# #[allow(dead_code)]
|
||||
num: i32,
|
||||
}
|
||||
unsafe impl ::pyo3::type_object::PyTypeInfo for MyClass {
|
||||
type AsRefTarget = ::pyo3::PyCell<Self>;
|
||||
const NAME: &'static str = "MyClass";
|
||||
const MODULE: ::std::option::Option<&'static str> = ::std::option::Option::None;
|
||||
#[inline]
|
||||
fn type_object_raw(py: ::pyo3::Python<'_>) -> *mut ::pyo3::ffi::PyTypeObject {
|
||||
use ::pyo3::type_object::LazyStaticType;
|
||||
static TYPE_OBJECT: LazyStaticType = LazyStaticType::new();
|
||||
TYPE_OBJECT.get_or_init::<Self>(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::pyo3::PyClass for MyClass {
|
||||
type Dict = ::pyo3::pyclass_slots::PyClassDummySlot;
|
||||
type WeakRef = ::pyo3::pyclass_slots::PyClassDummySlot;
|
||||
type BaseNativeType = ::pyo3::PyAny;
|
||||
}
|
||||
|
||||
unsafe impl ::pyo3::pyclass::MutablePyClass for MyClass {}
|
||||
|
||||
unsafe impl ::pyo3::class::impl_::BorrowImpl for MyClass {}
|
||||
|
||||
impl<'a> ::pyo3::derive_utils::ExtractExt<'a> for &'a mut MyClass {
|
||||
type Target = ::pyo3::PyRefMut<'a, MyClass>;
|
||||
}
|
||||
|
||||
impl<'a> ::pyo3::derive_utils::ExtractExt<'a> for &'a MyClass {
|
||||
type Target = ::pyo3::PyRef<'a, MyClass>;
|
||||
}
|
||||
|
||||
impl ::pyo3::IntoPy<::pyo3::PyObject> for MyClass {
|
||||
fn into_py(self, py: ::pyo3::Python) -> ::pyo3::PyObject {
|
||||
::pyo3::IntoPy::into_py(::pyo3::Py::new(py, self).unwrap(), py)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::pyo3::class::impl_::PyClassImpl for MyClass {
|
||||
const DOC: &'static str = "\u{0}";
|
||||
const IS_GC: bool = false;
|
||||
const IS_BASETYPE: bool = false;
|
||||
const IS_SUBCLASS: bool = false;
|
||||
type Layout = ::pyo3::PyCell<Self>;
|
||||
type BaseType = ::pyo3::PyAny;
|
||||
type ThreadChecker = ::pyo3::class::impl_::ThreadCheckerStub<MyClass>;
|
||||
fn for_each_method_def(visitor: &mut dyn ::std::ops::FnMut(&[::pyo3::class::PyMethodDefType])) {
|
||||
use ::pyo3::class::impl_::*;
|
||||
let collector = PyClassImplCollector::<Self>::new();
|
||||
visitor(collector.py_methods());
|
||||
visitor(collector.py_class_descriptors());
|
||||
visitor(collector.object_protocol_methods());
|
||||
visitor(collector.async_protocol_methods());
|
||||
visitor(collector.descr_protocol_methods());
|
||||
visitor(collector.mapping_protocol_methods());
|
||||
visitor(collector.number_protocol_methods());
|
||||
}
|
||||
fn get_new() -> ::std::option::Option<::pyo3::ffi::newfunc> {
|
||||
use ::pyo3::class::impl_::*;
|
||||
let collector = PyClassImplCollector::<Self>::new();
|
||||
collector.new_impl()
|
||||
}
|
||||
fn get_alloc() -> ::std::option::Option<::pyo3::ffi::allocfunc> {
|
||||
use ::pyo3::class::impl_::*;
|
||||
let collector = PyClassImplCollector::<Self>::new();
|
||||
collector.alloc_impl()
|
||||
}
|
||||
fn get_free() -> ::std::option::Option<::pyo3::ffi::freefunc> {
|
||||
use ::pyo3::class::impl_::*;
|
||||
let collector = PyClassImplCollector::<Self>::new();
|
||||
collector.free_impl()
|
||||
}
|
||||
fn for_each_proto_slot(visitor: &mut dyn ::std::ops::FnMut(&[::pyo3::ffi::PyType_Slot])) {
|
||||
use ::pyo3::class::impl_::*;
|
||||
let collector = PyClassImplCollector::<Self>::new();
|
||||
visitor(collector.object_protocol_slots());
|
||||
visitor(collector.number_protocol_slots());
|
||||
visitor(collector.iter_protocol_slots());
|
||||
visitor(collector.gc_protocol_slots());
|
||||
visitor(collector.descr_protocol_slots());
|
||||
visitor(collector.mapping_protocol_slots());
|
||||
visitor(collector.sequence_protocol_slots());
|
||||
visitor(collector.async_protocol_slots());
|
||||
visitor(collector.buffer_protocol_slots());
|
||||
visitor(collector.methods_protocol_slots());
|
||||
}
|
||||
fn get_buffer() -> ::std::option::Option<&'static ::pyo3::class::impl_::PyBufferProcs> {
|
||||
use ::pyo3::class::impl_::*;
|
||||
let collector = PyClassImplCollector::<Self>::new();
|
||||
collector.buffer_procs()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::pyo3::class::impl_::PyClassDescriptors<MyClass>
|
||||
for ::pyo3::class::impl_::PyClassImplCollector<MyClass>
|
||||
{
|
||||
fn py_class_descriptors(self) -> &'static [::pyo3::class::methods::PyMethodDefType] {
|
||||
static METHODS: &[::pyo3::class::methods::PyMethodDefType] = &[];
|
||||
METHODS
|
||||
}
|
||||
}
|
||||
# Python::with_gil(|py| {
|
||||
# let cls = py.get_type::<MyClass>();
|
||||
# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'")
|
||||
# });
|
||||
# }
|
||||
```
|
||||
|
||||
|
|
|
@ -760,6 +760,17 @@ impl<'a> PyClassImplsBuilder<'a> {
|
|||
}
|
||||
},
|
||||
};
|
||||
|
||||
let mutability = if self.attr.is_immutable {
|
||||
quote! {
|
||||
::pyo3::pycell::Immutable
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
::pyo3::pycell::Mutable
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
impl ::pyo3::class::impl_::PyClassImpl for #cls {
|
||||
const DOC: &'static str = #doc;
|
||||
|
@ -770,6 +781,7 @@ impl<'a> PyClassImplsBuilder<'a> {
|
|||
type Layout = ::pyo3::PyCell<Self>;
|
||||
type BaseType = #base;
|
||||
type ThreadChecker = #thread_checker;
|
||||
type Mutability= #mutability;
|
||||
|
||||
fn for_each_method_def(visitor: &mut dyn ::std::ops::FnMut(&[::pyo3::class::PyMethodDefType])) {
|
||||
use ::pyo3::class::impl_::*;
|
||||
|
@ -828,30 +840,10 @@ impl<'a> PyClassImplsBuilder<'a> {
|
|||
if self.attr.is_immutable {
|
||||
quote! {
|
||||
unsafe impl ::pyo3::pyclass::ImmutablePyClass for #cls {}
|
||||
|
||||
unsafe impl ::pyo3::class::impl_::BorrowImpl for #cls {
|
||||
fn get_borrow_flag() -> for<'r> fn(&'r ::pyo3::pycell::PyCell<Self>) -> ::pyo3::pycell::BorrowFlag
|
||||
where Self: ::pyo3::PyClass
|
||||
{
|
||||
::pyo3::pycell::impl_::get_borrow_flag_dummy
|
||||
}
|
||||
fn increment_borrow_flag() -> for<'r> fn(&'r ::pyo3::pycell::PyCell<Self>, ::pyo3::pycell::BorrowFlag)
|
||||
where Self: ::pyo3::PyClass
|
||||
{
|
||||
::pyo3::pycell::impl_::increment_borrow_flag_dummy
|
||||
}
|
||||
fn decrement_borrow_flag() -> for<'r> fn(&'r ::pyo3::pycell::PyCell<Self>, ::pyo3::pycell::BorrowFlag)
|
||||
where Self: ::pyo3::PyClass
|
||||
{
|
||||
::pyo3::pycell::impl_::decrement_borrow_flag_dummy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
unsafe impl ::pyo3::pyclass::MutablePyClass for #cls {}
|
||||
|
||||
unsafe impl ::pyo3::class::impl_::BorrowImpl for #cls {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ impl<T> Copy for PyClassImplCollector<T> {}
|
|||
///
|
||||
/// Users are discouraged from implementing this trait manually; it is a PyO3 implementation detail
|
||||
/// and may be changed at any time.
|
||||
pub trait PyClassImpl: Sized + BorrowImpl {
|
||||
pub trait PyClassImpl: Sized {
|
||||
/// Class doc string
|
||||
const DOC: &'static str = "\0";
|
||||
|
||||
|
@ -67,6 +67,8 @@ pub trait PyClassImpl: Sized + BorrowImpl {
|
|||
/// can be accessed by multiple threads by `threading` module.
|
||||
type ThreadChecker: PyClassThreadChecker<Self>;
|
||||
|
||||
type Mutability: crate::pycell::Mutability;
|
||||
|
||||
fn for_each_method_def(_visitor: &mut dyn FnMut(&[PyMethodDefType])) {}
|
||||
fn get_new() -> Option<ffi::newfunc> {
|
||||
None
|
||||
|
@ -83,27 +85,6 @@ pub trait PyClassImpl: Sized + BorrowImpl {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe trait BorrowImpl {
|
||||
fn get_borrow_flag() -> for<'r> fn(&'r pycell::PyCell<Self>) -> pycell::BorrowFlag
|
||||
where
|
||||
Self: PyClass,
|
||||
{
|
||||
pycell::impl_::get_borrow_flag
|
||||
}
|
||||
fn increment_borrow_flag() -> for<'r> fn(&'r pycell::PyCell<Self>, pycell::BorrowFlag)
|
||||
where
|
||||
Self: PyClass,
|
||||
{
|
||||
pycell::impl_::increment_borrow_flag
|
||||
}
|
||||
fn decrement_borrow_flag() -> for<'r> fn(&'r pycell::PyCell<Self>, pycell::BorrowFlag)
|
||||
where
|
||||
Self: PyClass,
|
||||
{
|
||||
pycell::impl_::decrement_borrow_flag
|
||||
}
|
||||
}
|
||||
|
||||
// Traits describing known special methods.
|
||||
|
||||
pub trait PyClassNewImpl<T> {
|
||||
|
|
185
src/pycell.rs
185
src/pycell.rs
|
@ -192,17 +192,112 @@ use std::cell::{Cell, UnsafeCell};
|
|||
use std::fmt;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait Mutability {
|
||||
/// Creates a new borrow checker
|
||||
fn new() -> Self;
|
||||
/// Increments immutable borrow count, if possible
|
||||
fn try_borrow(&self) -> Result<(), PyBorrowError>;
|
||||
|
||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError>;
|
||||
|
||||
/// Decrements immutable borrow count
|
||||
fn release_borrow(&self);
|
||||
/// Increments mutable borrow count, if possible
|
||||
fn try_borrow_mut(&self) -> Result<(), PyBorrowMutError>;
|
||||
/// Decremements mutable borrow count
|
||||
fn release_borrow_mut(&self);
|
||||
}
|
||||
|
||||
pub struct Mutable {
|
||||
flag: Cell<BorrowFlag>,
|
||||
}
|
||||
impl Mutability for Mutable {
|
||||
fn new() -> Self{
|
||||
Self{flag: Cell::new(BorrowFlag::UNUSED)}
|
||||
}
|
||||
|
||||
fn try_borrow(&self) -> Result<(), PyBorrowError>{
|
||||
let flag = self.flag.get();
|
||||
if flag != BorrowFlag::HAS_MUTABLE_BORROW {
|
||||
self.flag.set(flag.increment());
|
||||
Ok(())
|
||||
}
|
||||
else{
|
||||
Err(PyBorrowError { _private: () })
|
||||
}
|
||||
}
|
||||
|
||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError>{
|
||||
let flag = self.flag.get();
|
||||
if flag != BorrowFlag::HAS_MUTABLE_BORROW {
|
||||
Ok(())
|
||||
}
|
||||
else{
|
||||
Err(PyBorrowError { _private: () })
|
||||
}
|
||||
}
|
||||
|
||||
fn release_borrow(&self){
|
||||
let flag = self.flag.get();
|
||||
self.flag.set(flag.decrement())
|
||||
}
|
||||
|
||||
fn try_borrow_mut(&self) -> Result<(), PyBorrowMutError>{
|
||||
let flag = self.flag.get();
|
||||
if flag == BorrowFlag::UNUSED {
|
||||
self.flag.set(BorrowFlag::HAS_MUTABLE_BORROW);
|
||||
Ok(())
|
||||
}
|
||||
else{
|
||||
Err(PyBorrowMutError { _private: () })
|
||||
}
|
||||
}
|
||||
|
||||
fn release_borrow_mut(&self){
|
||||
self.flag.set(BorrowFlag::UNUSED)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Immutable{
|
||||
flag: PhantomData<Cell<BorrowFlag>>
|
||||
}
|
||||
impl Mutability for Immutable {
|
||||
fn new() -> Self{
|
||||
Self{flag: PhantomData}
|
||||
}
|
||||
|
||||
fn try_borrow(&self) -> Result<(), PyBorrowError>{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError>{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn release_borrow(&self){
|
||||
}
|
||||
|
||||
fn try_borrow_mut(&self) -> Result<(), PyBorrowMutError>{
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn release_borrow_mut(&self){
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Base layout of PyCell.
|
||||
/// This is necessary for sharing BorrowFlag between parents and children.
|
||||
#[doc(hidden)]
|
||||
#[repr(C)]
|
||||
pub struct PyCellBase<T> {
|
||||
pub struct PyCellBase<T, M: Mutability> {
|
||||
ob_base: T,
|
||||
borrow_flag: Cell<BorrowFlag>,
|
||||
borrow_impl: M,
|
||||
}
|
||||
|
||||
unsafe impl<T, U> PyLayout<T> for PyCellBase<U> where U: PySizedLayout<T> {}
|
||||
unsafe impl<T, U, M> PyLayout<T> for PyCellBase<U, M> where U: PySizedLayout<T>, M: Mutability {}
|
||||
|
||||
/// A container type for (mutably) accessing [`PyClass`] values
|
||||
///
|
||||
|
@ -395,13 +490,7 @@ impl<T: PyClass> PyCell<T> {
|
|||
/// });
|
||||
/// ```
|
||||
pub fn try_borrow(&self) -> Result<PyRef<'_, T>, PyBorrowError> {
|
||||
let flag = crate::class::impl_::BorrowImpl::get_borrow_flag()(self);
|
||||
if flag == BorrowFlag::HAS_MUTABLE_BORROW {
|
||||
Err(PyBorrowError { _private: () })
|
||||
} else {
|
||||
crate::class::impl_::BorrowImpl::increment_borrow_flag()(self, flag);
|
||||
Ok(PyRef { inner: self })
|
||||
}
|
||||
self.borrow_checker().try_borrow().map(|_| PyRef { inner: self })
|
||||
}
|
||||
|
||||
/// Mutably borrows the value `T`, returning an error if the value is currently borrowed.
|
||||
|
@ -429,12 +518,7 @@ impl<T: PyClass> PyCell<T> {
|
|||
where
|
||||
T: MutablePyClass,
|
||||
{
|
||||
if self.get_borrow_flag() != BorrowFlag::UNUSED {
|
||||
Err(PyBorrowMutError { _private: () })
|
||||
} else {
|
||||
self.set_borrow_flag(BorrowFlag::HAS_MUTABLE_BORROW);
|
||||
Ok(PyRefMut { inner: self })
|
||||
}
|
||||
self.borrow_checker().try_borrow_mut().map(|_| PyRefMut { inner: self })
|
||||
}
|
||||
|
||||
/// Immutably borrows the value `T`, returning an error if the value is
|
||||
|
@ -467,13 +551,7 @@ impl<T: PyClass> PyCell<T> {
|
|||
/// });
|
||||
/// ```
|
||||
pub unsafe fn try_borrow_unguarded(&self) -> Result<&T, PyBorrowError> {
|
||||
if crate::class::impl_::BorrowImpl::get_borrow_flag()(self)
|
||||
== BorrowFlag::HAS_MUTABLE_BORROW
|
||||
{
|
||||
Err(PyBorrowError { _private: () })
|
||||
} else {
|
||||
Ok(&*self.contents.value.get())
|
||||
}
|
||||
self.borrow_checker().try_borrow_unguarded().map(|_:()| &*self.contents.value.get())
|
||||
}
|
||||
|
||||
/// Replaces the wrapped value with a new one, returning the old value.
|
||||
|
@ -521,42 +599,6 @@ impl<T: PyClass> PyCell<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod impl_ {
|
||||
use super::*;
|
||||
|
||||
#[inline]
|
||||
pub fn get_borrow_flag<T: PyClass>(slf: &PyCell<T>) -> BorrowFlag {
|
||||
PyCellLayout::get_borrow_flag(slf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_borrow_flag_dummy<T: ImmutablePyClass>(_slf: &PyCell<T>) -> BorrowFlag {
|
||||
debug_assert_eq!(PyCellLayout::get_borrow_flag(_slf), BorrowFlag::UNUSED);
|
||||
BorrowFlag::UNUSED
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn increment_borrow_flag<T: PyClass>(slf: &PyCell<T>, flag: BorrowFlag) {
|
||||
PyCellLayout::set_borrow_flag(slf, flag.increment());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn increment_borrow_flag_dummy<T: ImmutablePyClass>(_slf: &PyCell<T>, _flag: BorrowFlag) {
|
||||
debug_assert_eq!(PyCellLayout::get_borrow_flag(_slf), BorrowFlag::UNUSED);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn decrement_borrow_flag<T: PyClass>(slf: &PyCell<T>, flag: BorrowFlag) {
|
||||
PyCellLayout::set_borrow_flag(slf, flag.decrement());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn decrement_borrow_flag_dummy<T: ImmutablePyClass>(_slf: &PyCell<T>, _flag: BorrowFlag) {
|
||||
debug_assert_eq!(PyCellLayout::get_borrow_flag(_slf), BorrowFlag::UNUSED);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: PyClass> PyLayout<T> for PyCell<T> {}
|
||||
impl<T: PyClass> PySizedLayout<T> for PyCell<T> {}
|
||||
|
||||
|
@ -740,8 +782,7 @@ impl<'p, T: PyClass> Deref for PyRef<'p, T> {
|
|||
|
||||
impl<'p, T: PyClass> Drop for PyRef<'p, T> {
|
||||
fn drop(&mut self) {
|
||||
let flag = crate::class::impl_::BorrowImpl::get_borrow_flag()(self.inner);
|
||||
crate::class::impl_::BorrowImpl::decrement_borrow_flag()(self.inner, flag);
|
||||
self.inner.borrow_checker().release_borrow()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -839,7 +880,7 @@ impl<'p, T: MutablePyClass> DerefMut for PyRefMut<'p, T> {
|
|||
|
||||
impl<'p, T: MutablePyClass> Drop for PyRefMut<'p, T> {
|
||||
fn drop(&mut self) {
|
||||
self.inner.set_borrow_flag(BorrowFlag::UNUSED)
|
||||
self.inner.borrow_checker().release_borrow_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -935,9 +976,7 @@ impl From<PyBorrowMutError> for PyErr {
|
|||
|
||||
#[doc(hidden)]
|
||||
pub trait PyCellLayout<T>: PyLayout<T> {
|
||||
fn get_borrow_flag(&self) -> BorrowFlag;
|
||||
fn set_borrow_flag(&self, flag: BorrowFlag);
|
||||
|
||||
fn borrow_checker(&self) -> &Mutable;
|
||||
/// Implementation of tp_dealloc.
|
||||
/// # Safety
|
||||
/// - slf must be a valid pointer to an instance of a T or a subclass.
|
||||
|
@ -945,16 +984,13 @@ pub trait PyCellLayout<T>: PyLayout<T> {
|
|||
unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python);
|
||||
}
|
||||
|
||||
impl<T, U> PyCellLayout<T> for PyCellBase<U>
|
||||
impl<T, U> PyCellLayout<T> for PyCellBase<U, Mutable>
|
||||
where
|
||||
U: PySizedLayout<T>,
|
||||
T: PyTypeInfo,
|
||||
{
|
||||
fn get_borrow_flag(&self) -> BorrowFlag {
|
||||
self.borrow_flag.get()
|
||||
}
|
||||
fn set_borrow_flag(&self, flag: BorrowFlag) {
|
||||
self.borrow_flag.set(flag)
|
||||
fn borrow_checker(&self) -> &Mutable {
|
||||
&self.borrow_impl
|
||||
}
|
||||
|
||||
unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python) {
|
||||
|
@ -982,12 +1018,9 @@ impl<T: PyClass> PyCellLayout<T> for PyCell<T>
|
|||
where
|
||||
<T::BaseType as PyClassBaseType>::LayoutAsBase: PyCellLayout<T::BaseType>,
|
||||
{
|
||||
fn get_borrow_flag(&self) -> BorrowFlag {
|
||||
fn borrow_checker(&self) -> &Mutable {
|
||||
self.contents.thread_checker.ensure();
|
||||
self.ob_base.get_borrow_flag()
|
||||
}
|
||||
fn set_borrow_flag(&self, flag: BorrowFlag) {
|
||||
self.ob_base.set_borrow_flag(flag)
|
||||
self.ob_base.borrow_checker()
|
||||
}
|
||||
unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python) {
|
||||
// Safety: Python only calls tp_dealloc when no references to the object remain.
|
||||
|
|
|
@ -198,7 +198,7 @@ macro_rules! pyobject_native_type_sized {
|
|||
impl<'a, $($generics,)*> $crate::class::impl_::PyClassBaseType for $name {
|
||||
type Dict = $crate::pyclass_slots::PyClassDummySlot;
|
||||
type WeakRef = $crate::pyclass_slots::PyClassDummySlot;
|
||||
type LayoutAsBase = $crate::pycell::PyCellBase<$layout>;
|
||||
type LayoutAsBase = $crate::pycell::PyCellBase<$layout, $crate::pycell::Mutable>;
|
||||
type BaseNativeType = $name;
|
||||
type ThreadChecker = $crate::class::impl_::ThreadCheckerStub<$crate::PyObject>;
|
||||
type Initializer = $crate::pyclass_init::PyNativeTypeInitializer<Self>;
|
||||
|
|
Loading…
Reference in New Issue