Add basic pyobject c-api functions (#7872)

This commit is contained in:
Bas Schoenmaeckers
2026-05-14 06:13:41 +02:00
committed by GitHub
parent ef375bec26
commit 11e991fb95

View File

@@ -1,7 +1,8 @@
use crate::PyObject;
use crate::pystate::with_vm;
use core::ffi::{c_int, c_uint, c_ulong};
use rustpython_vm::builtins::PyType;
use core::ffi::{CStr, c_char, c_int, c_uint, c_ulong};
use core::ptr::NonNull;
use rustpython_vm::builtins::{PyStr, PyType};
use rustpython_vm::{AsObject, Py};
pub type PyTypeObject = Py<PyType>;
@@ -46,3 +47,91 @@ pub extern "C" fn Py_GetConstantBorrowed(constant_id: c_uint) -> *mut PyObject {
Ok(constant)
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyObject_GetAttr(
obj: *mut PyObject,
name: *mut PyObject,
) -> *mut PyObject {
with_vm(|vm| {
let obj = unsafe { &*obj };
let name = unsafe { &*name }.try_downcast_ref::<PyStr>(vm)?;
obj.get_attr(name, vm)
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyObject_GetAttrString(
obj: *mut PyObject,
attr_name: *const c_char,
) -> *mut PyObject {
with_vm(|vm| {
let obj = unsafe { &*obj };
let name = unsafe {
CStr::from_ptr(attr_name)
.to_str()
.expect("attribute name must be valid UTF-8")
};
obj.get_attr(name, vm)
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyObject_SetAttrString(
obj: *mut PyObject,
attr_name: *const c_char,
value: *mut PyObject,
) -> c_int {
with_vm(|vm| {
let obj = unsafe { &*obj };
let name = unsafe { CStr::from_ptr(attr_name) }
.to_str()
.expect("attribute name must be valid UTF-8");
let value = unsafe { &*value }.to_owned();
obj.set_attr(name, value, vm)
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyObject_SetAttr(
obj: *mut PyObject,
name: *mut PyObject,
value: *mut PyObject,
) -> c_int {
with_vm(|vm| {
let obj = unsafe { &*obj };
let name = unsafe { &*name }.try_downcast_ref::<PyStr>(vm)?;
let value = unsafe { &*value }.to_owned();
obj.set_attr(name, value, vm)
})
}
#[unsafe(no_mangle)]
pub extern "C" fn PyObject_Repr(obj: *mut PyObject) -> *mut PyObject {
with_vm(|vm| {
let Some(obj) = NonNull::new(obj) else {
return Ok(vm.ctx.new_str("<NULL>"));
};
unsafe { obj.as_ref() }.repr(vm)
})
}
#[unsafe(no_mangle)]
pub extern "C" fn PyObject_Str(obj: *mut PyObject) -> *mut PyObject {
with_vm(|vm| {
let Some(obj) = NonNull::new(obj) else {
return Ok(vm.ctx.new_str("<NULL>"));
};
unsafe { obj.as_ref() }.str(vm)
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyObject_IsTrue(obj: *mut PyObject) -> c_int {
with_vm(|vm| {
let obj = unsafe { &*obj };
obj.to_owned().is_true(vm)
})
}