From 498f712cee140d14af142c7fd249408740d97223 Mon Sep 17 00:00:00 2001 From: Michael Carlstrom Date: Mon, 6 Oct 2025 21:45:38 -0700 Subject: [PATCH] Update to use new BaseImpl Signed-off-by: Michael Carlstrom --- rosidl_generator_py/package.xml | 1 + rosidl_generator_py/resource/_action.py.em | 44 +++++++++++++--------- rosidl_generator_py/resource/_srv.py.em | 18 +++++++-- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/rosidl_generator_py/package.xml b/rosidl_generator_py/package.xml index 19ad032c..6d931c7c 100644 --- a/rosidl_generator_py/package.xml +++ b/rosidl_generator_py/package.xml @@ -41,6 +41,7 @@ ament_index_python python3-numpy + python3-typing-extensions rosidl_cli rosidl_generator_c rosidl_parser diff --git a/rosidl_generator_py/resource/_action.py.em b/rosidl_generator_py/resource/_action.py.em index 50167f34..0a081993 100644 --- a/rosidl_generator_py/resource/_action.py.em +++ b/rosidl_generator_py/resource/_action.py.em @@ -79,32 +79,42 @@ class Metaclass_@(action.namespaced_type.name)(rosidl_pycommon.interface_base_cl @(module_name).Metaclass_@(action.feedback_message.structure.namespaced_type.name).__import_type_support__() +class _@(action.namespaced_type.name)_Impl(rosidl_pycommon.interface_base_classes.BaseImpl[ + @(action.send_goal_service.namespaced_type.name), + @(action.get_result_service.namespaced_type.name), + @(action.feedback_message.structure.namespaced_type.name) +]): + + # The send_goal service using a wrapped version of the goal message as a request. + SendGoalService: TypeAlias = @(action.send_goal_service.namespaced_type.name) + # The get_result service using a wrapped version of the result message as a response. + GetResultService: TypeAlias = @(action.get_result_service.namespaced_type.name) + # The feedback message with generic fields which wraps the feedback message. + FeedbackMessage: TypeAlias = @(action.feedback_message.structure.namespaced_type.name) + + # The generic service to cancel a goal. + from action_msgs.srv._cancel_goal import CancelGoal + CancelGoalService: TypeAlias = CancelGoal + # The generic message for get the status of a goal. + from action_msgs.msg._goal_status_array import GoalStatusArray + GoalStatusMessage: TypeAlias = GoalStatusArray + + class @(action.namespaced_type.name)(rosidl_pycommon.interface_base_classes.BaseAction[ @(action.goal.structure.namespaced_type.name), @(action.result.structure.namespaced_type.name), - @(action.feedback.structure.namespaced_type.name) + @(action.feedback.structure.namespaced_type.name), + _@(action.namespaced_type.name)_Impl ], metaclass=Metaclass_@(action.namespaced_type.name)): # The goal message defined in the action definition. - Goal: type[@(action.goal.structure.namespaced_type.name)] = @(action.goal.structure.namespaced_type.name) + Goal: TypeAlias = @(action.goal.structure.namespaced_type.name) # The result message defined in the action definition. - Result: type[@(action.result.structure.namespaced_type.name)] = @(action.result.structure.namespaced_type.name) + Result: TypeAlias = @(action.result.structure.namespaced_type.name) # The feedback message defined in the action definition. - Feedback: type[@(action.feedback.structure.namespaced_type.name)] = @(action.feedback.structure.namespaced_type.name) - - class Impl: - - # The send_goal service using a wrapped version of the goal message as a request. - from @('.'.join(action.namespaced_type.namespaces)).@(module_name) import @(action.send_goal_service.namespaced_type.name) as SendGoalService - # The get_result service using a wrapped version of the result message as a response. - from @('.'.join(action.namespaced_type.namespaces)).@(module_name) import @(action.get_result_service.namespaced_type.name) as GetResultService - # The feedback message with generic fields which wraps the feedback message. - from @('.'.join(action.namespaced_type.namespaces)).@(module_name) import @(action.feedback_message.structure.namespaced_type.name) as FeedbackMessage + Feedback: TypeAlias = @(action.feedback.structure.namespaced_type.name) - # The generic service to cancel a goal. - from action_msgs.srv._cancel_goal import CancelGoal as CancelGoalService - # The generic message for get the status of a goal. - from action_msgs.msg._goal_status_array import GoalStatusArray as GoalStatusMessage + Impl: TypeAlias = _@(action.namespaced_type.name)_Impl # Should eventually be typing.NoReturn. See mypy#14044 def __init__(self) -> None: diff --git a/rosidl_generator_py/resource/_srv.py.em b/rosidl_generator_py/resource/_srv.py.em index 7ac6e12e..3320ff22 100644 --- a/rosidl_generator_py/resource/_srv.py.em +++ b/rosidl_generator_py/resource/_srv.py.em @@ -23,6 +23,18 @@ TEMPLATE( package_name=package_name, interface_path=interface_path, message=service.event_message, import_statements=import_statements, type_annotations_import_statements=type_annotations_import_statements) + +# Can be removed in rhel10 since TypeAlias will exist in typing +TYPE_ALIAS_IMPORT = 'from typing_extensions import TypeAlias' +}@ +@[if TYPE_ALIAS_IMPORT not in type_annotations_import_statements]@ + + +if typing.TYPE_CHECKING: + @(TYPE_ALIAS_IMPORT) +@[end if]@ +@{ +type_annotations_import_statements.add(TYPE_ALIAS_IMPORT) }@ @@ -60,9 +72,9 @@ class @(service.namespaced_type.name)(rosidl_pycommon.interface_base_classes.Bas @(service.request_message.structure.namespaced_type.name), @(service.response_message.structure.namespaced_type.name) ], metaclass=Metaclass_@(service.namespaced_type.name)): - Request: type[@(service.request_message.structure.namespaced_type.name)] = @(service.request_message.structure.namespaced_type.name) - Response: type[@(service.response_message.structure.namespaced_type.name)] = @(service.response_message.structure.namespaced_type.name) - from @('.'.join(service.namespaced_type.namespaces)).@(module_name) import @(service.event_message.structure.namespaced_type.name) as Event + Request: TypeAlias = @(service.request_message.structure.namespaced_type.name) + Response: TypeAlias = @(service.response_message.structure.namespaced_type.name) + Event: TypeAlias = @(service.event_message.structure.namespaced_type.name) # Should eventually be typing.NoReturn. See mypy#14044 def __init__(self) -> None: