Used in update and ior.
(&self, other: PyObjectRef, vm: &VirtualMachine)
| 145 | |
| 146 | // Used in update and ior. |
| 147 | pub(crate) fn merge_object(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |
| 148 | let casted: Result<PyRefExact<Self>, _> = other.downcast_exact(vm); |
| 149 | let other = match casted { |
| 150 | Ok(dict_other) => return self.merge_dict(dict_other.into_pyref(), vm), |
| 151 | Err(other) => other, |
| 152 | }; |
| 153 | let dict = &self.entries; |
| 154 | // Use get_attr to properly invoke __getattribute__ for proxy objects |
| 155 | let keys_result = other.get_attr(vm.ctx.intern_str("keys"), vm); |
| 156 | let has_keys = match keys_result { |
| 157 | Ok(keys_method) => { |
| 158 | let keys = keys_method.call((), vm)?.get_iter(vm)?; |
| 159 | while let PyIterReturn::Return(key) = keys.next(vm)? { |
| 160 | let val = other.get_item(&*key, vm)?; |
| 161 | dict.insert(vm, &*key, val)?; |
| 162 | } |
| 163 | true |
| 164 | } |
| 165 | Err(e) if e.fast_isinstance(vm.ctx.exceptions.attribute_error) => false, |
| 166 | Err(e) => return Err(e), |
| 167 | }; |
| 168 | if !has_keys { |
| 169 | let iter = other.get_iter(vm)?; |
| 170 | loop { |
| 171 | fn err(vm: &VirtualMachine) -> PyBaseExceptionRef { |
| 172 | vm.new_value_error("Iterator must have exactly two elements") |
| 173 | } |
| 174 | let element = match iter.next(vm)? { |
| 175 | PyIterReturn::Return(obj) => obj, |
| 176 | PyIterReturn::StopIteration(_) => break, |
| 177 | }; |
| 178 | let elem_iter = element.get_iter(vm)?; |
| 179 | let key = elem_iter.next(vm)?.into_result().map_err(|_| err(vm))?; |
| 180 | let value = elem_iter.next(vm)?.into_result().map_err(|_| err(vm))?; |
| 181 | if matches!(elem_iter.next(vm)?, PyIterReturn::Return(_)) { |
| 182 | return Err(err(vm)); |
| 183 | } |
| 184 | dict.insert(vm, &*key, value)?; |
| 185 | } |
| 186 | } |
| 187 | Ok(()) |
| 188 | } |
| 189 | |
| 190 | fn merge_dict(&self, dict_other: PyDictRef, vm: &VirtualMachine) -> PyResult<()> { |
| 191 | let dict = &self.entries; |
no test coverage detected