pyclass: no need to try inherit base dict and weaklist

This commit is contained in:
David Hewitt 2021-12-30 12:16:46 +00:00
parent 90e8ef79e2
commit 807e126178
6 changed files with 112 additions and 119 deletions

View File

@ -664,8 +664,6 @@ impl<'a> PyClassImplsBuilder<'a> {
let attr = self.attr;
let dict = if attr.has_dict {
quote! { _pyo3::pyclass_slots::PyClassDictSlot }
} else if attr.has_extends {
quote! { <Self::BaseType as _pyo3::class::impl_::PyClassBaseType>::Dict }
} else {
quote! { _pyo3::pyclass_slots::PyClassDummySlot }
};
@ -673,8 +671,6 @@ impl<'a> PyClassImplsBuilder<'a> {
// insert space for weak ref
let weakref = if attr.has_weaklist {
quote! { _pyo3::pyclass_slots::PyClassWeakRefSlot }
} else if attr.has_extends {
quote! { <Self::BaseType as _pyo3::class::impl_::PyClassBaseType>::WeakRef }
} else {
quote! { _pyo3::pyclass_slots::PyClassDummySlot }
};

View File

@ -760,8 +760,6 @@ 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 {
type Dict;
type WeakRef;
type LayoutAsBase: PyCellLayout<Self>;
type BaseNativeType;
type ThreadChecker: PyClassThreadChecker<Self>;
@ -770,8 +768,6 @@ pub trait PyClassBaseType: Sized {
/// All PyClasses can be used as a base type.
impl<T: PyClass> PyClassBaseType for T {
type Dict = T::Dict;
type WeakRef = T::WeakRef;
type LayoutAsBase = crate::pycell::PyCell<T>;
type BaseNativeType = T::BaseNativeType;
type ThreadChecker = T::ThreadChecker;

View File

@ -197,8 +197,6 @@ macro_rules! pyobject_native_type_sized {
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 {
type Dict = $crate::pyclass_slots::PyClassDummySlot;
type WeakRef = $crate::pyclass_slots::PyClassDummySlot;
type LayoutAsBase = $crate::pycell::PyCellBase<$layout>;
type BaseNativeType = $name;
type ThreadChecker = $crate::class::impl_::ThreadCheckerStub<$crate::PyObject>;

View File

@ -343,3 +343,115 @@ fn test_tuple_struct_class() {
assert_eq!(instance.borrow(py).0, 1234);
});
}
#[pyclass(dict, subclass)]
struct DunderDictSupport {}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn dunder_dict_support() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, DunderDictSupport {}).unwrap();
py_run!(
py,
inst,
r#"
inst.a = 1
assert inst.a == 1
"#
);
}
// Accessing inst.__dict__ only supported in limited API from Python 3.10
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
fn access_dunder_dict() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, DunderDictSupport {}).unwrap();
py_run!(
py,
inst,
r#"
inst.a = 1
assert inst.__dict__ == {'a': 1}
"#
);
}
// If the base class has dict support, child class also has dict
#[pyclass(extends=DunderDictSupport)]
struct InheritDict {
_value: usize,
}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn inherited_dict() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, (InheritDict { _value: 0 }, DunderDictSupport {})).unwrap();
py_run!(
py,
inst,
r#"
inst.a = 1
assert inst.a == 1
"#
);
}
#[pyclass(weakref, dict)]
struct WeakRefDunderDictSupport {}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn weakref_dunder_dict_support() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, WeakRefDunderDictSupport {}).unwrap();
py_run!(
py,
inst,
"import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1"
);
}
#[pyclass(weakref, subclass)]
struct WeakRefSupport {}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn weakref_support() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, WeakRefSupport {}).unwrap();
py_run!(
py,
inst,
"import weakref; assert weakref.ref(inst)() is inst"
);
}
// If the base class has weakref support, child class also has weakref.
#[pyclass(extends=WeakRefSupport)]
struct InheritWeakRef {
_value: usize,
}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn inherited_weakref() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, (InheritWeakRef { _value: 0 }, WeakRefSupport {})).unwrap();
py_run!(
py,
inst,
"import weakref; assert weakref.ref(inst)() is inst"
);
}

View File

@ -148,41 +148,6 @@ fn gc_integration2() {
py_run!(py, inst, "import gc; assert inst in gc.get_objects()");
}
#[pyclass(weakref, subclass)]
struct WeakRefSupport {}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn weakref_support() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, WeakRefSupport {}).unwrap();
py_run!(
py,
inst,
"import weakref; assert weakref.ref(inst)() is inst"
);
}
// If the base class has weakref support, child class also has weakref.
#[pyclass(extends=WeakRefSupport)]
struct InheritWeakRef {
_value: usize,
}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn inherited_weakref() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, (InheritWeakRef { _value: 0 }, WeakRefSupport {})).unwrap();
py_run!(
py,
inst,
"import weakref; assert weakref.ref(inst)() is inst"
);
}
#[pyclass(subclass)]
struct BaseClassWithDrop {
data: Option<Arc<AtomicBool>>,

View File

@ -349,80 +349,6 @@ fn test_cls_impl() {
py_assert!(py, ob, "ob[100:200:1] == 'slice'");
}
#[pyclass(dict, subclass)]
struct DunderDictSupport {}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn dunder_dict_support() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, DunderDictSupport {}).unwrap();
py_run!(
py,
inst,
r#"
inst.a = 1
assert inst.a == 1
"#
);
}
// Accessing inst.__dict__ only supported in limited API from Python 3.10
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
fn access_dunder_dict() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, DunderDictSupport {}).unwrap();
py_run!(
py,
inst,
r#"
inst.a = 1
assert inst.__dict__ == {'a': 1}
"#
);
}
// If the base class has dict support, child class also has dict
#[pyclass(extends=DunderDictSupport)]
struct InheritDict {
_value: usize,
}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn inherited_dict() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, (InheritDict { _value: 0 }, DunderDictSupport {})).unwrap();
py_run!(
py,
inst,
r#"
inst.a = 1
assert inst.a == 1
"#
);
}
#[pyclass(weakref, dict)]
struct WeakRefDunderDictSupport {}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
fn weakref_dunder_dict_support() {
let gil = Python::acquire_gil();
let py = gil.python();
let inst = PyCell::new(py, WeakRefDunderDictSupport {}).unwrap();
py_run!(
py,
inst,
"import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1"
);
}
#[pyclass]
struct ClassWithGetAttr {
#[pyo3(get, set)]