diff --git a/rclpy/rclpy/impl/_rclpy_pybind11.pyi b/rclpy/rclpy/impl/_rclpy_pybind11.pyi index 75427df4d..0570c430c 100644 --- a/rclpy/rclpy/impl/_rclpy_pybind11.pyi +++ b/rclpy/rclpy/impl/_rclpy_pybind11.pyi @@ -14,7 +14,7 @@ from __future__ import annotations -from enum import IntEnum +from enum import Enum, IntEnum from types import TracebackType from typing import Any, Generic, Literal, overload, Sequence, TypedDict @@ -333,3 +333,31 @@ class WaitSet(Destroyable): def wait(self, timeout: int) -> None: """Wait until timeout is reached or event happened.""" + + +class SignalHandlerOptions(Enum): + _value_: int + NO = ... + SigInt = ... + SigTerm = ... + All = ... + + +def register_sigint_guard_condition(guard_condition: GuardCondition) -> None: + """Register a guard condition to be called on SIGINT.""" + + +def unregister_sigint_guard_condition(guard_condition: GuardCondition) -> None: + """Stop triggering a guard condition when SIGINT occurs.""" + + +def install_signal_handlers(options: SignalHandlerOptions) -> None: + """Install rclpy signal handlers.""" + + +def get_current_signal_handlers_options() -> SignalHandlerOptions: + """Get currently installed signal handler options.""" + + +def uninstall_signal_handlers() -> None: + """Uninstall rclpy signal handlers.""" diff --git a/rclpy/rclpy/signals.py b/rclpy/rclpy/signals.py index 5c6162508..1c54f06a8 100644 --- a/rclpy/rclpy/signals.py +++ b/rclpy/rclpy/signals.py @@ -11,26 +11,31 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from typing import Optional, TYPE_CHECKING from rclpy.exceptions import InvalidHandle from rclpy.guard_condition import GuardCondition from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy +if TYPE_CHECKING: + from typing import TypeAlias + + from rclpy.context import Context # re-export SignalHandlerOptions enum -SignalHandlerOptions = _rclpy.SignalHandlerOptions +SignalHandlerOptions: 'TypeAlias' = _rclpy.SignalHandlerOptions -def install_signal_handlers(options: SignalHandlerOptions = SignalHandlerOptions.ALL): +def install_signal_handlers(options: SignalHandlerOptions = SignalHandlerOptions.ALL) -> None: """ Install rclpy signal handlers. :param options: Indicate if to install sigint, sigterm, both or no signal handler. """ - return _rclpy.install_signal_handlers(options) + _rclpy.install_signal_handlers(options) -def get_current_signal_handlers_options(): +def get_current_signal_handlers_options() -> SignalHandlerOptions: """ Get current signal handler options. @@ -39,19 +44,19 @@ def get_current_signal_handlers_options(): return _rclpy.get_current_signal_handlers_options() -def uninstall_signal_handlers(): +def uninstall_signal_handlers() -> None: """Uninstall the rclpy signal handlers.""" _rclpy.uninstall_signal_handlers() class SignalHandlerGuardCondition(GuardCondition): - def __init__(self, context=None): + def __init__(self, context: 'Optional[Context]' = None) -> None: super().__init__(callback=None, callback_group=None, context=context) with self.handle: _rclpy.register_sigint_guard_condition(self.handle) - def __del__(self): + def __del__(self) -> None: try: self.destroy() except InvalidHandle: @@ -61,7 +66,7 @@ def __del__(self): # Guard condition was not registered pass - def destroy(self): + def destroy(self) -> None: with self.handle: _rclpy.unregister_sigint_guard_condition(self.handle) super().destroy()