From 54753b3d1407844a84672ac78b5c74fd312be63e Mon Sep 17 00:00:00 2001 From: Joey Hain Date: Wed, 20 Mar 2019 18:32:08 -0700 Subject: [PATCH 1/2] list, tuple: return NotImplemented for unsupported comparisons --- vm/src/obj/objlist.rs | 37 +++++++++++++++++++++---------------- vm/src/obj/objtuple.rs | 37 +++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index f435e6ea8d..903cd760b4 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -245,57 +245,62 @@ impl PyListRef { } } - fn eq(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn eq(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if self.as_object().is(&other) { - return Ok(true); + return Ok(vm.new_bool(true)); } if objtype::isinstance(&other, &vm.ctx.list_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_equal(vm, &zelf, &other)?) + let res = seq_equal(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Ok(false) + Ok(vm.ctx.not_implemented()) } } - fn lt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn lt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.list_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_lt(vm, &zelf, &other)?) + let res = seq_lt(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '<'", self, other))) + Ok(vm.ctx.not_implemented()) } } - fn gt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn gt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.list_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_gt(vm, &zelf, &other)?) + let res = seq_gt(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '>'", self, other))) + Ok(vm.ctx.not_implemented()) } } - fn ge(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn ge(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.list_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_ge(vm, &zelf, &other)?) + let res = seq_ge(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '>='", self, other))) + Ok(vm.ctx.not_implemented()) } } - fn le(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn le(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.list_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_le(vm, &zelf, &other)?) + let res = seq_le(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '<='", self, other))) + Ok(vm.ctx.not_implemented()) } } } diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs index 11d6a36947..d1986bce0d 100644 --- a/vm/src/obj/objtuple.rs +++ b/vm/src/obj/objtuple.rs @@ -46,43 +46,47 @@ impl PyValue for PyTuple { pub type PyTupleRef = PyRef; impl PyTupleRef { - fn lt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn lt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_lt(vm, &zelf, &other)?) + let res = seq_lt(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '<'", self, other))) + Ok(vm.ctx.not_implemented()) } } - fn gt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn gt(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_gt(vm, &zelf, &other)?) + let res = seq_gt(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '>'", self, other))) + Ok(vm.ctx.not_implemented()) } } - fn ge(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn ge(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_ge(vm, &zelf, &other)?) + let res = seq_ge(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '>='", self, other))) + Ok(vm.ctx.not_implemented()) } } - fn le(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn le(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let zelf = self.elements.borrow(); let other = get_elements(&other); - Ok(seq_le(vm, &zelf, &other)?) + let res = seq_le(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Err(vm.new_type_error(format!("Cannot compare {} and {} using '<='", self, other))) + Ok(vm.ctx.not_implemented()) } } @@ -93,7 +97,7 @@ impl PyTupleRef { let elements = e1.iter().chain(e2.iter()).cloned().collect(); Ok(vm.ctx.new_tuple(elements)) } else { - Err(vm.new_type_error(format!("Cannot add {} and {}", self, other))) + Ok(vm.ctx.not_implemented()) } } @@ -112,13 +116,14 @@ impl PyTupleRef { Ok(count) } - fn eq(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { + fn eq(self, other: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let zelf = &self.elements.borrow(); let other = get_elements(&other); - seq_equal(vm, &zelf, &other) + let res = seq_equal(vm, &zelf, &other)?; + Ok(vm.new_bool(res)) } else { - Ok(false) + Ok(vm.ctx.not_implemented()) } } From 0b1b6682c16eee99c44bfd9654aea42445311c80 Mon Sep 17 00:00:00 2001 From: Joey Hain Date: Wed, 20 Mar 2019 18:32:25 -0700 Subject: [PATCH 2/2] Fix Display impl for PyRef --- vm/src/obj/objstr.rs | 9 ++++----- vm/src/obj/objtype.rs | 7 +++++++ vm/src/pyobject.rs | 8 ++++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index 8569280ef9..139251f2a0 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -1,3 +1,4 @@ +use std::fmt; use std::hash::{Hash, Hasher}; use std::ops::Range; use std::str::FromStr; @@ -25,11 +26,9 @@ pub struct PyString { pub value: String, } -impl From for PyString { - fn from(t: T) -> PyString { - PyString { - value: t.to_string(), - } +impl fmt::Display for PyString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.value, f) } } diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index adb8b236d4..78c946dbc1 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; use std::collections::HashMap; +use std::fmt; use crate::function::PyFuncArgs; use crate::pyobject::{ @@ -20,6 +21,12 @@ pub struct PyClass { pub mro: Vec, } +impl fmt::Display for PyClass { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.name, f) + } +} + pub type PyClassRef = PyRef; impl PyValue for PyClass { diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index cd1ca77e66..fa84fc58e4 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -768,9 +768,13 @@ impl IntoPyObject for PyRef { } } -impl fmt::Display for PyRef { +impl fmt::Display for PyRef +where + T: PyValue + fmt::Display, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.obj.fmt(f) + let value: &T = self.obj.payload().expect("unexpected payload for type"); + fmt::Display::fmt(value, f) } }