-
Notifications
You must be signed in to change notification settings - Fork 189
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 unary operations to NumericType #5946
Conversation
@sphuber would you be able to review this? |
Yes, I will take care of this when I have time |
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.
Thanks for the contribution @Mahhheshh . I have left two comments in the code.
return self.value | ||
|
||
def __neg__(self): | ||
return self.new(-self.value) |
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.
Maybe we should also add the abs
operator which is listed together with +
, -
and ~
as the unary operators in the official Python documentation. We can omit the ~
invert operator since that doesn't make sense for floats and I doubt anyone would want to use it for Int
.
return self.new(-self.value) | |
return self.new(-self.value) |
tests/orm/nodes/data/test_base.py
Outdated
def test_unary(): | ||
"""Test Unary operations for orm.Int and orm.Float""" | ||
|
||
# Int | ||
int_a = Int(5) | ||
int_b = Int(-5) | ||
|
||
# Float | ||
float_a = Float(10.0) | ||
float_b = Float(-10.0) | ||
|
||
# Test __pos__ | ||
assert +int_a == int_a # True +5 > 5 == 5 | ||
assert +int_b == int_b # True +(-5) > -5 == -5 | ||
assert +float_a == float_a # True +10.0 > 10 == 10 | ||
assert +float_b == float_b # True +(-10.0) > -10.0 == 10.0 | ||
|
||
# Test __neg__ | ||
assert -int_a != int_a # True -(5) != 5 | ||
assert -int_b != int_b # True -(-5) != -5 | ||
assert -float_a != float_a # True (-10.0) != 10.0 | ||
assert -float_b != float_b # True -(-10.0) > 10.0 != -10.0 | ||
assert -int_a == -int_a # True -5 == -5 |
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 would split this test in two (three when you implement abs
as well) and use parametrization to do both numeric types
def test_unary(): | |
"""Test Unary operations for orm.Int and orm.Float""" | |
# Int | |
int_a = Int(5) | |
int_b = Int(-5) | |
# Float | |
float_a = Float(10.0) | |
float_b = Float(-10.0) | |
# Test __pos__ | |
assert +int_a == int_a # True +5 > 5 == 5 | |
assert +int_b == int_b # True +(-5) > -5 == -5 | |
assert +float_a == float_a # True +10.0 > 10 == 10 | |
assert +float_b == float_b # True +(-10.0) > -10.0 == 10.0 | |
# Test __neg__ | |
assert -int_a != int_a # True -(5) != 5 | |
assert -int_b != int_b # True -(-5) != -5 | |
assert -float_a != float_a # True (-10.0) != 10.0 | |
assert -float_b != float_b # True -(-10.0) > 10.0 != -10.0 | |
assert -int_a == -int_a # True -5 == -5 | |
@pytest.mark.parametrize('numeric_type', (Float, Int)) | |
def test_unary_pos(numeric_type): | |
"""Test the ``__pos__`` unary operator for all ``NumericType`` subclasses.""" | |
node_positive = numeric_type(1) | |
node_negative = numeric_type(-1) | |
assert +node_positive == node_positive | |
assert +node_negative == node_negative | |
@pytest.mark.parametrize('numeric_type', (Float, Int)) | |
def test_unary_neg(numeric_type): | |
"""Test the ``__neg__`` unary operator for all ``NumericType`` subclasses.""" | |
node_positive = numeric_type(1) | |
node_negative = numeric_type(-1) | |
assert -node_positive != node_positive | |
assert -node_negative != node_negative | |
assert -node_positive == node_negative | |
assert -node_negative == node_positive |
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.
test for __abs__
is failing, I don't have idea about how it should be handled. Also I have made typo in the method name (realized now). Because of that tests were passing when ran locally.
tests/orm/nodes/data/test_base.py
Outdated
# Test positive number | ||
abs_positive = node_positive.abs() | ||
assert abs_positive == node_positive | ||
|
||
# Test negative number | ||
abs_negative = node_negative.abs() | ||
assert abs_negative != node_negative |
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 __abs__
method is invoked by the abs
built-in, so I would test it as follows:
# Test positive number | |
abs_positive = node_positive.abs() | |
assert abs_positive == node_positive | |
# Test negative number | |
abs_negative = node_negative.abs() | |
assert abs_negative != node_negative | |
assert abs(node_positive) == node_positive | |
assert abs(node_negative) != node_negative | |
assert abs(node_negative) == node_positive |
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.
Good to go. Thanks a lot for the contribution @Mahhheshh
Fixes #5911
The changes made to the
NumericType
class include adding two new methods,__pos__
and__neg__
, to support unary operations.__pos__
overloads the unary plus operator+
and returns the value of the object as-is, while__neg__
overloads the unary minus operator-
and returns a new instance of the same class with the negation of the value of the original object.