Skip to content

Commit 859516c

Browse files
Add more dict functions to c-api (#8269)
* Add more dict functions to c-api * Review
1 parent 4a4cef6 commit 859516c

1 file changed

Lines changed: 111 additions & 1 deletion

File tree

crates/capi/src/dictobject.rs

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::PyObject;
22
use crate::object::define_py_check;
33
use crate::pystate::with_vm;
4-
use core::ffi::c_int;
4+
use core::ffi::{CStr, c_char, c_int};
55
use core::ptr::NonNull;
66
use rustpython_vm::AsObject;
77
use rustpython_vm::PyPayload;
@@ -18,6 +18,15 @@ pub extern "C" fn PyDict_New() -> *mut PyObject {
1818
with_vm(|vm| vm.ctx.new_dict())
1919
}
2020

21+
#[unsafe(no_mangle)]
22+
pub unsafe extern "C" fn PyDict_Clear(dict: *mut PyObject) {
23+
with_vm(|vm| {
24+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
25+
dict.clear();
26+
Ok(())
27+
})
28+
}
29+
2130
#[unsafe(no_mangle)]
2231
pub unsafe extern "C" fn PyDict_SetItem(
2332
dict: *mut PyObject,
@@ -32,6 +41,96 @@ pub unsafe extern "C" fn PyDict_SetItem(
3241
})
3342
}
3443

44+
#[unsafe(no_mangle)]
45+
pub unsafe extern "C" fn PyDict_SetItemString(
46+
dict: *mut PyObject,
47+
key: *const c_char,
48+
val: *mut PyObject,
49+
) -> c_int {
50+
with_vm(|vm| {
51+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
52+
let key = unsafe { CStr::from_ptr(key) }
53+
.to_str()
54+
.map_err(|_| vm.new_value_error("dictionary key must be valid UTF-8"))?;
55+
let value = unsafe { &*val }.to_owned();
56+
dict.inner_setitem(key, value, vm)
57+
})
58+
}
59+
60+
#[unsafe(no_mangle)]
61+
pub unsafe extern "C" fn PyDict_GetItem(dict: *mut PyObject, key: *mut PyObject) -> *mut PyObject {
62+
with_vm(|vm| {
63+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
64+
let key = unsafe { &*key };
65+
66+
match dict.inner_getitem_opt(key, vm) {
67+
Ok(Some(value)) => Ok(value.as_object().as_raw().cast_mut()),
68+
Ok(None) | Err(_) => Ok(core::ptr::null_mut()),
69+
}
70+
})
71+
}
72+
73+
#[unsafe(no_mangle)]
74+
pub unsafe extern "C" fn PyDict_GetItemWithError(
75+
dict: *mut PyObject,
76+
key: *mut PyObject,
77+
) -> *mut PyObject {
78+
with_vm(|vm| {
79+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
80+
let key = unsafe { &*key };
81+
82+
if let Some(value) = dict.inner_getitem_opt(key, vm)? {
83+
Ok(value.as_object().as_raw().cast_mut())
84+
} else {
85+
Ok(core::ptr::null_mut())
86+
}
87+
})
88+
}
89+
90+
#[unsafe(no_mangle)]
91+
pub unsafe extern "C" fn PyDict_GetItemString(
92+
dict: *mut PyObject,
93+
key: *const c_char,
94+
) -> *mut PyObject {
95+
with_vm(|vm| {
96+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
97+
let key = unsafe { CStr::from_ptr(key) }
98+
.to_str()
99+
.map_err(|_| vm.new_unicode_decode_error("dictionary key must be valid UTF-8"))?;
100+
101+
match dict.inner_getitem_opt(key, vm)? {
102+
Some(value) => Ok(value.as_object().as_raw().cast_mut()),
103+
None => Ok(core::ptr::null_mut()),
104+
}
105+
})
106+
}
107+
108+
#[unsafe(no_mangle)]
109+
pub unsafe extern "C" fn PyDict_GetItemStringRef(
110+
dict: *mut PyObject,
111+
key: *const c_char,
112+
result: *mut *mut PyObject,
113+
) -> c_int {
114+
with_vm(|vm| {
115+
unsafe {
116+
*result = core::ptr::null_mut();
117+
}
118+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
119+
let key = unsafe { CStr::from_ptr(key) }
120+
.to_str()
121+
.map_err(|_| vm.new_value_error("dictionary key must be valid UTF-8"))?;
122+
123+
if let Some(value) = dict.inner_getitem_opt(key, vm)? {
124+
unsafe {
125+
*result = value.into_raw().as_ptr();
126+
}
127+
Ok(true)
128+
} else {
129+
Ok(false)
130+
}
131+
})
132+
}
133+
35134
#[unsafe(no_mangle)]
36135
pub unsafe extern "C" fn PyDict_GetItemRef(
37136
dict: *mut PyObject,
@@ -128,6 +227,17 @@ pub unsafe extern "C" fn PyDict_DelItem(dict: *mut PyObject, key: *mut PyObject)
128227
})
129228
}
130229

230+
#[unsafe(no_mangle)]
231+
pub unsafe extern "C" fn PyDict_DelItemString(dict: *mut PyObject, key: *const c_char) -> c_int {
232+
with_vm(|vm| {
233+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
234+
let key = unsafe { CStr::from_ptr(key) }
235+
.to_str()
236+
.map_err(|_| vm.new_value_error("dictionary key must be valid UTF-8"))?;
237+
dict.del_item(key, vm)
238+
})
239+
}
240+
131241
#[unsafe(no_mangle)]
132242
pub unsafe extern "C" fn PyDict_Items(dict: *mut PyObject) -> *mut PyObject {
133243
with_vm(|vm| {

0 commit comments

Comments
 (0)