-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
[py trajectories] Adjust Clone and MakeDerivative for unique_ptr #22399
[py trajectories] Adjust Clone and MakeDerivative for unique_ptr #22399
Conversation
2c6d235
to
fe6a6f5
Compare
+@rpoyner-tri for feature review, please? This is a companion to #22353. Or maybe is there someone else who we could ramp up on bindings details like this to grow the feature reviewer pool? |
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.
Reviewed 7 of 7 files at r1, all commit messages.
Reviewable status: 3 unresolved discussions, needs at least two assigned reviewers
bindings/pydrake/trajectories_py.cc
line 205 at r1 (raw file):
captured_py_traj = py::none(); }); // Wrap it in a unique_ptr to meet out required return signature.
typo
Suggestion:
our
bindings/pydrake/trajectories_py.cc
line 205 at r1 (raw file):
captured_py_traj = py::none(); }); // Wrap it in a unique_ptr to meet out required return signature.
nit This comment doesn't quite do it for me. My first reading missed the crucial role of WrappedTrajectory in this particular caper.
Maybe instead: "Stuff the shared pointer inside a WrappedTrajectory, and return that via unique_ptr to meet our required return signature."
bindings/pydrake/trajectories_py.cc
line 223 at r1 (raw file):
bool used_legacy_clone = true; auto make_python_deepcopy = [&]() -> py::object { PYBIND11_OVERLOAD_INT(py::object, Trajectory<T>, "Clone");
nit similar to elsewhere, it's probably useful to point out that this macro lets control fall through if there is no suitable binding.
fe6a6f5
to
2c7caf5
Compare
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.
Reviewed 1 of 1 files at r2, all commit messages.
Reviewable status: 2 unresolved discussions, needs at least two assigned reviewers
2c7caf5
to
2f6169d
Compare
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.
Reviewed 1 of 1 files at r3, all commit messages.
Reviewable status: needs at least two assigned reviewers
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.
+@sherm1 for off-schedule platform review, please. Looking for some fresh eyes on this as the on-call people this week are already primed with a lot of background knowledge.
Reviewed 6 of 7 files at r1, 1 of 1 files at r3, all commit messages.
Reviewable status: LGTM missing from assignee sherm1(platform)
bindings/pydrake/trajectories_py.cc
line 205 at r1 (raw file):
Previously, rpoyner-tri (Rick Poyner (rico)) wrote…
nit This comment doesn't quite do it for me. My first reading missed the crucial role of WrappedTrajectory in this particular caper.
Maybe instead: "Stuff the shared pointer inside a WrappedTrajectory, and return that via unique_ptr to meet our required return signature."
"caper" -- I love it.
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.
Platform with a few nothing burgers
Reviewed 6 of 7 files at r1, 1 of 1 files at r3, all commit messages.
Reviewable status: 4 unresolved discussions
common/trajectories/wrapped_trajectory.h
line 21 at r3 (raw file):
BTW I had to wrestle with the idea that WrappedTrajectory both is-a Trajectory and has-a Trajectory. I had to go find the Trajectory class in order to understand why this makes sense. Consider saying something explicit about that in the class description here, something like:
WrappedTrajectory implements the abstract Trajectory interface using a pre-existing concrete Trajectory object held internally as a shared_ptr.
Maybe also mention that the purpose of this (IIUC) is to facilitate Python wrapping of Trajectory objects.
common/trajectories/wrapped_trajectory.h
line 30 at r3 (raw file):
private: // Trajectory overrides. std::unique_ptr<Trajectory<T>> DoClone() const final;
BTW an odd feature of this class is that WrappedTrajectory::Clone() doesn't return a WrappedTrajectory, it returns a Trajectory. That makes sense since it is only executing the Trajectory API, but it's odd semantics for a Clone() method. Consider pointing it out in the class documentation.
bindings/pydrake/test/trajectories_test.py
line 820 at r3 (raw file):
self.assertEqual(dut.rows(), 1) self.assertEqual(dut.cols(), 1) dut.Clone()
BTW just want to verify that your intent here was just to ensure Clone() doesn't blow up and that the repr tests below are intended to be on dut rather than dut.Clone().
common/trajectories/test/wrapped_trajectory_test.cc
line 43 at r3 (raw file):
EXPECT_EQ(dut.MakeDerivative(2)->value(t), -Circle(t)); auto clone = dut.Clone();
BTW consider noting that clone
is a Trajectory, not a WrappedTrajectory.
Because we allow implementations of Trajectory as Python subclasses, we cannot assume that the deleter associated with a call to Clone is `delete MyClass`, so we now adjust our PyTrajectory override logic to wrap its return value in a WrappedTrajectory. The only reason the unique_ptr used to work is Drake's custom fork or pybind11 with evil hacks, which will be going away soon. We also now warn Python subclasses to implement the canonical spelling of the __deepcopy__ method, instead of overriding the public Clone method. (Overriding Clone was already documented as deprecated in a prior commit; this just adds the warning.)
2f6169d
to
2ac30fd
Compare
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.
Reviewed 4 of 4 files at r4, all commit messages.
Reviewable status: complete! all discussions resolved, LGTM from assignees rpoyner-tri(platform),sherm1(platform)
bindings/pydrake/test/trajectories_test.py
line 820 at r3 (raw file):
Previously, sherm1 (Michael Sherman) wrote…
BTW just want to verify that your intent here was just to ensure Clone() doesn't blow up and that the repr tests below are intended to be on dut rather than dut.Clone().
Correct. But it was a somewhat haphazard so I shuffled a bit for improved readability and might as well add one more check.
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!
Reviewed 4 of 4 files at r4, all commit messages.
Reviewable status: complete! all discussions resolved, LGTM from assignees rpoyner-tri(platform),sherm1(platform)
Towards #5842 and #21968.
The situation with
Trajectory
is a bit different that some of our other similar changes to bindings for those issues. In most other cases, the only trouble comes fromClone
, but withTrajectory
we also have an instance factory methodMakeDerivative()
that also needs a solution. So in this case, we'll use the decorator pattern to solve the ownership problem (viainternal::WrappedTrajectory
) instead of trying to deal withClone
directly.This change is