Repository: RustPython/RustPython (language: rust)

Issue:
Fix test for test_field_metadata_custom_mapping
I'm looking at implementing the changes required for the test `test_field_metadata_custom_mapping` in `Lib/test/test_dataclasses.py` to pass. 

Specifically, accessing a non-existing field in the metadata of a dataclass field returns a `KeyError` instead of an `AttributeError` that CPython 3.12 produces. 

So this fails:
```python
with self.assertRaises(AttributeError):
  fields(C)[0].metadata["b"]
```

I'm currently working on this issue. 


Discussion / hints:
Looks like there is something strange:

The dataclass docs state that the object given to metadata will be wrapped in a [MappingProxyType()](https://docs.python.org/3/library/types.html#types.MappingProxyType)
https://docs.python.org/3/library/dataclasses.html#dataclasses.field

Following the link, it states that indexing with a key on MappingProxyType throws a `KeyError`.

But CPython produces an AttributeError and CPython's unit tests expect an AttributeError:
https://github.com/python/cpython/blob/5f4c7cf3f49629bcf890c305e0a90ffd708110a2/Lib/test/test_dataclasses/__init__.py#L2065C1-L2066C39

So it looks like that the documentation is partially wrong - `MappingProxyType` throws whatever the underlying structure throws, not always a `KeyError` as the documentation leads to believe.


Fix patch:
diff --git a/vm/src/builtins/mappingproxy.rs b/vm/src/builtins/mappingproxy.rs
index a5400ee6de..cf0fd9b5bb 100644
--- a/vm/src/builtins/mappingproxy.rs
+++ b/vm/src/builtins/mappingproxy.rs
@@ -93,13 +93,12 @@ impl Constructor for PyMappingProxy {
 ))]
 impl PyMappingProxy {
     fn get_inner(&self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
-        let opt = match &self.mapping {
-            MappingProxyInner::Class(class) => key
+        match &self.mapping {
+            MappingProxyInner::Class(class) => Ok(key
                 .as_interned_str(vm)
-                .and_then(|key| class.attributes.read().get(key).cloned()),
-            MappingProxyInner::Mapping(mapping) => mapping.mapping().subscript(&*key, vm).ok(),
-        };
-        Ok(opt)
+                .and_then(|key| class.attributes.read().get(key).cloned())),
+            MappingProxyInner::Mapping(mapping) => mapping.mapping().subscript(&*key, vm).map(Some),
+        }
     }
 
     #[pymethod]


Test patch:
diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py
index 2e51e43ae8..62ae5622a8 100644
--- a/Lib/test/test_dataclasses.py
+++ b/Lib/test/test_dataclasses.py
@@ -1843,8 +1843,6 @@ class C:
                                     'does not support item assignment'):
             fields(C)[0].metadata['test'] = 3
 
-    # TODO: RUSTPYTHON
-    @unittest.expectedFailure
     def test_field_metadata_custom_mapping(self):
         # Try a custom mapping.
         class SimpleNameSpace: