From 091172f00ce0ba8ef2b495eed5e5aa07adc749da Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Mon, 11 May 2026 13:23:49 +0200 Subject: [PATCH] Add macro for type check function in c-api --- crates/capi/src/object.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/crates/capi/src/object.rs b/crates/capi/src/object.rs index fb8fc3de54..3cfa461762 100644 --- a/crates/capi/src/object.rs +++ b/crates/capi/src/object.rs @@ -6,6 +6,35 @@ use rustpython_vm::{AsObject, Py}; pub type PyTypeObject = Py; +macro_rules! define_py_check { + ($name:ident, $($ctx_path:ident).+) => { + #[unsafe(no_mangle)] + pub unsafe extern "C" fn $name(obj: *mut crate::PyObject) -> core::ffi::c_int { + crate::pystate::with_vm(|vm| unsafe { + obj + .as_ref() + .map(|obj| obj.class().is_subtype(vm.ctx.$($ctx_path).+)) + .unwrap_or_default() + }) + } + }; + (exact $name:ident, $($ctx_path:ident).+) => { + #[unsafe(no_mangle)] + pub unsafe extern "C" fn $name(obj: *mut crate::PyObject) -> core::ffi::c_int { + use rustpython_vm::AsObject; + crate::pystate::with_vm(|vm| unsafe { + obj + .as_ref() + .map(|obj| obj.class().is(vm.ctx.$($ctx_path).+)) + .unwrap_or_default() + }) + } + }; +} + +define_py_check!(PyType_Check, types.type_type); +define_py_check!(exact PyType_CheckExact, types.type_type); + #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_TYPE(op: *mut PyObject) -> *const PyTypeObject { unsafe { (*op).class() } @@ -26,6 +55,15 @@ pub unsafe extern "C" fn PyType_GetFlags(ptr: *const PyTypeObject) -> c_ulong { ty.slots.flags.bits() as u32 as c_ulong } +#[unsafe(no_mangle)] +pub unsafe extern "C" fn PyType_IsSubtype(a: *const PyTypeObject, b: *const PyTypeObject) -> c_int { + with_vm(move |_vm| { + let a = unsafe { &*a }; + let b = unsafe { &*b }; + Ok(a.is_subtype(b)) + }) +} + #[unsafe(no_mangle)] pub extern "C" fn Py_GetConstantBorrowed(constant_id: c_uint) -> *mut PyObject { with_vm(|vm| {