Skip to content

Commit 057010b

Browse files
committed
Add payload views and Py handle shortcuts
PyTuple::payload_slice, PyBytes::payload_bytes, and PyStr::payload_wtf8 expose the payload data. Common payload methods are forwarded from Py<T>. Assisted-by: Grok CLI:grok-4.7
1 parent 3272bee commit 057010b

8 files changed

Lines changed: 139 additions & 0 deletions

File tree

‎crates/vm/src/builtins/bytes.rs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,17 @@ impl PyBytes {
550550

551551
#[pyclass]
552552
impl Py<PyBytes> {
553+
/// Borrowed bytes of the payload.
554+
#[inline]
555+
pub fn payload_bytes(&self) -> &[u8] {
556+
self.payload().as_bytes()
557+
}
558+
559+
#[inline]
560+
pub fn as_bytes(&self) -> &[u8] {
561+
self.payload_bytes()
562+
}
563+
553564
#[pymethod]
554565
fn __reduce_ex__(
555566
&self,

‎crates/vm/src/builtins/dict.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,16 @@ impl Representable for PyDict {
750750
}
751751

752752
impl Py<PyDict> {
753+
#[inline]
754+
pub fn is_empty(&self) -> bool {
755+
self.payload().is_empty()
756+
}
757+
758+
#[inline]
759+
pub fn size(&self) -> dict_inner::DictSize {
760+
self.payload().size()
761+
}
762+
753763
#[inline]
754764
fn exact_dict(&self, vm: &VirtualMachine) -> bool {
755765
self.class().is(vm.ctx.types.dict_type)

‎crates/vm/src/builtins/float.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ impl PyFloat {
3535
}
3636
}
3737

38+
impl Py<PyFloat> {
39+
#[inline]
40+
pub fn to_f64(&self) -> f64 {
41+
self.payload().to_f64()
42+
}
43+
}
44+
3845
thread_local! {
3946
static FLOAT_FREELIST: Cell<crate::object::FreeList<PyFloat>> = const { Cell::new(crate::object::FreeList::new()) };
4047
}

‎crates/vm/src/builtins/int.rs‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,21 @@ impl AsNumber for PyInt {
747747
}
748748
}
749749

750+
impl Py<PyInt> {
751+
#[inline]
752+
pub fn as_bigint(&self) -> &BigInt {
753+
self.payload().as_bigint()
754+
}
755+
756+
#[inline]
757+
pub fn try_to_primitive<'a, I>(&'a self, vm: &VirtualMachine) -> PyResult<I>
758+
where
759+
I: PrimInt + TryFrom<&'a BigInt>,
760+
{
761+
self.payload().try_to_primitive(vm)
762+
}
763+
}
764+
750765
impl PyInt {
751766
pub(super) const AS_NUMBER: PyNumberMethods = PyNumberMethods {
752767
add: Some(|a, b, vm| Self::number_op(a, b, |a, b, _vm| a + b, vm)),

‎crates/vm/src/builtins/list.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,18 @@ impl ToPyObject for Vec<PyObjectRef> {
128128
}
129129
}
130130

131+
impl Py<PyList> {
132+
#[inline]
133+
pub fn borrow_vec(&self) -> PyMappedRwLockReadGuard<'_, [PyObjectRef]> {
134+
self.payload().borrow_vec()
135+
}
136+
137+
#[inline]
138+
pub fn borrow_vec_mut(&self) -> PyRwLockWriteGuard<'_, Vec<PyObjectRef>> {
139+
self.payload().borrow_vec_mut()
140+
}
141+
}
142+
131143
impl PyList {
132144
#[deprecated(note = "use PyList::from(...).into_ref() instead")]
133145
pub fn new_ref(elements: Vec<PyObjectRef>, ctx: &Context) -> PyRef<Self> {

‎crates/vm/src/builtins/str.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,37 @@ impl PyStr {
629629
}
630630

631631
impl Py<PyStr> {
632+
/// Borrowed text of the payload.
633+
#[inline]
634+
pub fn payload_wtf8(&self) -> &Wtf8 {
635+
self.payload().as_wtf8()
636+
}
637+
638+
#[inline]
639+
pub fn as_wtf8(&self) -> &Wtf8 {
640+
self.payload_wtf8()
641+
}
642+
643+
#[inline]
644+
pub fn as_bytes(&self) -> &[u8] {
645+
self.payload_wtf8().as_bytes()
646+
}
647+
648+
#[inline]
649+
pub fn to_str(&self) -> Option<&str> {
650+
self.payload().to_str()
651+
}
652+
653+
#[inline]
654+
pub fn byte_len(&self) -> usize {
655+
self.payload().byte_len()
656+
}
657+
658+
#[inline]
659+
pub fn char_len(&self) -> usize {
660+
self.payload().char_len()
661+
}
662+
632663
pub fn as_utf8(&self) -> Option<&Py<PyUtf8Str>> {
633664
if self.is_utf8() {
634665
// SAFETY: is_utf8() guarantees the PyUtf8Str invariant.

‎crates/vm/src/builtins/tuple.rs‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,35 @@ impl PyTuple<PyObjectRef> {
386386
}
387387
}
388388

389+
impl<R> Py<PyTuple<R>> {
390+
/// Element slice of the tuple payload.
391+
#[inline]
392+
pub fn payload_slice(&self) -> &[R] {
393+
(&*self).as_slice()
394+
}
395+
}
396+
389397
impl Py<PyTuple> {
398+
#[inline]
399+
pub fn as_slice(&self) -> &[PyObjectRef] {
400+
self.payload_slice()
401+
}
402+
403+
#[inline]
404+
pub fn len(&self) -> usize {
405+
self.payload_slice().len()
406+
}
407+
408+
#[inline]
409+
pub fn is_empty(&self) -> bool {
410+
self.payload_slice().is_empty()
411+
}
412+
413+
#[inline]
414+
pub fn iter(&self) -> core::slice::Iter<'_, PyObjectRef> {
415+
self.payload_slice().iter()
416+
}
417+
390418
pub fn extract_tuple<'a, T: FromPyTuple<'a>>(&'a self, vm: &VirtualMachine) -> PyResult<T> {
391419
T::from_pytuple(self, vm)
392420
}

‎crates/vm/src/builtins/type.rs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,31 @@ impl PyType {
16511651
}
16521652

16531653
impl Py<PyType> {
1654+
#[inline]
1655+
pub fn name(&self) -> BorrowedValue<'_, str> {
1656+
self.payload().name()
1657+
}
1658+
1659+
#[inline]
1660+
pub fn slot_name(&self) -> BorrowedValue<'_, str> {
1661+
self.payload().slot_name()
1662+
}
1663+
1664+
#[inline]
1665+
pub fn set_attr(&self, attr_name: &'static PyStrInterned, value: PyObjectRef) {
1666+
self.payload().set_attr(attr_name, value)
1667+
}
1668+
1669+
#[inline]
1670+
pub fn get_attr(&self, attr_name: &'static PyStrInterned) -> Option<PyObjectRef> {
1671+
self.payload().get_attr(attr_name)
1672+
}
1673+
1674+
#[inline]
1675+
pub fn get_direct_attr(&self, attr_name: &'static PyStrInterned) -> Option<PyObjectRef> {
1676+
self.payload().get_direct_attr(attr_name)
1677+
}
1678+
16541679
pub fn is_subtype(&self, other: &Self) -> bool {
16551680
is_subtype_with_mro(&self.mro.read(), self, other)
16561681
}

0 commit comments

Comments
 (0)