Skip to content

Commit e7cd832

Browse files
committed
Changed to proper implementation in vm
1 parent 0e4d367 commit e7cd832

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

vm/src/obj/objobject.rs

-12
Original file line numberDiff line numberDiff line change
@@ -101,24 +101,12 @@ pub fn init(context: &PyContext) {
101101
object.set_attr("__hash__", context.new_rustfunc(object_hash));
102102
object.set_attr("__str__", context.new_rustfunc(object_str));
103103
object.set_attr("__repr__", context.new_rustfunc(object_repr));
104-
object.set_attr("__and__", context.new_rustfunc(object_and));
105104
}
106105

107106
fn object_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
108107
Ok(vm.ctx.none())
109108
}
110109

111-
fn object_and(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
112-
arg_check!(vm, args, required = [(zelf, None), (other, None)]);
113-
114-
let zelf_type = objtype::get_type_name(&zelf.typ());
115-
let other_type = objtype::get_type_name(&other.typ());
116-
Err(vm.new_type_error(format!(
117-
"unsupported operand type(s) for &: {:?} and {:?}",
118-
zelf_type, other_type
119-
)))
120-
}
121-
122110
fn object_dict(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
123111
match args.args[0].borrow().kind {
124112
PyObjectKind::Class { ref dict, .. } => Ok(dict.clone()),

vm/src/vm.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,50 @@ impl VirtualMachine {
407407
}
408408

409409
pub fn _and(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
410-
self.call_method(&a, "__and__", vec![b])
410+
// 1. Try __and__, next __rand__, next, give up
411+
if let Ok(method) = self.get_method(a.clone(), "__and__") {
412+
match self.invoke(
413+
method,
414+
PyFuncArgs {
415+
args: vec![b.clone()],
416+
kwargs: vec![],
417+
},
418+
) {
419+
Ok(value) => return Ok(value),
420+
Err(err) => {
421+
if !objtype::isinstance(&err, &self.ctx.exceptions.not_implemented_error) {
422+
return Err(err);
423+
}
424+
}
425+
}
426+
}
427+
428+
// 2. try __rand__
429+
if let Ok(method) = self.get_method(b.clone(), "__rand__") {
430+
match self.invoke(
431+
method,
432+
PyFuncArgs {
433+
args: vec![a.clone()],
434+
kwargs: vec![],
435+
},
436+
) {
437+
Ok(value) => return Ok(value),
438+
Err(err) => {
439+
if !objtype::isinstance(&err, &self.ctx.exceptions.not_implemented_error) {
440+
return Err(err);
441+
}
442+
}
443+
}
444+
}
445+
446+
// 3. It all failed :(
447+
// Cannot and a and b
448+
let a_type_name = objtype::get_type_name(&a.typ());
449+
let b_type_name = objtype::get_type_name(&b.typ());
450+
Err(self.new_type_error(format!(
451+
"Unsupported operand types for '&': '{}' and '{}'",
452+
a_type_name, b_type_name
453+
)))
411454
}
412455
}
413456

0 commit comments

Comments
 (0)