-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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()) == NotImplementedAnd |
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
| .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.