diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 009ebcbb2d..cc2aff0f57 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -1283,8 +1283,6 @@ class SimpleNamespaceTests(unittest.TestCase): del ns1.spam self.assertEqual(vars(ns1), {}) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_repr(self): ns1 = types.SimpleNamespace(x=1, y=2, w=3) ns2 = types.SimpleNamespace() @@ -1333,8 +1331,6 @@ class SimpleNamespaceTests(unittest.TestCase): self.assertEqual(ns3.spam, ns2) self.assertEqual(ns2.spam.spam, ns2) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_recursive_repr(self): ns1 = types.SimpleNamespace(c='cookie') ns2 = types.SimpleNamespace() diff --git a/vm/src/builtins/namespace.rs b/vm/src/builtins/namespace.rs index e448d0ebfb..910bc354fd 100644 --- a/vm/src/builtins/namespace.rs +++ b/vm/src/builtins/namespace.rs @@ -3,8 +3,9 @@ use crate::{ builtins::PyDict, function::FuncArgs, types::{Comparable, Constructor, PyComparisonOp}, - PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, - VirtualMachine, + vm::ReprGuard, + IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, + TypeProtocol, VirtualMachine, }; /// A simple attribute-based namespace. @@ -46,6 +47,35 @@ impl PyNamespace { } Ok(()) } + + #[pymethod(magic)] + fn repr(zelf: PyRef, vm: &VirtualMachine) -> PyResult { + let o = zelf.as_object(); + let name = if o.class().is(&vm.ctx.types.namespace_type) { + "namespace".to_owned() + } else { + o.class().slot_name() + }; + + let repr = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) { + let parts = if let Some(dict) = zelf.as_object().dict() { + let mut parts = Vec::with_capacity(dict.len()); + for (key, value) in dict { + let k = vm.to_repr(&key)?; + let key_str = k.as_str(); + let value_repr = vm.to_repr(&value)?; + parts.push(format!("{}={}", &key_str[1..key_str.len() - 1], value_repr)); + } + parts + } else { + vec![] + }; + format!("{}({})", name, parts.join(", ")) + } else { + format!("{}(...)", name) + }; + Ok(repr) + } } impl Comparable for PyNamespace {