Add more dict functions to c-api by bschoenmaeckers · Pull Request #8043 · RustPython/RustPython
define_py_check!(fn PyDict_Check, types.dict_type);
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Contains(dict: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; let key = unsafe { &*key }; Ok(dict.inner_getitem_opt(key, vm)?.is_some()) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Copy(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; Ok(dict.copy().into_ref(&vm.ctx)) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_DelItem(dict: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; let key = unsafe { &*key }; dict.del_item(key, vm) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Items(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; let items = dict .items_vec() .into_iter() .map(|(k, v)| vm.ctx.new_tuple(vec![k, v]).into()) .collect(); Ok(vm.ctx.new_list(items)) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Keys(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; Ok(vm.ctx.new_list(dict.keys_vec())) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Values(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; Ok(vm.ctx.new_list(dict.values_vec())) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Merge( dict: *mut PyObject, other: *mut PyObject, override_: c_int, ) -> c_int { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; let other = unsafe { &*other }.to_owned(); if override_ != 0 { dict.merge_object(other, vm) } else { dict.merge_object_if_missing(other, vm) } }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Update(dict: *mut PyObject, other: *mut PyObject) -> c_int { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; let other = unsafe { &*other }.to_owned(); dict.merge_object(other, vm) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_MergeFromSeq2( dict: *mut PyObject, seq2: *mut PyObject, override_: c_int, ) -> c_int { with_vm(|vm| { let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?; let seq2 = unsafe { &*seq2 }.to_owned(); dict.merge_from_seq2(seq2, override_ != 0, vm) }) }
#[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Next( dict: *mut PyObject,
#[test] fn test_create_empty_dict() {
#[test] fn dict_contains() { Python::attach(|py| { let dict = [(1, 2)].into_py_dict(py).unwrap(); assert!(dict.contains(1).unwrap()); assert!(!dict.contains(3).unwrap()); }) }
#[test] fn dict_copy_and_del_item() { Python::attach(|py| { let dict = [(1, 2), (3, 4)].into_py_dict(py).unwrap(); let copied = dict.copy().unwrap(); assert_eq!(copied.len(), 2); copied.del_item(1).unwrap(); assert!(!copied.contains(1).unwrap()); }) }
#[test] fn dict_keys_values_items() { Python::attach(|py| { let dict = [(1, 2), (3, 4)].into_py_dict(py).unwrap(); assert_eq!(dict.keys().len(), 2); assert_eq!(dict.values().len(), 2); assert_eq!(dict.items().len(), 2); }) }
#[test] fn dict_update_and_merge() { Python::attach(|py| { let dict = [(1, 10)].into_py_dict(py).unwrap(); let replacement = [(1, 20), (2, 30)].into_py_dict(py).unwrap(); dict.update(replacement.as_mapping()).unwrap(); assert_eq!( dict.get_item(1).unwrap().unwrap().extract::<i32>().unwrap(), 20 ); assert_eq!( dict.get_item(2).unwrap().unwrap().extract::<i32>().unwrap(), 30 );
let merged_missing = [(1, 99), (3, 40)].into_py_dict(py).unwrap(); dict.update_if_missing(merged_missing.as_mapping()).unwrap(); assert_eq!( dict.get_item(1).unwrap().unwrap().extract::<i32>().unwrap(), 20 ); assert_eq!( dict.get_item(3).unwrap().unwrap().extract::<i32>().unwrap(), 40 ); }) }
#[test] fn dict_merge_from_seq2() { Python::attach(|py| { let seq = PyList::new(py, [(1, 10), (1, 20), (2, 30)]).unwrap(); let dict = PyDict::from_sequence(seq.as_any()).unwrap(); assert_eq!( dict.get_item(1).unwrap().unwrap().extract::<i32>().unwrap(), 20 ); assert_eq!( dict.get_item(2).unwrap().unwrap().extract::<i32>().unwrap(), 30 ); }) } }