From 89993023bd613cd918d26da4ed4bee5608194337 Mon Sep 17 00:00:00 2001 From: Michael Carlstrom Date: Wed, 7 Aug 2024 16:35:14 -0400 Subject: [PATCH] minor improvements (#1330) Signed-off-by: Michael Carlstrom --- rclpy/rclpy/client.py | 24 +++++++++++++----------- rclpy/rclpy/node.py | 4 ++-- rclpy/rclpy/service.py | 6 +++--- rclpy/rclpy/type_support.py | 3 +-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/rclpy/rclpy/client.py b/rclpy/rclpy/client.py index b5d53258a..cba396a1f 100644 --- a/rclpy/rclpy/client.py +++ b/rclpy/rclpy/client.py @@ -41,7 +41,7 @@ def __init__( self, context: Context, client_impl: _rclpy.Client, - srv_type: Srv[SrvRequestT, SrvResponseT, SrvEventT], + srv_type: Type[Srv[SrvRequestT, SrvResponseT, SrvEventT]], srv_name: str, qos_profile: QoSProfile, callback_group: CallbackGroup @@ -66,7 +66,7 @@ def __init__( self.srv_name = srv_name self.qos_profile = qos_profile # Key is a sequence number, value is an instance of a Future - self._pending_requests: Dict[int, Future] = {} + self._pending_requests: Dict[int, Future[SrvResponseT]] = {} self.callback_group = callback_group # True when the callback is ready to fire but has not been "taken" by an executor self._executor_event = False @@ -95,7 +95,7 @@ def call( event = threading.Event() - def unblock(future): + def unblock(future: Future[SrvResponseT]) -> None: nonlocal event event.set() @@ -109,11 +109,13 @@ def unblock(future): if not event.wait(timeout_sec): # Timed out. remove_pending_request() to free resources self.remove_pending_request(future) - if future.exception() is not None: - raise future.exception() + + exception = future.exception() + if exception is not None: + raise exception return future.result() - def call_async(self, request: SrvRequestT) -> Future: + def call_async(self, request: SrvRequestT) -> Future[SrvResponseT]: """ Make a service request and asynchronously get the result. @@ -132,14 +134,14 @@ def call_async(self, request: SrvRequestT) -> Future: if sequence_number in self._pending_requests: raise RuntimeError(f'Sequence ({sequence_number}) conflicts with pending request') - future = Future() + future = Future[SrvResponseT]() self._pending_requests[sequence_number] = future future.add_done_callback(self.remove_pending_request) return future - def get_pending_request(self, sequence_number: int) -> Future: + def get_pending_request(self, sequence_number: int) -> Future[SrvResponseT]: """ Get a future from the list of pending requests. @@ -150,7 +152,7 @@ def get_pending_request(self, sequence_number: int) -> Future: with self._lock: return self._pending_requests[sequence_number] - def remove_pending_request(self, future: Future) -> None: + def remove_pending_request(self, future: Future[SrvResponseT]) -> None: """ Remove a future from the list of pending requests. @@ -220,7 +222,7 @@ def service_name(self) -> str: with self.handle: return self.__client.service_name - def destroy(self): + def destroy(self) -> None: """ Destroy a container for a ROS service client. @@ -229,7 +231,7 @@ def destroy(self): """ self.__client.destroy_when_not_in_use() - def __enter__(self) -> 'Client': + def __enter__(self) -> 'Client[SrvRequestT, SrvResponseT, SrvEventT]': return self def __exit__( diff --git a/rclpy/rclpy/node.py b/rclpy/rclpy/node.py index a70f1d7c3..75cd3b241 100644 --- a/rclpy/rclpy/node.py +++ b/rclpy/rclpy/node.py @@ -1677,7 +1677,7 @@ def create_subscription( def create_client( self, - srv_type: Srv[SrvRequestT, SrvResponseT, SrvEventT], + srv_type: Type[Srv[SrvRequestT, SrvResponseT, SrvEventT]], srv_name: str, *, qos_profile: QoSProfile = qos_profile_services_default, @@ -1719,7 +1719,7 @@ def create_client( def create_service( self, - srv_type: Srv[SrvRequestT, SrvResponseT, SrvEventT], + srv_type: Type[Srv[SrvRequestT, SrvResponseT, SrvEventT]], srv_name: str, callback: Callable[[SrvRequestT, SrvResponseT], SrvResponseT], *, diff --git a/rclpy/rclpy/service.py b/rclpy/rclpy/service.py index 78a004dac..bc13940cf 100644 --- a/rclpy/rclpy/service.py +++ b/rclpy/rclpy/service.py @@ -36,7 +36,7 @@ class Service(Generic[SrvRequestT, SrvResponseT, SrvEventT]): def __init__( self, service_impl: _rclpy.Service, - srv_type: Srv[SrvRequestT, SrvResponseT, SrvEventT], + srv_type: Type[Srv[SrvRequestT, SrvResponseT, SrvEventT]], srv_name: str, callback: Callable[[SrvRequestT, SrvResponseT], SrvResponseT], callback_group: CallbackGroup, @@ -112,7 +112,7 @@ def service_name(self) -> str: with self.handle: return self.__service.name - def destroy(self): + def destroy(self) -> None: """ Destroy a container for a ROS service server. @@ -121,7 +121,7 @@ def destroy(self): """ self.__service.destroy_when_not_in_use() - def __enter__(self) -> 'Service': + def __enter__(self) -> 'Service[SrvRequestT, SrvResponseT, SrvEventT]': return self def __exit__( diff --git a/rclpy/rclpy/type_support.py b/rclpy/rclpy/type_support.py index a06891127..f13ad8415 100644 --- a/rclpy/rclpy/type_support.py +++ b/rclpy/rclpy/type_support.py @@ -66,8 +66,7 @@ class Srv(Protocol[SrvRequestT, SrvResponseT, SrvEventT], metaclass=CommonMsgSrv Response: Type[SrvResponseT] Event: Type[SrvEventT] - def __init__(self) -> NoReturn: - ... + def __init__(self) -> NoReturn: ... # Can be used if https://github.com/python/typing/issues/548 ever gets approved.