|  | 
| 28 | 28 | 
 | 
| 29 | 29 | import launch.logging | 
| 30 | 30 | 
 | 
| 31 |  | - | 
|  | 31 | +from .opaque_function import OpaqueFunction | 
| 32 | 32 | from .set_launch_configuration import SetLaunchConfiguration | 
| 33 | 33 | from ..action import Action | 
| 34 | 34 | from ..frontend import Entity | 
| @@ -212,13 +212,7 @@ def execute(self, context: LaunchContext) -> List[Union[SetLaunchConfiguration, | 
| 212 | 212 |                                                             LaunchDescriptionEntity]]: | 
| 213 | 213 |         """Execute the action.""" | 
| 214 | 214 |         launch_description = self.__launch_description_source.get_launch_description(context) | 
| 215 |  | -        # If the location does not exist, then it's likely set to '<script>' or something. | 
| 216 |  | -        context.extend_locals({ | 
| 217 |  | -            'current_launch_file_path': self._get_launch_file(), | 
| 218 |  | -        }) | 
| 219 |  | -        context.extend_locals({ | 
| 220 |  | -            'current_launch_file_directory': self._get_launch_file_directory(), | 
| 221 |  | -        }) | 
|  | 215 | +        self._set_launch_file_location_locals(context) | 
| 222 | 216 | 
 | 
| 223 | 217 |         # Do best effort checking to see if non-optional, non-default declared arguments | 
| 224 | 218 |         # are being satisfied. | 
| @@ -255,7 +249,45 @@ def execute(self, context: LaunchContext) -> List[Union[SetLaunchConfiguration, | 
| 255 | 249 |             set_launch_configuration_actions.append(SetLaunchConfiguration(name, value)) | 
| 256 | 250 | 
 | 
| 257 | 251 |         # Set launch arguments as launch configurations and then include the launch description. | 
| 258 |  | -        return [*set_launch_configuration_actions, launch_description] | 
|  | 252 | +        return [ | 
|  | 253 | +            *set_launch_configuration_actions, | 
|  | 254 | +            launch_description, | 
|  | 255 | +            OpaqueFunction(function=self._restore_launch_file_location_locals), | 
|  | 256 | +        ] | 
|  | 257 | + | 
|  | 258 | +    def _set_launch_file_location_locals(self, context: LaunchContext) -> None: | 
|  | 259 | +        context._push_locals() | 
|  | 260 | +        # Keep the previous launch file path/dir locals so that we can restore them after | 
|  | 261 | +        context_locals = context.get_locals_as_dict() | 
|  | 262 | +        self.__previous_launch_file_path = context_locals.get('current_launch_file_path', None) | 
|  | 263 | +        self.__previous_launch_file_dir = context_locals.get('current_launch_file_directory', None) | 
|  | 264 | +        context.extend_locals({ | 
|  | 265 | +            'current_launch_file_path': self._get_launch_file(), | 
|  | 266 | +        }) | 
|  | 267 | +        context.extend_locals({ | 
|  | 268 | +            'current_launch_file_directory': self._get_launch_file_directory(), | 
|  | 269 | +        }) | 
|  | 270 | + | 
|  | 271 | +    def _restore_launch_file_location_locals(self, context: LaunchContext) -> None: | 
|  | 272 | +        # We want to keep the state of the context locals even after the include, since included | 
|  | 273 | +        # launch descriptions are meant to act as if they were included literally in the parent | 
|  | 274 | +        # launch description. | 
|  | 275 | +        # However, we want to restore the launch file path/dir locals to their previous state, and | 
|  | 276 | +        # we may have to just delete them if we're now going back to a launch script (i.e., not a | 
|  | 277 | +        # launch file). However, there is no easy way to delete context locals, so save current | 
|  | 278 | +        # locals, reset to the state before the include previous state and then re-apply locals, | 
|  | 279 | +        # potentially minus the launch file path/dir locals. | 
|  | 280 | +        context_locals = context.get_locals_as_dict() | 
|  | 281 | +        if self.__previous_launch_file_path is None: | 
|  | 282 | +            del context_locals['current_launch_file_path'] | 
|  | 283 | +        else: | 
|  | 284 | +            context_locals['current_launch_file_path'] = self.__previous_launch_file_path | 
|  | 285 | +        if self.__previous_launch_file_dir is None: | 
|  | 286 | +            del context_locals['current_launch_file_directory'] | 
|  | 287 | +        else: | 
|  | 288 | +            context_locals['current_launch_file_directory'] = self.__previous_launch_file_dir | 
|  | 289 | +        context._pop_locals() | 
|  | 290 | +        context.extend_locals(context_locals) | 
| 259 | 291 | 
 | 
| 260 | 292 |     def __repr__(self) -> Text: | 
| 261 | 293 |         """Return a description of this IncludeLaunchDescription as a string.""" | 
|  | 
0 commit comments