diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 1bd8efa6a..588edc376 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -1362,7 +1362,6 @@ class MappingProxyTests(unittest.TestCase): self.assertEqual(view['key1'], 70) self.assertEqual(copy['key1'], 27) - @unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: unsupported operand type(s) for |: 'dict' and 'mappingproxy' def test_union(self): mapping = {'a': 0, 'b': 1, 'c': 2} view = self.mappingproxy(mapping) diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py index 5f996893e..13285c9b2 100644 --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -244,7 +244,6 @@ class UserDictTest(mapping_tests.TestHashMappingProtocol): test_repr_deep = mapping_tests.TestHashMappingProtocol.test_repr_deep - @unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: unsupported operand type(s) for |: 'UserDict' and 'mappingproxy' def test_mixed_or(self): for t in UserDict, dict, types.MappingProxyType: with self.subTest(t.__name__): diff --git a/crates/vm/src/builtins/mappingproxy.rs b/crates/vm/src/builtins/mappingproxy.rs index df9c61e0a..fe7e0e178 100644 --- a/crates/vm/src/builtins/mappingproxy.rs +++ b/crates/vm/src/builtins/mappingproxy.rs @@ -258,11 +258,19 @@ impl AsNumber for PyMappingProxy { fn as_number() -> &'static PyNumberMethods { static AS_NUMBER: PyNumberMethods = PyNumberMethods { or: Some(|a, b, vm| { - if let Some(a) = a.downcast_ref::() { - a.__or__(b.to_pyobject(vm), vm) - } else { - Ok(vm.ctx.not_implemented()) - } + // Mirror CPython's mappingproxy_or: when either side is a + // mappingproxy, unwrap to its underlying mapping and delegate + // to PyNumber_Or so `dict | mp`, `mp | dict`, and `mp | mp` + // all produce a `dict` result. + let a_obj = match a.downcast_ref::() { + Some(mp) => mp.copy(vm)?, + None => a.to_pyobject(vm), + }; + let b_obj = match b.downcast_ref::() { + Some(mp) => mp.copy(vm)?, + None => b.to_pyobject(vm), + }; + vm._or(a_obj.as_ref(), b_obj.as_ref()) }), inplace_or: Some(|a, b, vm| { if let Some(a) = a.downcast_ref::() {