mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
237 lines
7.4 KiB
Rust
237 lines
7.4 KiB
Rust
use super::objstr;
|
|
use super::objtype;
|
|
use crate::pyobject::{
|
|
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult,
|
|
TypeProtocol,
|
|
};
|
|
use crate::vm::VirtualMachine;
|
|
use std::cell::RefCell;
|
|
use std::collections::HashMap;
|
|
|
|
pub fn new_instance(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
|
// more or less __new__ operator
|
|
let type_ref = args.shift();
|
|
let obj = vm.ctx.new_instance(type_ref.clone(), None);
|
|
Ok(obj)
|
|
}
|
|
|
|
pub fn create_object(type_type: PyObjectRef, object_type: PyObjectRef, _dict_type: PyObjectRef) {
|
|
(*object_type.borrow_mut()).payload = PyObjectPayload::Class {
|
|
name: String::from("object"),
|
|
dict: RefCell::new(HashMap::new()),
|
|
mro: vec![],
|
|
};
|
|
(*object_type.borrow_mut()).typ = Some(type_type.clone());
|
|
}
|
|
|
|
fn object_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
|
|
);
|
|
Ok(vm.ctx.not_implemented())
|
|
}
|
|
|
|
fn object_ne(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
|
|
);
|
|
|
|
Ok(vm.ctx.not_implemented())
|
|
}
|
|
|
|
fn object_lt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
|
|
);
|
|
|
|
Ok(vm.ctx.not_implemented())
|
|
}
|
|
|
|
fn object_le(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
|
|
);
|
|
|
|
Ok(vm.ctx.not_implemented())
|
|
}
|
|
|
|
fn object_gt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
|
|
);
|
|
|
|
Ok(vm.ctx.not_implemented())
|
|
}
|
|
|
|
fn object_ge(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
|
|
);
|
|
|
|
Ok(vm.ctx.not_implemented())
|
|
}
|
|
|
|
fn object_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(vm, args, required = [(_zelf, Some(vm.ctx.object()))]);
|
|
|
|
// For now default to non hashable
|
|
Err(vm.new_type_error("unhashable type".to_string()))
|
|
}
|
|
|
|
// TODO: is object the right place for delattr?
|
|
fn object_delattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [
|
|
(zelf, Some(vm.ctx.object())),
|
|
(attr, Some(vm.ctx.str_type()))
|
|
]
|
|
);
|
|
|
|
match zelf.borrow().payload {
|
|
PyObjectPayload::Class { ref dict, .. } | PyObjectPayload::Instance { ref dict, .. } => {
|
|
let attr_name = objstr::get_value(attr);
|
|
dict.borrow_mut().remove(&attr_name);
|
|
Ok(vm.get_none())
|
|
}
|
|
_ => Err(vm.new_type_error("TypeError: no dictionary.".to_string())),
|
|
}
|
|
}
|
|
|
|
fn object_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.object()))]);
|
|
vm.call_method(zelf, "__repr__", vec![])
|
|
}
|
|
|
|
fn object_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(vm, args, required = [(obj, Some(vm.ctx.object()))]);
|
|
let type_name = objtype::get_type_name(&obj.typ());
|
|
let address = obj.get_id();
|
|
Ok(vm.new_str(format!("<{} object at 0x{:x}>", type_name, address)))
|
|
}
|
|
|
|
fn object_format(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [
|
|
(obj, Some(vm.ctx.object())),
|
|
(format_spec, Some(vm.ctx.str_type()))
|
|
]
|
|
);
|
|
if objstr::get_value(format_spec).is_empty() {
|
|
vm.to_str(obj)
|
|
} else {
|
|
Err(vm.new_type_error("unsupported format string passed to object.__format__".to_string()))
|
|
}
|
|
}
|
|
|
|
pub fn init(context: &PyContext) {
|
|
let object = &context.object;
|
|
let object_doc = "The most base type";
|
|
|
|
context.set_attr(&object, "__new__", context.new_rustfunc(new_instance));
|
|
context.set_attr(&object, "__init__", context.new_rustfunc(object_init));
|
|
context.set_attr(&object, "__eq__", context.new_rustfunc(object_eq));
|
|
context.set_attr(&object, "__ne__", context.new_rustfunc(object_ne));
|
|
context.set_attr(&object, "__lt__", context.new_rustfunc(object_lt));
|
|
context.set_attr(&object, "__le__", context.new_rustfunc(object_le));
|
|
context.set_attr(&object, "__gt__", context.new_rustfunc(object_gt));
|
|
context.set_attr(&object, "__ge__", context.new_rustfunc(object_ge));
|
|
context.set_attr(&object, "__delattr__", context.new_rustfunc(object_delattr));
|
|
context.set_attr(
|
|
&object,
|
|
"__dict__",
|
|
context.new_member_descriptor(object_dict),
|
|
);
|
|
context.set_attr(&object, "__hash__", context.new_rustfunc(object_hash));
|
|
context.set_attr(&object, "__str__", context.new_rustfunc(object_str));
|
|
context.set_attr(&object, "__repr__", context.new_rustfunc(object_repr));
|
|
context.set_attr(&object, "__format__", context.new_rustfunc(object_format));
|
|
context.set_attr(
|
|
&object,
|
|
"__getattribute__",
|
|
context.new_rustfunc(object_getattribute),
|
|
);
|
|
context.set_attr(&object, "__doc__", context.new_str(object_doc.to_string()));
|
|
}
|
|
|
|
fn object_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
|
|
Ok(vm.ctx.none())
|
|
}
|
|
|
|
fn object_dict(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
match args.args[0].borrow().payload {
|
|
PyObjectPayload::Class { ref dict, .. } | PyObjectPayload::Instance { ref dict, .. } => {
|
|
let new_dict = vm.new_dict();
|
|
for (attr, value) in dict.borrow().iter() {
|
|
vm.ctx.set_item(&new_dict, &attr, value.clone());
|
|
}
|
|
Ok(new_dict)
|
|
}
|
|
_ => Err(vm.new_type_error("TypeError: no dictionary.".to_string())),
|
|
}
|
|
}
|
|
|
|
fn object_getattribute(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
|
arg_check!(
|
|
vm,
|
|
args,
|
|
required = [
|
|
(obj, Some(vm.ctx.object())),
|
|
(name_str, Some(vm.ctx.str_type()))
|
|
]
|
|
);
|
|
let name = objstr::get_value(&name_str);
|
|
trace!("object.__getattribute__({:?}, {:?})", obj, name);
|
|
let cls = obj.typ();
|
|
|
|
if let Some(attr) = cls.get_attr(&name) {
|
|
let attr_class = attr.typ();
|
|
if attr_class.has_attr("__set__") {
|
|
if let Some(descriptor) = attr_class.get_attr("__get__") {
|
|
return vm.invoke(
|
|
descriptor,
|
|
PyFuncArgs {
|
|
args: vec![attr, obj.clone(), cls],
|
|
kwargs: vec![],
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if let Some(obj_attr) = obj.get_attr(&name) {
|
|
Ok(obj_attr)
|
|
} else if let Some(attr) = cls.get_attr(&name) {
|
|
vm.call_get_descriptor(attr, obj.clone())
|
|
} else if let Some(getter) = cls.get_attr("__getattr__") {
|
|
vm.invoke(
|
|
getter,
|
|
PyFuncArgs {
|
|
args: vec![cls, name_str.clone()],
|
|
kwargs: vec![],
|
|
},
|
|
)
|
|
} else {
|
|
let attribute_error = vm.context().exceptions.attribute_error.clone();
|
|
Err(vm.new_exception(
|
|
attribute_error,
|
|
format!("{} has no attribute '{}'", obj.borrow(), name),
|
|
))
|
|
}
|
|
}
|