pub trait PyPayload:
MaybeTraverse
+ PyThreadingConstraint
+ Sized
+ 'static {
const PAYLOAD_TYPE_ID: TypeId = _;
const NEW_REF_UNTRACKED: bool = false;
const HAS_FREELIST: bool = false;
const MAX_FREELIST: usize = 0;
// Required method
fn class(ctx: &Context) -> &'static Py<PyType>;
// Provided methods
unsafe fn validate_downcastable_from(_obj: &PyObject) -> bool { ... }
fn try_downcast_from(obj: &PyObject, vm: &VirtualMachine) -> PyResult<()> { ... }
unsafe fn freelist_push(_obj: *mut PyObject) -> bool { ... }
unsafe fn freelist_pop(_payload: &Self) -> Option<NonNull<PyObject>> { ... }
fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef
where Self: Debug { ... }
fn _into_ref(self, cls: PyTypeRef, ctx: &Context) -> PyRef<Self>
where Self: Debug { ... }
fn into_exact_ref(self, ctx: &Context) -> PyRefExact<Self>
where Self: Debug { ... }
fn into_ref(self, ctx: &Context) -> PyRef<Self>
where Self: Debug { ... }
fn into_ref_with_type(
self,
vm: &VirtualMachine,
cls: PyTypeRef,
) -> PyResult<PyRef<Self>>
where Self: Debug { ... }
fn into_ref_with_type_lazy_dict(
self,
vm: &VirtualMachine,
cls: PyTypeRef,
) -> PyResult<PyRef<Self>>
where Self: Debug { ... }
fn into_ref_with_type_and_dict(
self,
vm: &VirtualMachine,
cls: PyTypeRef,
eager_dict: bool,
) -> PyResult<PyRef<Self>>
where Self: Debug { ... }
}Expand description
Native subclasses declared with #[pyclass(base = Base)] share the base’s
payload type ID. Their base field must start at offset zero, and their
payload must start at the same offset inside Py<T> as the base payload.
The derived object must also meet the base object’s alignment requirement.
The macro checks these conditions at compile time. repr(C) on the payload
alone does not guarantee the second condition:
use rustpython_vm::{builtins::PyDict, pyclass};
#[pyclass(module = false, name = "MisalignedDict", base = PyDict)]
#[derive(Debug)]
#[repr(C, align(64))]
struct MisalignedDict {
base: PyDict,
}
#[pyclass]
impl MisalignedDict {}An enum cannot provide the required base field layout:
use rustpython_vm::{builtins::PyDict, pyclass};
#[pyclass(module = false, name = "EnumDict", base = PyDict)]
#[derive(Debug)]
enum EnumDict {
Dict(PyDict),
Empty,
}
#[pyclass]
impl EnumDict {}Provided Associated Constants§
const PAYLOAD_TYPE_ID: TypeId = _
Sourceconst NEW_REF_UNTRACKED: bool = false
const NEW_REF_UNTRACKED: bool = false
Whether PyRef::new_ref skips auto-tracking this type in the GC even
when it would otherwise qualify (has traverse, dict, or heap type).
Such objects are created untracked and must be tracked explicitly if
and when they can become part of a reference cycle. Used by FrameObject,
which is created untracked and tracked lazily only on escape.
Sourceconst HAS_FREELIST: bool = false
const HAS_FREELIST: bool = false
Whether this type has a freelist. Types with freelists require immediate (non-deferred) GC untracking during dealloc to prevent race conditions when the object is reused.
Sourceconst MAX_FREELIST: usize = 0
const MAX_FREELIST: usize = 0
Maximum number of objects to keep in the freelist.
Required Methods§
Provided Methods§
Sourceunsafe fn validate_downcastable_from(_obj: &PyObject) -> bool
unsafe fn validate_downcastable_from(_obj: &PyObject) -> bool
§Safety
This function should only be called if payload_type_id matches the type of obj.
fn try_downcast_from(obj: &PyObject, vm: &VirtualMachine) -> PyResult<()>
Sourceunsafe fn freelist_push(_obj: *mut PyObject) -> bool
unsafe fn freelist_push(_obj: *mut PyObject) -> bool
Try to push a dead object onto this type’s freelist for reuse. Returns true if the object was stored (caller must NOT free the memory). Called after tp_clear, so the payload is a cleared husk; implementations must not rely on its pre-clear contents.
§Safety
obj must be a valid pointer to a Py<Self> with refcount 0
whose tp_clear has already run, with no outstanding borrows into the
payload (PyRef::new_ref may pop and reuse the husk immediately).
Sourceunsafe fn freelist_pop(_payload: &Self) -> Option<NonNull<PyObject>>
unsafe fn freelist_pop(_payload: &Self) -> Option<NonNull<PyObject>>
Try to pop a pre-allocated object from this type’s freelist.
The returned pointer still has the old payload; the caller must
reinitialize ref_count, gc_bits, and payload.
§Safety
The returned pointer (if Some) must point to a valid Py<Self>
whose payload is still initialized from a previous allocation. The caller
will drop and overwrite payload before reuse.
fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRefwhere
Self: Debug,
fn _into_ref(self, cls: PyTypeRef, ctx: &Context) -> PyRef<Self>where
Self: Debug,
fn into_exact_ref(self, ctx: &Context) -> PyRefExact<Self>where
Self: Debug,
fn into_ref(self, ctx: &Context) -> PyRef<Self>where
Self: Debug,
fn into_ref_with_type(
self,
vm: &VirtualMachine,
cls: PyTypeRef,
) -> PyResult<PyRef<Self>>where
Self: Debug,
Sourcefn into_ref_with_type_lazy_dict(
self,
vm: &VirtualMachine,
cls: PyTypeRef,
) -> PyResult<PyRef<Self>>where
Self: Debug,
fn into_ref_with_type_lazy_dict(
self,
vm: &VirtualMachine,
cls: PyTypeRef,
) -> PyResult<PyRef<Self>>where
Self: Debug,
Like into_ref_with_type, but leaves the instance __dict__ unallocated
until the first attribute write or __dict__ access. Only valid for types
whose attribute protocol materializes the dict lazily via get_or_insert.
fn into_ref_with_type_and_dict(
self,
vm: &VirtualMachine,
cls: PyTypeRef,
eager_dict: bool,
) -> PyResult<PyRef<Self>>where
Self: Debug,
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".