forked from Rust-related/RustPython
Merge pull request #3334 from DimitrisJim/namespace_fixes
Namespace fixes
This commit is contained in:
6
Lib/test/test_types.py
vendored
6
Lib/test/test_types.py
vendored
@@ -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()
|
||||
@@ -1295,8 +1293,6 @@ class SimpleNamespaceTests(unittest.TestCase):
|
||||
self.assertEqual(repr(ns1), "{name}(x=1, y=2, w=3)".format(name=name))
|
||||
self.assertEqual(repr(ns2), "{name}(x='spam', _y=5)".format(name=name))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_equal(self):
|
||||
ns1 = types.SimpleNamespace(x=1)
|
||||
ns2 = types.SimpleNamespace()
|
||||
@@ -1335,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()
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use super::PyTypeRef;
|
||||
use crate::{
|
||||
function::{IntoPyObject, KwArgs},
|
||||
types::Constructor,
|
||||
PyClassImpl, PyContext, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
builtins::PyDict,
|
||||
function::FuncArgs,
|
||||
types::{Comparable, Constructor, PyComparisonOp},
|
||||
vm::ReprGuard,
|
||||
IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TypeProtocol, VirtualMachine,
|
||||
};
|
||||
|
||||
/// A simple attribute-based namespace.
|
||||
@@ -19,14 +22,10 @@ impl PyValue for PyNamespace {
|
||||
}
|
||||
|
||||
impl Constructor for PyNamespace {
|
||||
type Args = KwArgs;
|
||||
type Args = FuncArgs;
|
||||
|
||||
fn py_new(cls: PyTypeRef, kwargs: Self::Args, vm: &VirtualMachine) -> PyResult {
|
||||
let zelf = PyNamespace.into_ref_with_type(vm, cls)?;
|
||||
for (name, value) in kwargs.into_iter() {
|
||||
zelf.as_object().set_attr(name, value, vm)?;
|
||||
}
|
||||
Ok(zelf.into_pyobject(vm))
|
||||
fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult {
|
||||
PyNamespace {}.into_pyresult_with_type(vm, cls)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +35,63 @@ impl PyNamespace {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(flags(BASETYPE, HAS_DICT), with(Constructor))]
|
||||
impl PyNamespace {}
|
||||
#[pyimpl(flags(BASETYPE, HAS_DICT), with(Constructor, Comparable))]
|
||||
impl PyNamespace {
|
||||
#[pymethod(magic)]
|
||||
fn init(zelf: PyRef<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
if !args.args.is_empty() {
|
||||
return Err(vm.new_type_error("no positional arguments expected".to_owned()));
|
||||
}
|
||||
for (name, value) in args.kwargs.into_iter() {
|
||||
zelf.as_object().set_attr(name, value, vm)?;
|
||||
}
|
||||
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 {
|
||||
fn cmp(
|
||||
zelf: &PyRef<Self>,
|
||||
other: &PyObjectRef,
|
||||
op: PyComparisonOp,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
let other = class_or_notimplemented!(Self, other);
|
||||
match (zelf.as_object().dict(), other.as_object().dict()) {
|
||||
(Some(d1), Some(d2)) => PyDict::cmp(&d1, d2.as_object(), op, vm),
|
||||
_ => Ok(PyComparisonValue::NotImplemented),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyNamespace::extend_class(context, &context.types.namespace_type);
|
||||
|
||||
Reference in New Issue
Block a user