pub struct PyStackRef { /* private fields */ }Expand description
A tagged stack reference to a Python object.
Uses the lowest bit of the pointer to distinguish owned vs borrowed:
- bit 0 = 0 → owned: refcount was incremented; Drop will decrement.
- bit 0 = 1 → borrowed: no refcount change; Drop is a no-op.
Same size as PyObjectRef (one pointer-width). PyObject is at least
8-byte aligned, so the low bit is always available for tagging.
Uses NonZeroUsize so that Option<PyStackRef> has the same size as
PyStackRef via niche optimization (matching Option<PyObjectRef>).
Implementations§
Source§impl PyStackRef
impl PyStackRef
Sourcepub fn new_owned(obj: PyObjectRef) -> Self
pub fn new_owned(obj: PyObjectRef) -> Self
Create an owned stack reference, consuming the PyObjectRef.
Refcount is NOT incremented — ownership is transferred.
Sourcepub unsafe fn new_borrowed(obj: &PyObject) -> Self
pub unsafe fn new_borrowed(obj: &PyObject) -> Self
Create a borrowed stack reference from a &PyObject.
§Safety
The caller must guarantee that the pointed-to object lives at least as
long as this PyStackRef. In practice the compiler guarantees that
borrowed refs are consumed within the same basic block, before any
STORE_FAST/DELETE_FAST could overwrite the source slot.
Sourcepub fn is_borrowed(&self) -> bool
pub fn is_borrowed(&self) -> bool
Whether this is a borrowed (non-owning) reference.
Sourcepub fn as_object(&self) -> &PyObject
pub fn as_object(&self) -> &PyObject
Get a &PyObject reference. Works for both owned and borrowed.
Sourcepub fn to_pyobj(self) -> PyObjectRef
pub fn to_pyobj(self) -> PyObjectRef
Convert to an owned PyObjectRef.
- If borrowed → increments refcount, forgets self.
- If owned → reconstructs
PyObjectReffrom the raw pointer, forgets self.
Methods from Deref<Target = PyObject>§
pub fn try_to_value<'a, T>(&'a self, vm: &VirtualMachine) -> PyResult<T>where
T: 'a + TryFromBorrowedObject<'a>,
pub fn try_to_ref<'a, T>(&'a self, vm: &VirtualMachine) -> PyResult<&'a Py<T>>where
T: 'a + PyPayload,
pub fn try_value_with<T, F, R>(&self, f: F, vm: &VirtualMachine) -> PyResult<R>
pub fn try_bytes_like<R>( &self, vm: &VirtualMachine, f: impl FnOnce(&[u8]) -> R, ) -> PyResult<R>
pub fn try_rw_bytes_like<R>( &self, vm: &VirtualMachine, f: impl FnOnce(&mut [u8]) -> R, ) -> PyResult<R>
pub fn as_interned_str( &self, vm: &VirtualMachine, ) -> Option<&'static PyStrInterned>
Sourcepub fn try_to_owned(&self) -> Option<PyObjectRef>
pub fn try_to_owned(&self) -> Option<PyObjectRef>
Atomically try to create a strong reference.
Returns None if the strong count is already 0 (object being destroyed).
Uses CAS to prevent the TOCTOU race between checking strong_count and
incrementing it.
pub fn downgrade( &self, callback: Option<PyObjectRef>, vm: &VirtualMachine, ) -> PyResult<PyRef<PyWeak>>
pub fn get_weak_references(&self) -> Option<Vec<PyRef<PyWeak>>>
pub fn payload_is<T: PyPayload>(&self) -> bool
use downcastable instead
Sourcepub unsafe fn payload_unchecked<T: PyPayload>(&self) -> &T
👎Deprecated: use downcast_unchecked_ref instead
pub unsafe fn payload_unchecked<T: PyPayload>(&self) -> &T
use downcast_unchecked_ref instead
pub fn payload<T: PyPayload>(&self) -> Option<&T>
use downcast_ref instead
pub fn class(&self) -> &Py<PyType>
pub fn set_class(&self, typ: PyTypeRef, vm: &VirtualMachine)
pub fn payload_if_exact<T: PyPayload>(&self, vm: &VirtualMachine) -> Option<&T>
use downcast_ref_if_exact instead
pub fn dict(&self) -> Option<PyDictRef>
Sourcepub fn set_dict(&self, dict: PyDictRef) -> Result<(), PyDictRef>
pub fn set_dict(&self, dict: PyDictRef) -> Result<(), PyDictRef>
Set the dict field. Returns Err(dict) if this object does not have a dict field
in the first place.
pub fn payload_if_subclass<T: PyPayload>( &self, vm: &VirtualMachine, ) -> Option<&T>
use downcast_ref instead
Sourcepub fn downcastable<T: PyPayload>(&self) -> bool
pub fn downcastable<T: PyPayload>(&self) -> bool
Check if this object can be downcast to T.
Sourcepub fn try_downcast_ref<'a, T: PyPayload>(
&'a self,
vm: &VirtualMachine,
) -> PyResult<&'a Py<T>>
pub fn try_downcast_ref<'a, T: PyPayload>( &'a self, vm: &VirtualMachine, ) -> PyResult<&'a Py<T>>
Attempt to downcast this reference to a subclass.
Sourcepub fn downcast_ref<T: PyPayload>(&self) -> Option<&Py<T>>
pub fn downcast_ref<T: PyPayload>(&self) -> Option<&Py<T>>
Attempt to downcast this reference to a subclass.
pub fn downcast_ref_if_exact<T: PyPayload>( &self, vm: &VirtualMachine, ) -> Option<&Py<T>>
Sourcepub unsafe fn downcast_unchecked_ref<T: PyPayload>(&self) -> &Py<T>
pub unsafe fn downcast_unchecked_ref<T: PyPayload>(&self) -> &Py<T>
§Safety
T must be the exact payload type
pub fn strong_count(&self) -> usize
pub fn weak_count(&self) -> Option<usize>
pub fn as_raw(&self) -> *const Self
Sourcepub fn is_gc_tracked(&self) -> bool
pub fn is_gc_tracked(&self) -> bool
_PyObject_GC_IS_TRACKED
Sourcepub fn gc_get_referents(&self) -> Vec<PyObjectRef>
pub fn gc_get_referents(&self) -> Vec<PyObjectRef>
Get the referents (objects directly referenced) of this object. Uses the full traverse including dict and slots.
Sourcepub fn try_call_finalizer(&self)
pub fn try_call_finalizer(&self)
Call del if present, without triggering object deallocation. Used by GC to call finalizers before breaking cycles. This allows proper resurrection detection. PyObject_CallFinalizerFromDealloc
Sourcepub fn gc_clear_weakrefs_collect_callbacks(
&self,
) -> Vec<(PyRef<PyWeak>, PyObjectRef)>
pub fn gc_clear_weakrefs_collect_callbacks( &self, ) -> Vec<(PyRef<PyWeak>, PyObjectRef)>
Clear weakrefs but collect callbacks instead of calling them.
This is used by GC to ensure ALL weakrefs are cleared BEFORE any callbacks run.
Returns collected callbacks as (PyRef
Sourcepub unsafe fn gc_get_referent_ptrs(&self) -> Vec<NonNull<PyObject>>
pub unsafe fn gc_get_referent_ptrs(&self) -> Vec<NonNull<PyObject>>
Get raw pointers to referents without incrementing reference counts. This is used during GC to avoid reference count manipulation. tp_traverse visits objects without incref
§Safety
The returned pointers are only valid as long as the object is alive and its contents haven’t been modified.
Sourcepub unsafe fn gc_clear(&self) -> Vec<PyObjectRef>
pub unsafe fn gc_clear(&self) -> Vec<PyObjectRef>
Clear this object for cycle breaking (tp_clear). This version takes &self but should only be called during GC when exclusive access is guaranteed.
§Safety
- The caller must guarantee exclusive access (no other references exist)
- This is only safe during GC when the object is unreachable
Sourcepub fn gc_has_clear(&self) -> bool
pub fn gc_has_clear(&self) -> bool
Check if this object has clear capability (tp_clear)
pub fn to_callable(&self) -> Option<PyCallable<'_>>
pub fn is_callable(&self) -> bool
Sourcepub fn call(&self, args: impl IntoFuncArgs, vm: &VirtualMachine) -> PyResult
pub fn call(&self, args: impl IntoFuncArgs, vm: &VirtualMachine) -> PyResult
PyObject_CallArg series
Sourcepub fn call_with_args(&self, args: FuncArgs, vm: &VirtualMachine) -> PyResult
pub fn call_with_args(&self, args: FuncArgs, vm: &VirtualMachine) -> PyResult
PyObject_Call
Sourcepub fn vectorcall(
&self,
args: Vec<PyObjectRef>,
nargs: usize,
kwnames: Option<&[PyObjectRef]>,
vm: &VirtualMachine,
) -> PyResult
pub fn vectorcall( &self, args: Vec<PyObjectRef>, nargs: usize, kwnames: Option<&[PyObjectRef]>, vm: &VirtualMachine, ) -> PyResult
Vectorcall: call with owned positional args + optional kwnames. Falls back to FuncArgs-based call if no vectorcall slot.
pub fn mapping_unchecked(&self) -> PyMapping<'_>
pub fn try_mapping(&self, vm: &VirtualMachine) -> PyResult<PyMapping<'_>>
pub fn number(&self) -> PyNumber<'_>
pub fn try_index_opt(&self, vm: &VirtualMachine) -> Option<PyResult<PyIntRef>>
pub fn try_index(&self, vm: &VirtualMachine) -> PyResult<PyIntRef>
pub fn try_int(&self, vm: &VirtualMachine) -> PyResult<PyIntRef>
pub fn try_float_opt( &self, vm: &VirtualMachine, ) -> Option<PyResult<PyRef<PyFloat>>>
pub fn try_float(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyFloat>>
Sourcepub fn get_iter(&self, vm: &VirtualMachine) -> PyResult<PyIter>
pub fn get_iter(&self, vm: &VirtualMachine) -> PyResult<PyIter>
Takes an object and returns an iterator for it. This is typically a new iterator but if the argument is an iterator, this returns itself.
pub fn get_aiter(&self, vm: &VirtualMachine) -> PyResult
pub fn has_attr<'a>( &self, attr_name: impl AsPyStr<'a>, vm: &VirtualMachine, ) -> PyResult<bool>
Sourcepub fn get_attr<'a>(
&self,
attr_name: impl AsPyStr<'a>,
vm: &VirtualMachine,
) -> PyResult
pub fn get_attr<'a>( &self, attr_name: impl AsPyStr<'a>, vm: &VirtualMachine, ) -> PyResult
Get an attribute by name.
attr_name can be a &str, String, or PyStrRef.
pub fn call_set_attr( &self, vm: &VirtualMachine, attr_name: &Py<PyStr>, attr_value: PySetterValue, ) -> PyResult<()>
pub fn set_attr<'a>( &self, attr_name: impl AsPyStr<'a>, attr_value: impl Into<PyObjectRef>, vm: &VirtualMachine, ) -> PyResult<()>
pub fn generic_setattr( &self, attr_name: &Py<PyStr>, value: PySetterValue, vm: &VirtualMachine, ) -> PyResult<()>
pub fn generic_getattr(&self, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult
Sourcepub fn generic_getattr_opt(
&self,
name_str: &Py<PyStr>,
dict: Option<PyDictRef>,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>>
pub fn generic_getattr_opt( &self, name_str: &Py<PyStr>, dict: Option<PyDictRef>, vm: &VirtualMachine, ) -> PyResult<Option<PyObjectRef>>
CPython _PyObject_GenericGetAttrWithDict
pub fn del_attr<'a>( &self, attr_name: impl AsPyStr<'a>, vm: &VirtualMachine, ) -> PyResult<()>
pub fn rich_compare_bool( &self, other: &Self, op_id: PyComparisonOp, vm: &VirtualMachine, ) -> PyResult<bool>
pub fn repr_utf8(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyUtf8Str>>
pub fn repr(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>>
pub fn ascii(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>>
pub fn str_utf8(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyUtf8Str>>
pub fn str(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>>
Sourcepub fn real_is_subclass(
&self,
cls: &Self,
vm: &VirtualMachine,
) -> PyResult<bool>
pub fn real_is_subclass( &self, cls: &Self, vm: &VirtualMachine, ) -> PyResult<bool>
Real issubclass check without going through subclasscheck This is equivalent to CPython’s _PyObject_RealIsSubclass which just calls recursive_issubclass
Sourcepub fn is_subclass(&self, cls: &Self, vm: &VirtualMachine) -> PyResult<bool>
pub fn is_subclass(&self, cls: &Self, vm: &VirtualMachine) -> PyResult<bool>
Determines if self is a subclass of cls, either directly, indirectly or virtually
via the subclasscheck magic method.
PyObject_IsSubclass/object_issubclass
Sourcepub fn is_instance(&self, cls: &Self, vm: &VirtualMachine) -> PyResult<bool>
pub fn is_instance(&self, cls: &Self, vm: &VirtualMachine) -> PyResult<bool>
Determines if self is an instance of cls, either directly, indirectly or virtually via
the instancecheck magic method.
pub fn hash(&self, vm: &VirtualMachine) -> PyResult<PyHash>
pub fn obj_type(&self) -> PyObjectRef
pub fn type_check(&self, typ: &Py<PyType>) -> bool
pub fn length_opt(&self, vm: &VirtualMachine) -> Option<PyResult<usize>>
pub fn length(&self, vm: &VirtualMachine) -> PyResult<usize>
pub fn get_item<K: DictKey + ?Sized>( &self, needle: &K, vm: &VirtualMachine, ) -> PyResult
pub fn set_item<K: DictKey + ?Sized>( &self, needle: &K, value: PyObjectRef, vm: &VirtualMachine, ) -> PyResult<()>
pub fn del_item<K: DictKey + ?Sized>( &self, needle: &K, vm: &VirtualMachine, ) -> PyResult<()>
Sourcepub fn lookup_special(
&self,
attr: &Py<PyStr>,
vm: &VirtualMachine,
) -> Option<PyObjectRef>
pub fn lookup_special( &self, attr: &Py<PyStr>, vm: &VirtualMachine, ) -> Option<PyObjectRef>
Equivalent to CPython’s _PyObject_LookupSpecial Looks up a special method in the type’s MRO without checking instance dict. Returns None if not found (masking AttributeError like CPython).
pub fn sequence_unchecked(&self) -> PySequence<'_>
pub fn try_sequence(&self, vm: &VirtualMachine) -> PyResult<PySequence<'_>>
Trait Implementations§
Source§impl Clone for PyStackRef
impl Clone for PyStackRef
Source§impl Debug for PyStackRef
impl Debug for PyStackRef
Source§impl Deref for PyStackRef
impl Deref for PyStackRef
Source§impl Drop for PyStackRef
impl Drop for PyStackRef
Source§impl Traverse for PyStackRef
impl Traverse for PyStackRef
Source§fn traverse(&self, traverse_fn: &mut TraverseFn<'_>)
fn traverse(&self, traverse_fn: &mut TraverseFn<'_>)
traverse() with caution! Following those guideline so traverse doesn’t cause memory error!: Read moreSource§fn clear(&mut self, _out: &mut Vec<PyObjectRef>)
fn clear(&mut self, _out: &mut Vec<PyObjectRef>)
Auto Trait Implementations§
impl Freeze for PyStackRef
impl RefUnwindSafe for PyStackRef
impl Send for PyStackRef
impl Sync for PyStackRef
impl Unpin for PyStackRef
impl UnsafeUnpin for PyStackRef
impl UnwindSafe for PyStackRef
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more