-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add object.{__lt__, __le__, __gt__, __gt__} #424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add object.{__lt__, __le__, __gt__, __gt__} #424
Conversation
vm/src/obj/objobject.rs
Outdated
|
||
Err(vm.new_type_error(format!( | ||
"'>' not supported between instances of {} and {}", | ||
i.borrow(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using the Display
trait, go for vm.py_str
to properly call the __str__
or __repr__
of the object.
Is this code required? If the |
Yes, RustPython:
Python3.7.2:
Looks like error from RustPython not so clear. @windelbouwman what do you think? |
I am unsure what is the proper location to implement this. We might also choose to update the existing error message in Rustpython. We already raise the correct exception type, so the message should be expanded, right? I would look in the |
Yes.
The unsupported method error thorws on 251 line in |
The proper error message appears already to be implemented here: https://github.com/RustPython/RustPython/blob/master/vm/src/vm.rs#L554 The correct function to take a look at is Take a look at the |
Looks like some work done in #433. Maybe I can add erros the same way? |
Yep! The class MyClass:
pass
assert MyClass().__le__(MyClass()) == NotImplemented
assert MyClass().__lt__(MyClass()) == NotImplemented
assert MyClass().__ge__(MyClass()) == NotImplemented
assert MyClass().__gt__(MyClass()) == NotImplemented And |
bfb122e
to
0887b55
Compare
@OddCoincidence I added the methods to
What I'm doing wrong? Can you help me please |
Sounds like the same type of bug I fixed in: #441
|
@cthulahoops You are right! Thank you! Should we change all calling |
Thats probably better. The magic methods should be used sparingly, preferably in wrapper methods. |
vm/src/vm.rs
Outdated
pub fn _lt(&mut self, a: &PyObjectRef, b: PyObjectRef) -> PyResult { | ||
self.call_method(a, "__lt__", vec![b]) | ||
pub fn _lt(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult { | ||
self.call_or_unsupported(a, b, "__lt__", "__lt__", |vm, a, b| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reverse methods for these shouldn't be the same, i.e. they're not commutative like __eq__
and __ne__
; a > b != b > a. Instead, as described here:
lt() and gt() are each other’s reflection, le() and ge() are each other’s reflection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -100,7 +100,7 @@ fn float_lt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | |||
.ctx | |||
.new_bool(v1 < objint::get_value(i2).to_f64().unwrap())) | |||
} else { | |||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i.borrow(), i2.borrow()))) | |||
Ok(vm.ctx.not_implemented()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think float_{gt,ge,le}
need this change as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks
pub fn _lt(&mut self, a: &PyObjectRef, b: PyObjectRef) -> PyResult { | ||
self.call_method(a, "__lt__", vec![b]) | ||
pub fn _lt(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult { | ||
self.call_or_unsupported(a, b, "__lt__", "__gt__", |vm, a, b| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The opposite of <
is >=
, right? I would expect __lt__
to fail over to __ge__
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because call_or_unsupported
flips the operands. If you think about it, a > b and b < a are equivalent. a > b and b <= a are not.
Also from the python docs:
lt() and gt() are each other’s reflection, le() and ge() are each other’s reflection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, yes, you are right! Sorry for that!
No description provided.