part 3
This commit is contained in:
parent
63eda2f5c9
commit
64d85e5ebf
|
@ -637,6 +637,7 @@ impl<'a> PyClassImplsBuilder<'a> {
|
|||
type Dict = #dict;
|
||||
type WeakRef = #weakref;
|
||||
type BaseNativeType = #base_nativetype;
|
||||
type Mutability = ::pyo3::pycell::Immutable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -763,8 +764,8 @@ impl<'a> PyClassImplsBuilder<'a> {
|
|||
|
||||
let mutability = if self.attr.is_immutable {
|
||||
quote! {
|
||||
::pyo3::pycell::Immutable
|
||||
}
|
||||
::pyo3::pycell::Immutable
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
::pyo3::pycell::Mutable
|
||||
|
@ -781,7 +782,6 @@ 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_::*;
|
||||
|
@ -839,8 +839,8 @@ impl<'a> PyClassImplsBuilder<'a> {
|
|||
let cls = self.cls;
|
||||
if self.attr.is_immutable {
|
||||
quote! {
|
||||
unsafe impl ::pyo3::pyclass::ImmutablePyClass for #cls {}
|
||||
}
|
||||
unsafe impl ::pyo3::pyclass::ImmutablePyClass for #cls {}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
unsafe impl ::pyo3::pyclass::MutablePyClass for #cls {}
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
exceptions::{PyAttributeError, PyNotImplementedError},
|
||||
ffi,
|
||||
impl_::freelist::FreeList,
|
||||
pycell::{PyCellLayout, Mutability},
|
||||
pycell::{Mutability, PyCellLayout},
|
||||
pyclass_init::PyObjectInit,
|
||||
type_object::{PyLayout, PyTypeObject},
|
||||
PyClass, PyMethodDefType, PyNativeType, PyResult, PyTypeInfo, Python,
|
||||
|
@ -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 {
|
||||
pub trait PyClassImpl<M: Mutability>: Sized {
|
||||
/// Class doc string
|
||||
const DOC: &'static str = "\0";
|
||||
|
||||
|
@ -56,7 +56,7 @@ pub trait PyClassImpl: Sized {
|
|||
type Layout: PyLayout<Self>;
|
||||
|
||||
/// Base class
|
||||
type BaseType: PyTypeInfo + PyTypeObject + PyClassBaseType;
|
||||
type BaseType: PyTypeInfo + PyTypeObject + PyClassBaseType<M>;
|
||||
|
||||
/// This handles following two situations:
|
||||
/// 1. In case `T` is `Send`, stub `ThreadChecker` is used and does nothing.
|
||||
|
@ -67,8 +67,6 @@ pub trait PyClassImpl: Sized {
|
|||
/// 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
|
||||
|
@ -749,9 +747,14 @@ impl<T> PyClassThreadChecker<T> for ThreadCheckerImpl<T> {
|
|||
/// Thread checker for types that have `Send` and `extends=...`.
|
||||
/// Ensures that `T: Send` and the parent is not accessed by another thread.
|
||||
#[doc(hidden)]
|
||||
pub struct ThreadCheckerInherited<T: Send, U: PyClassBaseType>(PhantomData<T>, U::ThreadChecker);
|
||||
pub struct ThreadCheckerInherited<T: Send, U: PyClassBaseType<M>, M: Mutability>(
|
||||
PhantomData<T>,
|
||||
U::ThreadChecker,
|
||||
);
|
||||
|
||||
impl<T: Send, U: PyClassBaseType> PyClassThreadChecker<T> for ThreadCheckerInherited<T, U> {
|
||||
impl<T: Send, U: PyClassBaseType<M>, M: Mutability> PyClassThreadChecker<T>
|
||||
for ThreadCheckerInherited<T, U, M>
|
||||
{
|
||||
fn ensure(&self) {
|
||||
self.1.ensure();
|
||||
}
|
||||
|
@ -762,25 +765,23 @@ impl<T: Send, U: PyClassBaseType> PyClassThreadChecker<T> for ThreadCheckerInher
|
|||
}
|
||||
|
||||
/// Trait denoting that this class is suitable to be used as a base type for PyClass.
|
||||
pub trait PyClassBaseType: Sized {
|
||||
pub trait PyClassBaseType<M: Mutability>: Sized {
|
||||
type Dict;
|
||||
type WeakRef;
|
||||
type LayoutAsBase: PyCellLayout<Self>;
|
||||
type LayoutAsBase: PyCellLayout<Self, M>;
|
||||
type BaseNativeType;
|
||||
type ThreadChecker: PyClassThreadChecker<Self>;
|
||||
type Initializer: PyObjectInit<Self>;
|
||||
type Mutability: Mutability;
|
||||
}
|
||||
|
||||
/// All PyClasses can be used as a base type.
|
||||
impl<T: PyClass> PyClassBaseType for T {
|
||||
impl<T: PyClass> PyClassBaseType<T::Mutability> for T {
|
||||
type Dict = T::Dict;
|
||||
type WeakRef = T::WeakRef;
|
||||
type LayoutAsBase = crate::pycell::PyCell<T>;
|
||||
type BaseNativeType = T::BaseNativeType;
|
||||
type ThreadChecker = T::ThreadChecker;
|
||||
type Initializer = crate::pyclass_init::PyClassInitializer<Self>;
|
||||
type Mutability = T::Mutability;
|
||||
}
|
||||
|
||||
/// Default new implementation
|
||||
|
|
|
@ -174,6 +174,7 @@
|
|||
//! [guide]: https://pyo3.rs/latest/class.html#pycell-and-interior-mutability "PyCell and interior mutability"
|
||||
//! [Interior Mutability]: https://doc.rust-lang.org/book/ch15-05-interior-mutability.html "RefCell<T> and the Interior Mutability Pattern - The Rust Programming Language"
|
||||
|
||||
use crate::class::impl_::PyClassImpl;
|
||||
use crate::exceptions::PyRuntimeError;
|
||||
use crate::pyclass::{MutablePyClass, PyClass};
|
||||
use crate::pyclass_init::PyClassInitializer;
|
||||
|
@ -181,7 +182,6 @@ use crate::pyclass_slots::{PyClassDict, PyClassWeakRef};
|
|||
use crate::type_object::{PyLayout, PySizedLayout};
|
||||
use crate::types::PyAny;
|
||||
use crate::{class::impl_::PyClassBaseType, class::impl_::PyClassThreadChecker};
|
||||
use crate::class::impl_::PyClassImpl;
|
||||
use crate::{
|
||||
conversion::{AsPyPointer, FromPyPointer, ToPyObject},
|
||||
ffi::PyBaseObject_Type,
|
||||
|
@ -191,9 +191,9 @@ use crate::{
|
|||
use crate::{ffi, IntoPy, PyErr, PyNativeType, PyObject, PyResult, Python};
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait Mutability {
|
||||
/// Creates a new borrow checker
|
||||
|
@ -202,7 +202,7 @@ pub trait Mutability {
|
|||
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
|
||||
|
@ -215,76 +215,74 @@ pub struct Mutable {
|
|||
flag: Cell<BorrowFlag>,
|
||||
}
|
||||
impl Mutability for Mutable {
|
||||
fn new() -> Self{
|
||||
Self{flag: Cell::new(BorrowFlag::UNUSED)}
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
flag: Cell::new(BorrowFlag::UNUSED),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_borrow(&self) -> Result<(), PyBorrowError>{
|
||||
fn try_borrow(&self) -> Result<(), PyBorrowError> {
|
||||
let flag = self.flag.get();
|
||||
if flag != BorrowFlag::HAS_MUTABLE_BORROW {
|
||||
self.flag.set(flag.increment());
|
||||
Ok(())
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
Err(PyBorrowError { _private: () })
|
||||
}
|
||||
}
|
||||
|
||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError>{
|
||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError> {
|
||||
let flag = self.flag.get();
|
||||
if flag != BorrowFlag::HAS_MUTABLE_BORROW {
|
||||
Ok(())
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
Err(PyBorrowError { _private: () })
|
||||
}
|
||||
}
|
||||
|
||||
fn release_borrow(&self){
|
||||
fn release_borrow(&self) {
|
||||
let flag = self.flag.get();
|
||||
self.flag.set(flag.decrement())
|
||||
}
|
||||
|
||||
fn try_borrow_mut(&self) -> Result<(), PyBorrowMutError>{
|
||||
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{
|
||||
} else {
|
||||
Err(PyBorrowMutError { _private: () })
|
||||
}
|
||||
}
|
||||
|
||||
fn release_borrow_mut(&self){
|
||||
fn release_borrow_mut(&self) {
|
||||
self.flag.set(BorrowFlag::UNUSED)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Immutable{
|
||||
flag: PhantomData<Cell<BorrowFlag>>
|
||||
pub struct Immutable {
|
||||
flag: PhantomData<Cell<BorrowFlag>>,
|
||||
}
|
||||
impl Mutability for Immutable {
|
||||
fn new() -> Self{
|
||||
Self{flag: PhantomData}
|
||||
fn new() -> Self {
|
||||
Self { flag: PhantomData }
|
||||
}
|
||||
|
||||
fn try_borrow(&self) -> Result<(), PyBorrowError>{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError>{
|
||||
fn try_borrow(&self) -> Result<(), PyBorrowError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn release_borrow(&self){
|
||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn try_borrow_mut(&self) -> Result<(), PyBorrowMutError>{
|
||||
fn release_borrow(&self) {}
|
||||
|
||||
fn try_borrow_mut(&self) -> Result<(), PyBorrowMutError> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn release_borrow_mut(&self){
|
||||
fn release_borrow_mut(&self) {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +296,12 @@ pub struct PyCellBase<T, M: Mutability> {
|
|||
borrow_impl: M,
|
||||
}
|
||||
|
||||
unsafe impl<T, U, M> PyLayout<T> for PyCellBase<U, M> where U: PySizedLayout<T>, M: Mutability {}
|
||||
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
|
||||
///
|
||||
|
@ -337,7 +340,7 @@ unsafe impl<T, U, M> PyLayout<T> for PyCellBase<U, M> where U: PySizedLayout<T>,
|
|||
/// [module-level documentation](self).
|
||||
#[repr(C)]
|
||||
pub struct PyCell<T: PyClass> {
|
||||
ob_base: <T::BaseType as PyClassBaseType>::LayoutAsBase,
|
||||
ob_base: <T::BaseType as PyClassBaseType<T::Mutability>>::LayoutAsBase,
|
||||
contents: PyCellContents<T>,
|
||||
}
|
||||
|
||||
|
@ -491,7 +494,9 @@ impl<T: PyClass> PyCell<T> {
|
|||
/// });
|
||||
/// ```
|
||||
pub fn try_borrow(&self) -> Result<PyRef<'_, T>, PyBorrowError> {
|
||||
self.borrow_checker().try_borrow().map(|_| 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.
|
||||
|
@ -519,7 +524,9 @@ impl<T: PyClass> PyCell<T> {
|
|||
where
|
||||
T: MutablePyClass,
|
||||
{
|
||||
self.borrow_checker().try_borrow_mut().map(|_| 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
|
||||
|
@ -552,7 +559,9 @@ impl<T: PyClass> PyCell<T> {
|
|||
/// });
|
||||
/// ```
|
||||
pub unsafe fn try_borrow_unguarded(&self) -> Result<&T, PyBorrowError> {
|
||||
self.borrow_checker().try_borrow_unguarded().map(|_:()| &*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.
|
||||
|
@ -976,8 +985,11 @@ impl From<PyBorrowMutError> for PyErr {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait PyCellLayout<T>: PyLayout<T> {
|
||||
fn borrow_checker(&self) -> &T::Mutability where T: PyClass;
|
||||
pub trait PyCellLayout<T, M>: PyLayout<T>
|
||||
where
|
||||
M: Mutability,
|
||||
{
|
||||
fn borrow_checker(&self) -> &M;
|
||||
/// Implementation of tp_dealloc.
|
||||
/// # Safety
|
||||
/// - slf must be a valid pointer to an instance of a T or a subclass.
|
||||
|
@ -985,14 +997,13 @@ pub trait PyCellLayout<T>: PyLayout<T> {
|
|||
unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python);
|
||||
}
|
||||
|
||||
impl<T, U, M> PyCellLayout<T> for PyCellBase<U, M>
|
||||
impl<T, U, M> PyCellLayout<T, M> for PyCellBase<U, M>
|
||||
where
|
||||
U: PySizedLayout<T>,
|
||||
T: PyTypeInfo,
|
||||
M: Mutability
|
||||
|
||||
M: Mutability,
|
||||
{
|
||||
fn borrow_checker(&self) -> &T::Mutability where T: PyClass{
|
||||
fn borrow_checker(&self) -> &M {
|
||||
&self.borrow_impl
|
||||
}
|
||||
|
||||
|
@ -1017,11 +1028,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: PyClass> PyCellLayout<T> for PyCell<T>
|
||||
impl<T: PyClass> PyCellLayout<T, T::Mutability> for PyCell<T>
|
||||
where
|
||||
<T::BaseType as PyClassBaseType>::LayoutAsBase: PyCellLayout<T::BaseType>,
|
||||
<T::BaseType as PyClassBaseType<T::Mutability>>::LayoutAsBase:
|
||||
PyCellLayout<T::BaseType, T::Mutability>,
|
||||
{
|
||||
fn borrow_checker(&self) -> &T ::Mutability {
|
||||
fn borrow_checker(&self) -> &T::Mutability {
|
||||
self.contents.thread_checker.ensure();
|
||||
self.ob_base.borrow_checker()
|
||||
}
|
||||
|
@ -1031,6 +1043,6 @@ where
|
|||
ManuallyDrop::drop(&mut cell.contents.value);
|
||||
cell.contents.dict.clear_dict(py);
|
||||
cell.contents.weakref.clear_weakrefs(slf, py);
|
||||
<T::BaseType as PyClassBaseType>::LayoutAsBase::tp_dealloc(slf, py)
|
||||
<T::BaseType as PyClassBaseType<T::Mutability>>::LayoutAsBase::tp_dealloc(slf, py)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//! `PyClass` and related traits.
|
||||
use crate::pycell::Mutability;
|
||||
use crate::{
|
||||
class::impl_::{fallback_new, tp_dealloc, PyClassImpl},
|
||||
ffi,
|
||||
pyclass_slots::{PyClassDict, PyClassWeakRef},
|
||||
PyCell, PyErr, PyMethodDefType, PyNativeType, PyResult, PyTypeInfo, Python,
|
||||
};
|
||||
use crate::pycell::Mutability;
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
ffi::CString,
|
||||
|
@ -19,7 +19,7 @@ use std::{
|
|||
/// The `#[pyclass]` attribute automatically implements this trait for your Rust struct,
|
||||
/// so you normally don't have to use this trait directly.
|
||||
pub trait PyClass:
|
||||
PyTypeInfo<AsRefTarget = PyCell<Self>> + PyClassImpl<Layout = PyCell<Self>>
|
||||
PyTypeInfo<AsRefTarget = PyCell<Self>> + PyClassImpl<Self::Mutability, Layout = PyCell<Self>>
|
||||
{
|
||||
/// Specify this class has `#[pyclass(dict)]` or not.
|
||||
type Dict: PyClassDict;
|
||||
|
@ -29,7 +29,7 @@ pub trait PyClass:
|
|||
/// `#[pyclass(extends=PyDict)]`, it's `PyDict`.
|
||||
type BaseNativeType: PyTypeInfo + PyNativeType;
|
||||
|
||||
//type Mutability: Mutability;
|
||||
type Mutability: Mutability;
|
||||
}
|
||||
|
||||
pub unsafe trait MutablePyClass: PyClass {}
|
||||
|
|
|
@ -127,14 +127,17 @@ impl<T: PyTypeInfo> PyObjectInit<T> for PyNativeTypeInitializer<T> {
|
|||
/// ```
|
||||
pub struct PyClassInitializer<T: PyClass> {
|
||||
init: T,
|
||||
super_init: <T::BaseType as PyClassBaseType>::Initializer,
|
||||
super_init: <T::BaseType as PyClassBaseType<T::Mutability>>::Initializer,
|
||||
}
|
||||
|
||||
impl<T: PyClass> PyClassInitializer<T> {
|
||||
/// Constructs a new initializer from value `T` and base class' initializer.
|
||||
///
|
||||
/// It is recommended to use `add_subclass` instead of this method for most usage.
|
||||
pub fn new(init: T, super_init: <T::BaseType as PyClassBaseType>::Initializer) -> Self {
|
||||
pub fn new(
|
||||
init: T,
|
||||
super_init: <T::BaseType as PyClassBaseType<T::Mutability>>::Initializer,
|
||||
) -> Self {
|
||||
Self { init, super_init }
|
||||
}
|
||||
|
||||
|
@ -187,7 +190,7 @@ impl<T: PyClass> PyClassInitializer<T> {
|
|||
pub fn add_subclass<S>(self, subclass_value: S) -> PyClassInitializer<S>
|
||||
where
|
||||
S: PyClass<BaseType = T>,
|
||||
S::BaseType: PyClassBaseType<Initializer = Self>,
|
||||
S::BaseType: PyClassBaseType<T::Mutability, Initializer = Self>,
|
||||
{
|
||||
PyClassInitializer::new(subclass_value, self)
|
||||
}
|
||||
|
@ -228,16 +231,16 @@ impl<T: PyClass> PyObjectInit<T> for PyClassInitializer<T> {
|
|||
/// Layout of a PyCellBase after base new has been called, but the borrow flag has not
|
||||
/// yet been initialized.
|
||||
#[repr(C)]
|
||||
struct PartiallyInitializedPyCellBase<T> {
|
||||
struct PartiallyInitializedPyCellBase<T: PyClass> {
|
||||
_ob_base: T,
|
||||
borrow_flag: MaybeUninit<Cell<BorrowFlag>>,
|
||||
borrow_flag: MaybeUninit<T::Mutability>,
|
||||
}
|
||||
|
||||
/// Layout of a PyCell after base new has been called, but the contents have not yet been
|
||||
/// written.
|
||||
#[repr(C)]
|
||||
struct PartiallyInitializedPyCell<T: PyClass> {
|
||||
_ob_base: <T::BaseType as PyClassBaseType>::LayoutAsBase,
|
||||
_ob_base: <T::BaseType as PyClassBaseType<T::Mutability>>::LayoutAsBase,
|
||||
contents: MaybeUninit<PyCellContents<T>>,
|
||||
}
|
||||
|
||||
|
@ -271,7 +274,7 @@ impl<T: PyClass> PyObjectInit<T> for PyClassInitializer<T> {
|
|||
impl<T> From<T> for PyClassInitializer<T>
|
||||
where
|
||||
T: PyClass,
|
||||
T::BaseType: PyClassBaseType<Initializer = PyNativeTypeInitializer<T::BaseType>>,
|
||||
T::BaseType: PyClassBaseType<T::Mutability, Initializer = PyNativeTypeInitializer<T::BaseType>>,
|
||||
{
|
||||
#[inline]
|
||||
fn from(value: T) -> PyClassInitializer<T> {
|
||||
|
@ -283,7 +286,7 @@ impl<S, B> From<(S, B)> for PyClassInitializer<S>
|
|||
where
|
||||
S: PyClass<BaseType = B>,
|
||||
B: PyClass,
|
||||
B::BaseType: PyClassBaseType<Initializer = PyNativeTypeInitializer<B::BaseType>>,
|
||||
B::BaseType: PyClassBaseType<Initializer = PyNativeTypeInitializer<B::BaseType>>,
|
||||
{
|
||||
fn from(sub_and_base: (S, B)) -> PyClassInitializer<S> {
|
||||
let (sub, base) = sub_and_base;
|
||||
|
|
|
@ -195,14 +195,13 @@ macro_rules! pyobject_native_type_sized {
|
|||
($name:ty, $layout:path $(;$generics:ident)*) => {
|
||||
unsafe impl $crate::type_object::PyLayout<$name> for $layout {}
|
||||
impl $crate::type_object::PySizedLayout<$name> for $layout {}
|
||||
impl<'a, $($generics,)*> $crate::class::impl_::PyClassBaseType for $name {
|
||||
impl<'a, $($generics,)*> $crate::class::impl_::PyClassBaseType<$crate::pycell::Mutable> for $name {
|
||||
type Dict = $crate::pyclass_slots::PyClassDummySlot;
|
||||
type WeakRef = $crate::pyclass_slots::PyClassDummySlot;
|
||||
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>;
|
||||
type Mutability = $crate::pycell::Mutable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue