1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15+ from types import TracebackType
16+ from typing import Any , Generic , List , Optional , Type , TYPE_CHECKING , TypeVar
17+
18+
19+ from rclpy .impl .implementation_singleton import rclpy_implementation as _rclpy
20+
21+ T = TypeVar ('T' )
22+
23+
24+ if TYPE_CHECKING :
25+ from typing_extensions import Self
26+
27+ from rclpy .callback_groups import CallbackGroup
28+ from rclpy .task import Future
29+
1530
1631class NumberOfEntities :
1732
@@ -24,8 +39,8 @@ class NumberOfEntities:
2439 'num_events' ]
2540
2641 def __init__ (
27- self , num_subs = 0 , num_gcs = 0 , num_timers = 0 ,
28- num_clients = 0 , num_services = 0 , num_events = 0
42+ self , num_subs : int = 0 , num_gcs : int = 0 , num_timers : int = 0 ,
43+ num_clients : int = 0 , num_services : int = 0 , num_events : int = 0
2944 ):
3045 self .num_subscriptions = num_subs
3146 self .num_guard_conditions = num_gcs
@@ -34,7 +49,7 @@ def __init__(
3449 self .num_services = num_services
3550 self .num_events = num_events
3651
37- def __add__ (self , other ) :
52+ def __add__ (self , other : 'NumberOfEntities' ) -> 'NumberOfEntities' :
3853 result = self .__class__ ()
3954 result .num_subscriptions = self .num_subscriptions + other .num_subscriptions
4055 result .num_guard_conditions = self .num_guard_conditions + other .num_guard_conditions
@@ -44,7 +59,7 @@ def __add__(self, other):
4459 result .num_events = self .num_events + other .num_events
4560 return result
4661
47- def __iadd__ (self , other ) :
62+ def __iadd__ (self , other : 'NumberOfEntities' ) -> 'NumberOfEntities' :
4863 self .num_subscriptions += other .num_subscriptions
4964 self .num_guard_conditions += other .num_guard_conditions
5065 self .num_timers += other .num_timers
@@ -53,59 +68,64 @@ def __iadd__(self, other):
5368 self .num_events += other .num_events
5469 return self
5570
56- def __repr__ (self ):
71+ def __repr__ (self ) -> str :
5772 return '<{0}({1}, {2}, {3}, {4}, {5}, {6})>' .format (
5873 self .__class__ .__name__ , self .num_subscriptions ,
5974 self .num_guard_conditions , self .num_timers , self .num_clients ,
6075 self .num_services , self .num_events )
6176
6277
63- class Waitable :
78+ class Waitable ( Generic [ T ]) :
6479 """
6580 Add something to a wait set and execute it.
6681
6782 This class wraps a collection of entities which can be added to a wait set.
6883 """
6984
70- def __init__ (self , callback_group ):
85+ def __init__ (self , callback_group : 'CallbackGroup' ):
7186 # A callback group to control when this entity can execute (used by Executor)
7287 self .callback_group = callback_group
7388 self .callback_group .add_entity (self )
7489 # Flag set by executor when a handler has been created but not executed (used by Executor)
7590 self ._executor_event = False
7691 # List of Futures that have callbacks needing execution
77- self ._futures = []
92+ self ._futures : List [ Future [ Any ]] = []
7893
79- def __enter__ (self ):
94+ def __enter__ (self ) -> 'Self' :
8095 """Implement to mark entities as in-use to prevent destruction while waiting on them."""
81- pass
96+ raise NotImplementedError ( 'Must be implemented by subclass' )
8297
83- def __exit__ (self , t , v , tb ):
98+ def __exit__ (
99+ self ,
100+ exc_type : Optional [Type [BaseException ]],
101+ exc_val : Optional [BaseException ],
102+ exc_tb : Optional [TracebackType ],
103+ ) -> None :
84104 """Implement to mark entities as not-in-use to allow destruction after waiting on them."""
85- pass
105+ raise NotImplementedError ( 'Must be implemented by subclass' )
86106
87- def add_future (self , future ) :
107+ def add_future (self , future : 'Future[Any]' ) -> None :
88108 self ._futures .append (future )
89109
90- def remove_future (self , future ) :
110+ def remove_future (self , future : 'Future[Any]' ) -> None :
91111 self ._futures .remove (future )
92112
93- def is_ready (self , wait_set ) :
113+ def is_ready (self , wait_set : _rclpy . WaitSet ) -> bool :
94114 """Return True if entities are ready in the wait set."""
95115 raise NotImplementedError ('Must be implemented by subclass' )
96116
97- def take_data (self ):
117+ def take_data (self ) -> T :
98118 """Take stuff from lower level so the wait set doesn't immediately wake again."""
99119 raise NotImplementedError ('Must be implemented by subclass' )
100120
101- async def execute (self , taken_data ) :
121+ async def execute (self , taken_data : T ) -> None :
102122 """Execute work after data has been taken from a ready wait set."""
103123 raise NotImplementedError ('Must be implemented by subclass' )
104124
105- def get_num_entities (self ):
125+ def get_num_entities (self ) -> NumberOfEntities :
106126 """Return number of each type of entity used."""
107127 raise NotImplementedError ('Must be implemented by subclass' )
108128
109- def add_to_wait_set (self , wait_set ) :
129+ def add_to_wait_set (self , wait_set : _rclpy . WaitSet ) -> None :
110130 """Add entities to wait set."""
111131 raise NotImplementedError ('Must be implemented by subclass' )
0 commit comments