rustpython_vm/object/
payload.rs1use crate::object::{MaybeTraverse, Py, PyObjectRef, PyRef, PyResult};
2use crate::{
3 builtins::{PyBaseExceptionRef, PyType, PyTypeRef},
4 types::PyTypeFlags,
5 vm::{Context, VirtualMachine},
6 PyRefExact,
7};
8
9cfg_if::cfg_if! {
10 if #[cfg(feature = "threading")] {
11 pub trait PyThreadingConstraint: Send + Sync {}
12 impl<T: Send + Sync> PyThreadingConstraint for T {}
13 } else {
14 pub trait PyThreadingConstraint {}
15 impl<T> PyThreadingConstraint for T {}
16 }
17}
18
19pub trait PyPayload:
20 std::fmt::Debug + MaybeTraverse + PyThreadingConstraint + Sized + 'static
21{
22 fn class(ctx: &Context) -> &'static Py<PyType>;
23
24 #[inline]
25 fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
26 self.into_ref(&vm.ctx).into()
27 }
28
29 #[inline]
30 fn _into_ref(self, cls: PyTypeRef, ctx: &Context) -> PyRef<Self> {
31 let dict = if cls.slots.flags.has_feature(PyTypeFlags::HAS_DICT) {
32 Some(ctx.new_dict())
33 } else {
34 None
35 };
36 PyRef::new_ref(self, cls, dict)
37 }
38
39 #[inline]
40 fn into_exact_ref(self, ctx: &Context) -> PyRefExact<Self> {
41 unsafe {
42 PyRefExact::new_unchecked(self.into_ref(ctx))
44 }
45 }
46
47 #[inline]
48 fn into_ref(self, ctx: &Context) -> PyRef<Self> {
49 let cls = Self::class(ctx);
50 self._into_ref(cls.to_owned(), ctx)
51 }
52
53 #[inline]
54 fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult<PyRef<Self>> {
55 let exact_class = Self::class(&vm.ctx);
56 if cls.fast_issubclass(exact_class) {
57 Ok(self._into_ref(cls, &vm.ctx))
58 } else {
59 #[cold]
60 #[inline(never)]
61 fn _into_ref_with_type_error(
62 vm: &VirtualMachine,
63 cls: &PyTypeRef,
64 exact_class: &Py<PyType>,
65 ) -> PyBaseExceptionRef {
66 vm.new_type_error(format!(
67 "'{}' is not a subtype of '{}'",
68 &cls.name(),
69 exact_class.name()
70 ))
71 }
72 Err(_into_ref_with_type_error(vm, &cls, exact_class))
73 }
74 }
75}
76
77pub trait PyObjectPayload:
78 std::any::Any + std::fmt::Debug + MaybeTraverse + PyThreadingConstraint + 'static
79{
80}
81
82impl<T: PyPayload + 'static> PyObjectPayload for T {}
83
84pub trait SlotOffset {
85 fn offset() -> usize;
86}