Skip to content

Commit 11e991f

Browse files
Add basic pyobject c-api functions (#7872)
1 parent ef375be commit 11e991f

1 file changed

Lines changed: 91 additions & 2 deletions

File tree

crates/capi/src/object.rs

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::PyObject;
22
use crate::pystate::with_vm;
3-
use core::ffi::{c_int, c_uint, c_ulong};
4-
use rustpython_vm::builtins::PyType;
3+
use core::ffi::{CStr, c_char, c_int, c_uint, c_ulong};
4+
use core::ptr::NonNull;
5+
use rustpython_vm::builtins::{PyStr, PyType};
56
use rustpython_vm::{AsObject, Py};
67

78
pub type PyTypeObject = Py<PyType>;
@@ -46,3 +47,91 @@ pub extern "C" fn Py_GetConstantBorrowed(constant_id: c_uint) -> *mut PyObject {
4647
Ok(constant)
4748
})
4849
}
50+
51+
#[unsafe(no_mangle)]
52+
pub unsafe extern "C" fn PyObject_GetAttr(
53+
obj: *mut PyObject,
54+
name: *mut PyObject,
55+
) -> *mut PyObject {
56+
with_vm(|vm| {
57+
let obj = unsafe { &*obj };
58+
let name = unsafe { &*name }.try_downcast_ref::<PyStr>(vm)?;
59+
obj.get_attr(name, vm)
60+
})
61+
}
62+
63+
#[unsafe(no_mangle)]
64+
pub unsafe extern "C" fn PyObject_GetAttrString(
65+
obj: *mut PyObject,
66+
attr_name: *const c_char,
67+
) -> *mut PyObject {
68+
with_vm(|vm| {
69+
let obj = unsafe { &*obj };
70+
let name = unsafe {
71+
CStr::from_ptr(attr_name)
72+
.to_str()
73+
.expect("attribute name must be valid UTF-8")
74+
};
75+
obj.get_attr(name, vm)
76+
})
77+
}
78+
79+
#[unsafe(no_mangle)]
80+
pub unsafe extern "C" fn PyObject_SetAttrString(
81+
obj: *mut PyObject,
82+
attr_name: *const c_char,
83+
value: *mut PyObject,
84+
) -> c_int {
85+
with_vm(|vm| {
86+
let obj = unsafe { &*obj };
87+
let name = unsafe { CStr::from_ptr(attr_name) }
88+
.to_str()
89+
.expect("attribute name must be valid UTF-8");
90+
let value = unsafe { &*value }.to_owned();
91+
obj.set_attr(name, value, vm)
92+
})
93+
}
94+
95+
#[unsafe(no_mangle)]
96+
pub unsafe extern "C" fn PyObject_SetAttr(
97+
obj: *mut PyObject,
98+
name: *mut PyObject,
99+
value: *mut PyObject,
100+
) -> c_int {
101+
with_vm(|vm| {
102+
let obj = unsafe { &*obj };
103+
let name = unsafe { &*name }.try_downcast_ref::<PyStr>(vm)?;
104+
let value = unsafe { &*value }.to_owned();
105+
obj.set_attr(name, value, vm)
106+
})
107+
}
108+
109+
#[unsafe(no_mangle)]
110+
pub extern "C" fn PyObject_Repr(obj: *mut PyObject) -> *mut PyObject {
111+
with_vm(|vm| {
112+
let Some(obj) = NonNull::new(obj) else {
113+
return Ok(vm.ctx.new_str("<NULL>"));
114+
};
115+
116+
unsafe { obj.as_ref() }.repr(vm)
117+
})
118+
}
119+
120+
#[unsafe(no_mangle)]
121+
pub extern "C" fn PyObject_Str(obj: *mut PyObject) -> *mut PyObject {
122+
with_vm(|vm| {
123+
let Some(obj) = NonNull::new(obj) else {
124+
return Ok(vm.ctx.new_str("<NULL>"));
125+
};
126+
127+
unsafe { obj.as_ref() }.str(vm)
128+
})
129+
}
130+
131+
#[unsafe(no_mangle)]
132+
pub unsafe extern "C" fn PyObject_IsTrue(obj: *mut PyObject) -> c_int {
133+
with_vm(|vm| {
134+
let obj = unsafe { &*obj };
135+
obj.to_owned().is_true(vm)
136+
})
137+
}

0 commit comments

Comments
 (0)