Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions vm/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn builtin_bin(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {

fn builtin_callable(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, None)]);
let is_callable = objtype::class_has_attr(&obj.type_pyref(), "__call__");
let is_callable = objtype::class_has_attr(&obj.class(), "__call__");
Ok(vm.new_bool(is_callable))
}

Expand Down Expand Up @@ -240,7 +240,7 @@ fn make_scope(
} else if vm.isinstance(arg, &dict_type)? {
Some(arg)
} else {
let arg_typ = arg.typ();
let arg_typ = arg.class();
let actual_type = vm.to_pystr(&arg_typ)?;
let expected_type_name = vm.to_pystr(&dict_type)?;
return Err(vm.new_type_error(format!(
Expand Down Expand Up @@ -368,7 +368,7 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
Err(..) => Err(vm.new_type_error(format!(
"object of type '{}' has no method {:?}",
objtype::get_type_name(&obj.typ()),
obj.class().name,
len_method_name
))),
}
Expand Down Expand Up @@ -605,10 +605,9 @@ fn builtin_reversed(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
match vm.get_method(obj.clone(), "__reversed__") {
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
// TODO: fallback to using __len__ and __getitem__, if object supports sequence protocol
Err(..) => Err(vm.new_type_error(format!(
"'{}' object is not reversible",
objtype::get_type_name(&obj.typ()),
))),
Err(..) => {
Err(vm.new_type_error(format!("'{}' object is not reversible", obj.class().name)))
}
}
}
// builtin_reversed
Expand Down Expand Up @@ -802,9 +801,9 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
};

for base in bases.clone() {
if objtype::issubclass(&base.type_pyref(), &metaclass) {
metaclass = base.type_pyref();
} else if !objtype::issubclass(&metaclass, &base.type_pyref()) {
if objtype::issubclass(&base.class(), &metaclass) {
metaclass = base.class();
} else if !objtype::issubclass(&metaclass, &base.class()) {
return Err(vm.new_type_error("metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases".to_string()));
}
}
Expand Down
3 changes: 1 addition & 2 deletions vm/src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
args,
required = [(exc, Some(vm.ctx.exceptions.exception_type.clone()))]
);
let type_name = objtype::get_type_name(&exc.typ());
let msg = if let Ok(m) = vm.get_attribute(exc.clone(), "msg") {
match vm.to_pystr(&m) {
Ok(msg) => msg,
Expand All @@ -77,7 +76,7 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
} else {
panic!("Error message must be set");
};
let s = format!("{}: {}", type_name, msg);
let s = format!("{}: {}", exc.class().name, msg);
Ok(vm.new_str(s))
}

Expand Down
6 changes: 3 additions & 3 deletions vm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ impl Frame {
// let args = PyFuncArgs::default();
// TODO: what happens when we got an error during handling exception?
let args = if let Some(exc) = exc {
let exc_type = exc.typ();
let exc_type = exc.class().into_object();
let exc_val = exc.clone();
let exc_tb = vm.ctx.none(); // TODO: retrieve traceback?
vec![exc_type, exc_val, exc_tb]
Expand Down Expand Up @@ -1093,7 +1093,7 @@ impl Frame {
Ok(found) => Ok(found),
Err(_) => Err(vm.new_type_error(format!(
"{} has no __contains__ method",
objtype::get_type_name(&haystack.typ())
haystack.class().name
))),
}
}
Expand All @@ -1103,7 +1103,7 @@ impl Frame {
Ok(found) => Ok(vm.ctx.new_bool(!objbool::get_value(&found))),
Err(_) => Err(vm.new_type_error(format!(
"{} has no __contains__ method",
objtype::get_type_name(&haystack.typ())
haystack.class().name
))),
}
}
Expand Down
2 changes: 1 addition & 1 deletion vm/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl PyFuncArgs {
Ok(Some(kwarg))
} else {
let expected_ty_name = vm.to_pystr(&ty)?;
let actual_ty_name = vm.to_pystr(&kwarg.typ())?;
let actual_ty_name = vm.to_pystr(&kwarg.class())?;
Err(vm.new_type_error(format!(
"argument of type {} is required for named parameter `{}` (got: {})",
expected_ty_name, key, actual_ty_name
Expand Down
2 changes: 1 addition & 1 deletion vm/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ macro_rules! type_check {
let arg = &$args.args[$arg_count];

if !$crate::obj::objtype::isinstance(arg, &expected_type) {
let arg_typ = arg.typ();
let arg_typ = arg.class();
let expected_type_name = $vm.to_pystr(&expected_type)?;
let actual_type = $vm.to_pystr(&arg_typ)?;
return Err($vm.new_type_error(format!(
Expand Down
3 changes: 1 addition & 2 deletions vm/src/obj/objfloat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,7 @@ impl PyFloatRef {
}
}
} else {
let type_name = objtype::get_type_name(&arg.typ());
return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
return Err(vm.new_type_error(format!("can't convert {} to float", arg.class().name)));
};
PyFloat { value }.into_ref_with_type(vm, cls)
}
Expand Down
2 changes: 1 addition & 1 deletion vm/src/obj/objfunction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn bind_method(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
required = [(function, None), (obj, None), (cls, None)]
);

if obj.is(&vm.get_none()) && !cls.is(&obj.typ()) {
if obj.is(&vm.get_none()) && !cls.is(&obj.class()) {
Ok(function.clone())
} else {
Ok(vm.ctx.new_bound_method(function.clone(), obj.clone()))
Expand Down
15 changes: 3 additions & 12 deletions vm/src/obj/objint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,7 @@ impl PyIntRef {

fn lshift(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
return Err(vm.new_type_error(format!(
"unsupported operand type(s) for << '{}' and '{}'",
objtype::get_type_name(&self.as_object().typ()),
objtype::get_type_name(&other.typ())
)));
return Ok(vm.ctx.not_implemented());
}

if let Some(n_bits) = get_value(&other).to_usize() {
Expand All @@ -234,11 +230,7 @@ impl PyIntRef {

fn rshift(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
return Err(vm.new_type_error(format!(
"unsupported operand type(s) for >> '{}' and '{}'",
objtype::get_type_name(&self.as_object().typ()),
objtype::get_type_name(&other.typ())
)));
return Ok(vm.ctx.not_implemented());
}

if let Some(n_bits) = get_value(&other).to_usize() {
Expand Down Expand Up @@ -420,10 +412,9 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult<Big
}
}
} else {
let type_name = objtype::get_type_name(&obj.typ());
return Err(vm.new_type_error(format!(
"int() argument must be a string or a number, not '{}'",
type_name
obj.class().name
)));
};
Ok(val)
Expand Down
2 changes: 1 addition & 1 deletion vm/src/obj/objiter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::obj::objtype::PyClassRef;
*/
pub fn get_iter(vm: &VirtualMachine, iter_target: &PyObjectRef) -> PyResult {
vm.call_method(iter_target, "__iter__", vec![])
// let type_str = objstr::get_value(&vm.to_str(iter_target.typ()).unwrap());
// let type_str = objstr::get_value(&vm.to_str(iter_target.class()).unwrap());
// let type_error = vm.new_type_error(format!("Cannot iterate over {}", type_str));
// return Err(type_error);
}
Expand Down
10 changes: 5 additions & 5 deletions vm/src/obj/objnone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub type PyNoneRef = PyRef<PyNone>;

impl PyValue for PyNone {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.ctx.none().type_pyref()
vm.ctx.none().class()
}
}

Expand Down Expand Up @@ -44,7 +44,7 @@ impl PyNoneRef {

fn get_attribute(self, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
trace!("None.__getattribute__({:?}, {:?})", self, name);
let cls = self.typ();
let cls = self.class();

// Properties use a comparision with None to determine if they are either invoked by am
// instance binding or a class binding. But if the object itself is None then this detection
Expand All @@ -69,7 +69,7 @@ impl PyNoneRef {
}

if let Some(attr) = class_get_attr(&cls, &name.value) {
let attr_class = attr.type_pyref();
let attr_class = attr.class();
if class_has_attr(&attr_class, "__set__") {
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
return call_descriptor(
Expand All @@ -88,7 +88,7 @@ impl PyNoneRef {
// Ok(obj_attr)
// } else
if let Some(attr) = class_get_attr(&cls, &name.value) {
let attr_class = attr.type_pyref();
let attr_class = attr.class();
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
call_descriptor(attr, get_func, self.into_object(), cls.into_object(), vm)
} else {
Expand All @@ -107,7 +107,7 @@ fn none_new(_: PyClassRef, vm: &VirtualMachine) -> PyNoneRef {
}

pub fn init(context: &PyContext) {
extend_class!(context, &context.none.typ(), {
extend_class!(context, &context.none.class(), {
"__new__" => context.new_rustfunc(none_new),
"__repr__" => context.new_rustfunc(PyNoneRef::repr),
"__bool__" => context.new_rustfunc(PyNoneRef::bool),
Expand Down
29 changes: 14 additions & 15 deletions vm/src/obj/objobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ fn object_setattr(
vm: &VirtualMachine,
) -> PyResult<()> {
trace!("object.__setattr__({:?}, {}, {:?})", obj, attr_name, value);
let cls = obj.type_pyref();
let cls = obj.class();

if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) {
if let Some(descriptor) = objtype::class_get_attr(&attr.type_pyref(), "__set__") {
if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__set__") {
return vm
.invoke(descriptor, vec![attr, obj.clone(), value])
.map(|_| ());
Expand All @@ -118,19 +118,19 @@ fn object_setattr(
dict.set_item(&vm.ctx, &attr_name.value, value);
Ok(())
} else {
let type_name = objtype::get_type_name(obj.type_ref());
Err(vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
type_name, &attr_name.value
obj.class().name,
&attr_name.value
)))
}
}

fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
let cls = obj.type_pyref();
let cls = obj.class();

if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) {
if let Some(descriptor) = objtype::class_get_attr(&attr.type_pyref(), "__delete__") {
if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__delete__") {
return vm.invoke(descriptor, vec![attr, obj.clone()]).map(|_| ());
}
}
Expand All @@ -139,10 +139,10 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine)
dict.del_item(&attr_name.value);
Ok(())
} else {
let type_name = objtype::get_type_name(obj.type_ref());
Err(vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
type_name, &attr_name.value
obj.class().name,
&attr_name.value
)))
}
}
Expand All @@ -154,9 +154,8 @@ fn object_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {

fn object_repr(vm: &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)))
Ok(vm.new_str(format!("<{} object at 0x{:x}>", obj.class().name, address)))
}

pub fn object_dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyList {
Expand Down Expand Up @@ -216,15 +215,15 @@ fn object_init(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
}

fn object_class(obj: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef {
obj.typ()
obj.class().into_object()
}

fn object_class_setter(
instance: PyObjectRef,
_value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
let type_repr = vm.to_pystr(&instance.typ())?;
let type_repr = vm.to_pystr(&instance.class())?;
Err(vm.new_type_error(format!("can't change class of type '{}'", type_repr)))
}

Expand All @@ -247,10 +246,10 @@ fn object_getattribute(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
);
let name = objstr::get_value(&name_str);
trace!("object.__getattribute__({:?}, {:?})", obj, name);
let cls = obj.type_pyref();
let cls = obj.class();

if let Some(attr) = objtype::class_get_attr(&cls, &name) {
let attr_class = attr.type_pyref();
let attr_class = attr.class();
if objtype::class_has_attr(&attr_class, "__set__") {
if let Some(descriptor) = objtype::class_get_attr(&attr_class, "__get__") {
return vm.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()]);
Expand Down Expand Up @@ -279,7 +278,7 @@ fn object_getattr(obj: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {

pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
// Get class attributes:
let mut attributes = objtype::get_attributes(obj.type_pyref());
let mut attributes = objtype::get_attributes(obj.class());

// Get instance attributes:
if let Some(dict) = &obj.dict {
Expand Down
10 changes: 6 additions & 4 deletions vm/src/obj/objproperty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::function::IntoPyNativeFunc;
use crate::function::OptionalArg;
use crate::obj::objstr::PyStringRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue};
use crate::pyobject::{
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::vm::VirtualMachine;

/// Read-only property, doesn't have __set__ or __delete__
Expand Down Expand Up @@ -137,7 +139,7 @@ impl PyPropertyRef {
setter: self.setter.clone(),
deleter: self.deleter.clone(),
}
.into_ref_with_type(vm, self.typ())
.into_ref_with_type(vm, TypeProtocol::class(&self))
}

fn setter(self, setter: Option<PyObjectRef>, vm: &VirtualMachine) -> PyResult<Self> {
Expand All @@ -146,7 +148,7 @@ impl PyPropertyRef {
setter: setter.or_else(|| self.setter.clone()),
deleter: self.deleter.clone(),
}
.into_ref_with_type(vm, self.typ())
.into_ref_with_type(vm, TypeProtocol::class(&self))
}

fn deleter(self, deleter: Option<PyObjectRef>, vm: &VirtualMachine) -> PyResult<Self> {
Expand All @@ -155,7 +157,7 @@ impl PyPropertyRef {
setter: self.setter.clone(),
deleter: deleter.or_else(|| self.deleter.clone()),
}
.into_ref_with_type(vm, self.typ())
.into_ref_with_type(vm, TypeProtocol::class(&self))
}
}

Expand Down
4 changes: 2 additions & 2 deletions vm/src/obj/objsequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,13 @@ pub fn get_item(
if sequence.payload::<PyList>().is_some() {
Ok(PyObject::new(
PyList::from(elements.to_vec().get_slice_items(vm, &subscript)?),
sequence.type_pyref(),
sequence.class(),
None,
))
} else if sequence.payload::<PyTuple>().is_some() {
Ok(PyObject::new(
PyTuple::from(elements.to_vec().get_slice_items(vm, &subscript)?),
sequence.type_pyref(),
sequence.class(),
None,
))
} else {
Expand Down
Loading