Skip to content

Commit d973e6d

Browse files
committed
Apply copilot review
1 parent 3f1d39e commit d973e6d

File tree

1 file changed

+28
-18
lines changed

1 file changed

+28
-18
lines changed

vm/src/frame.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,19 +1541,11 @@ impl ExecutingFrame<'_> {
15411541
let map_obj = vm.ctx.new_dict();
15421542
for obj in self.pop_multiple(size) {
15431543
// Use keys() method for all mapping objects to preserve order
1544-
let Some(keys_method) = vm.get_method(obj.clone(), vm.ctx.intern_str("keys")) else {
1545-
return Err(
1546-
vm.new_type_error(format!("'{}' object is not a mapping", obj.class().name()))
1547-
);
1548-
};
1549-
1550-
let keys = keys_method?.call((), vm)?.get_iter(vm)?;
1551-
while let PyIterReturn::Return(key) = keys.next(vm)? {
1544+
Self::iterate_mapping_keys(vm, &obj, "keyword argument", |key| {
15521545
// Check for keyword argument restrictions
15531546
if key.downcast_ref::<PyStr>().is_none() {
15541547
return Err(vm.new_type_error("keywords must be strings".to_owned()));
15551548
}
1556-
15571549
if map_obj.contains_key(&*key, vm) {
15581550
let key_repr = &key.repr(vm)?;
15591551
let msg = format!(
@@ -1565,7 +1557,8 @@ impl ExecutingFrame<'_> {
15651557

15661558
let value = obj.get_item(&*key, vm)?;
15671559
map_obj.set_item(&*key, value, vm)?;
1568-
}
1560+
Ok(())
1561+
})?;
15691562
}
15701563

15711564
self.push_value(map_obj.into());
@@ -1614,19 +1607,14 @@ impl ExecutingFrame<'_> {
16141607
let mut kwargs = IndexMap::new();
16151608

16161609
// Use keys() method for all mapping objects to preserve order
1617-
let Some(keys_method) = vm.get_method(kw_obj.clone(), vm.ctx.intern_str("keys")) else {
1618-
return Err(vm.new_type_error("argument after ** must be a mapping".to_owned()));
1619-
};
1620-
1621-
// Handle custom mapping objects like OrderedDict using keys() method
1622-
let keys = keys_method?.call((), vm)?.get_iter(vm)?;
1623-
while let PyIterReturn::Return(key) = keys.next(vm)? {
1610+
Self::iterate_mapping_keys(vm, &kw_obj, "argument after **", |key| {
16241611
let key_str = key
16251612
.payload_if_subclass::<PyStr>(vm)
16261613
.ok_or_else(|| vm.new_type_error("keywords must be strings".to_owned()))?;
16271614
let value = kw_obj.get_item(&*key, vm)?;
16281615
kwargs.insert(key_str.as_str().to_owned(), value);
1629-
}
1616+
Ok(())
1617+
})?;
16301618
kwargs
16311619
} else {
16321620
IndexMap::new()
@@ -1638,6 +1626,28 @@ impl ExecutingFrame<'_> {
16381626
Ok(FuncArgs { args, kwargs })
16391627
}
16401628

1629+
/// Helper function to iterate over mapping keys using the keys() method.
1630+
/// This ensures proper order preservation for OrderedDict and other custom mappings.
1631+
fn iterate_mapping_keys<F>(
1632+
vm: &VirtualMachine,
1633+
mapping: &PyObjectRef,
1634+
error_prefix: &str,
1635+
mut key_handler: F,
1636+
) -> PyResult<()>
1637+
where
1638+
F: FnMut(PyObjectRef) -> PyResult<()>,
1639+
{
1640+
let Some(keys_method) = vm.get_method(mapping.clone(), vm.ctx.intern_str("keys")) else {
1641+
return Err(vm.new_type_error(format!("{} must be a mapping", error_prefix)));
1642+
};
1643+
1644+
let keys = keys_method?.call((), vm)?.get_iter(vm)?;
1645+
while let PyIterReturn::Return(key) = keys.next(vm)? {
1646+
key_handler(key)?;
1647+
}
1648+
Ok(())
1649+
}
1650+
16411651
#[inline]
16421652
fn execute_call(&mut self, args: FuncArgs, vm: &VirtualMachine) -> FrameResult {
16431653
let func_ref = self.pop_value();

0 commit comments

Comments
 (0)