-
Notifications
You must be signed in to change notification settings - Fork 183
refactor(api): Move more vector arithmetic from Pydantic models to Point
#18699
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
Conversation
The `return NotImplemented` statement here didn't seem right. `NotImplemented` is a magic thing that Python uses in operators like `__add__()` and `__sub__()`, and it doesn't have that magic when it's used in normal methods like `magnitude_to()`.
def magnitude_to(self, other: Any) -> float: | ||
if not isinstance(other, Point): | ||
return NotImplemented | ||
def magnitude_to(self, other: Point) -> float: |
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.
One unrelated change here: This use of NotImplemented
did not seem right. NotImplemented
is a magic sentinel for use in things like __add__()
. It isn't meant for, and has no special meaning in, normal methods like magnitude_to()
.
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.
Like this a lot, thank you. Agreed that we'll probably never get to the point of using just one XYZ type, but this change should steer us to a universal XYZ adapter type, which is the next best thing.
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.
Agree with the reasoning. can we refactor that last thing in move labware to get rid of the step back there
This avoids an especially ugly conversion in MoveLabwareImplementation.
Changelog
__add__()
from Pydantic models likeLabwareOffsetVector
. Now, callers should convert the model to aPoint
and usePoint
's arithmetic methods.Point
, instead of definingto_point()
on every vector-like Pydantic model, add aPoint.from_xyz_attrs(model)
method that works on anything withx
/y
/z
attributes. Delete the existingto_point()
methods.The intent is to encourage us to consistently use
Point
s for everything mathematical, and reserve Pydantic models for just the interface boundaries where we're converting to/from JSON. I think we want to do this because:LabwareOffsetVector
,Vec3f
,Vector3D
, etc.). We are working to consolidate these, but I doubt that we'll ever have one Pydantic vector model to rule them all. In part, because parsing/serialization contexts have different needs. Sometimes we want the fields to have defaults, sometimes we don't; sometimes we care about float vs. int, sometimes we don't.protocol_engine/types/module.py
, really ought to live inshared-data
. We can't move them toshared-data
if they have a dependency onopentrons.types.Point
.Test Plan and Hands on Testing
Just existing automated tests.
Review requests
Ideologically, does this seem good?
Risk assessment
Mostly low, but there is one hazard.
Point
's operators are defined like:An unfortunate side effect of
other: Any
andreturn NotImplemented
is that if you accidentally dopoint + not_a_point
, you won't get a type-checking error, and you'll probably get aTypeError
at runtime, unless the other side defined a suitable__radd__()
(which it probably didn't). So we need to be careful that in my changes, I'm never doingpoint + not_a_point
.I mitigated this by temporarily changing the type annotation locally and looking to see if that surfaced any new errors. I don't think we can actually merge that change because
Point.__add__
needs to remain compatible withNamedTuple.__add__
. Perhaps this indicates we shouldn't be subclassing fromNamedTuple
.