-
Notifications
You must be signed in to change notification settings - Fork 237
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
Use PyCapsule names #129
Use PyCapsule names #129
Conversation
rclpy/rclpy/node.py
Outdated
if not class_ or class_.__name__ != 'PyCapsule': | ||
raise ValueError('The node handle must be a PyCapsule') | ||
for sub in self.subscriptions: | ||
_rclpy.rclpy_destroy_node_entity(sub.subscription_handle, self.handle) |
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 return value is not being considered anymore?
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.
This is intentional. Currently rclpy_destroy_node_entity
returns True on success or raises a RuntimeError on failure, so I got rid of the return value altogether.
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 see. If the return value of the function doesn't have any purpose anymore I would suggest to return None
instead (like any Python function without a return statement).
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 believe that is what this PR is doing, raising and returning NULL on failure otherwise returning None:
https://github.com/ros2/rclpy/pull/129/files#diff-80dda03110b5be606b823d6b0558b5c2R1567
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.
Sorry for the noise. I don't know what I was looking at.
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.
code change looks good to me, a few comment regarding docblock consistency throughout the PR
rclpy/src/rclpy/_rclpy.c
Outdated
PyList_SET_ITEM(pylist, 1, PyLong_FromUnsignedLongLong((uint64_t)&gc->impl)); | ||
|
||
return pylist; | ||
} | ||
|
||
/// Trigger a general purpose guard condition | ||
/** | ||
* Raises ValueError if the guard condition is not a capsule of the correcttype | ||
* Raises RuntimeError if the guard condition could not be triggered |
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.
Several other places do raise runtime error on this type of failure, maybe we should take advantage of this PR to update them all
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 updated all the ones I found in 451a072
rclpy/src/rclpy/_rclpy.c
Outdated
@@ -597,6 +613,7 @@ rclpy_expand_topic_name(PyObject * Py_UNUSED(self), PyObject * args) | |||
* provided as pymsg_type to send messages over the wire. | |||
* | |||
* A ValueError is raised (and NULL returned) when the topic name is invalid. | |||
* Raises ValueError if the capsules are not the correct types |
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.
Can you rephrase the sentence above to match this one 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 451a072
rclpy/src/rclpy/_rclpy.c
Outdated
@@ -772,6 +799,8 @@ rclpy_create_timer(PyObject * Py_UNUSED(self), PyObject * args) | |||
|
|||
/// Returns the period of the timer in nanoseconds | |||
/** | |||
* Raise ValueError if capsule is not a timer capsule |
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.
typo: Raises for consistency with other docblocks added in this PR
Can you also move the Raise RuntimeError on rcl error
here? (same for the other functions)
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 451a072
Naming capsules prevents calling the wrong kind of cleanup on a pointer
7841e73
to
0840184
Compare
Rclpy named capsules fixups
rclpy/rclpy/node.py
Outdated
self.services = [] | ||
self.clients = [] | ||
self.publishers = [] | ||
self.guards = [] |
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.
Nitpick: maybe use the same order as above for the loops? That allows easier comparison that the same variables are used in both.
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.
pub, sub, cli, srv, tmr, gc 1561483
rcl_guard_condition_t * gc = (rcl_guard_condition_t *)PyCapsule_GetPointer( | ||
pygc, "rcl_guard_condition_t"); | ||
if (!gc) { | ||
return NULL; |
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.
What is the expectation here? It should only return NULL
when an error is set, right? But PyCapsule_GetPointer
shouldn't set an error. Should a specific error message be set or should this return Py_RETURN_NONE
instead (which would be a silent failure, probably not?)?
Same below for various other pointers.
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.
PyCapsule_GetPointer
will raise an exception if the Capsule is not a valid capsule with a matching name. I think the assumption here is that the only reason for gc
to be NULL
is if PyCapsule_GetPointer
fails and thus an exception is already being set so we need to return NULL
.
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.
You are right, it does set an error when returning NULL
. Sorry for the noise - should have checked the docs before.
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.
LGTM
I found a few bugs in this PR, please hold before merging |
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.
lgtm, it would be great to rerun CI to make sure we didnt break anything along the way
@mikaelarguedas CI in progress edit: started again with d4048f6 |
CI green. squash/merging. |
} | ||
PyErr_Format(PyExc_RuntimeError, | ||
"Failed to create service: %s", rcl_get_error_string_safe()); | ||
Py_DECREF(service); |
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.
This line seems to be the reason for this new test failure: http://ci.ros2.org/view/nightly/job/nightly_win_deb/lastCompletedBuild/testReport/(root)/projectroot/rclpytests/
Naming capsules prevents calling the wrong kind of cleanup on a pointer. This also removes the string parameter from
rclpy_destroy_entity
andrclpy_destroy_node_entity
since it can be figured out from the capsule name.If a non-capsule or a capsule of the wrong type is specified, the functions let
PyCapsule_GetPointer
raise.