Add repr for namespaces.

This commit is contained in:
jfh
2021-10-18 13:15:22 +03:00
parent 809171dcf8
commit c6a8511425
2 changed files with 32 additions and 6 deletions

View File

@@ -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()

View File

@@ -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<Self>, vm: &VirtualMachine) -> PyResult<String> {
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 {