def results_to_json(res: Any) -> Optional[list[str]]: """Prepares action results into list of JSONs. Return value could be tuple or single value. :param res: :return: """ if res is None: return None if isinstance(res, tuple): return [plugin_from_instance(r).value_to_json(r) for r in res] else: return [plugin_from_instance(res).value_to_json(res)]
def test_plugin_from_instance() -> None: assert plugin_from_instance(Image.new("RGB", (320, 240))) is ImagePlugin
def test_plugin_from_instance(self, val: TestEnum) -> None: assert plugin_from_instance(val) is StringEnumPlugin
def test_plugin_from_instance() -> None: assert plugin_from_instance(Pose()) is PosePlugin
def test_plugin_from_instance(self, val: str) -> None: assert plugin_from_instance(val) is StringPlugin
def test_plugin_from_instance(self, val: bool) -> None: assert plugin_from_instance(val) is BooleanPlugin
def wrapper(obj: Generic, *action_args: Any, an: Optional[str] = None, **kwargs: Any) -> Any: # remembers the outermost action # when set, serves as a flag, that we are inside an action # ...then when another action is executed, we know that it is a nested one (and the outer one is composite) global _executed_action action_id: Optional[str] = None action_mapping_provided = hasattr(obj, ACTION_NAME_ID_MAPPING_ATTR) # if not set (e.g. when writing actions manually), do not attempt to get action IDs from names if action_mapping_provided: if _executed_action and an: raise Arcor2Exception( "Inner actions should not have name specified.") if not _executed_action: # do not attempt to get id for inner actions try: action_id = getattr(obj, ACTION_NAME_ID_MAPPING_ATTR)[an] except AttributeError: # mapping from action name to id not provided, ActionState won't be sent pass except KeyError: if an is None: raise Arcor2Exception( "Mapping from action name to id provided, but action name not set." ) raise Arcor2Exception( f"Mapping from action name to id is missing key {an}.") if _executed_action and not _executed_action[ 1].__action__.composite: # type: ignore msg = f"Outer action {_executed_action[1].__name__}/{_executed_action[0]} not flagged as composite." _executed_action = None raise Arcor2Exception(msg) if _executed_action is None: # the following code should be executed only for outermost action _executed_action = action_id, f # collect action point ids, ignore missing action_point_ids: set[str] = set() for aa in action_args: try: if isinstance(aa, (Pose, ProjectRobotJoints)): action_point_ids.add(getattr(aa, AP_ID_ATTR)) except AttributeError: if breakpoints: raise Arcor2Exception( "Orientations/Joints not patched. Breakpoints won't work!" ) # validate if break is required make_a_break = bool(breakpoints and breakpoints.intersection(action_point_ids)) # dispatch ActionStateBefore event for every (outermost) action state_before = ActionStateBefore( ActionStateBefore.Data( # TODO deal with kwargs parameters action_id, None, action_point_ids if action_point_ids else None, )) try: state_before.data.parameters = [ plugin_from_instance(arg).value_to_json(arg) for arg in action_args ] except Arcor2Exception: if action_id: # for projects with logic, it should not happen that there is unknown parameter type # for projects without logic (for which we don't know action_id), it is fine... _executed_action = None raise print_event(state_before) handle_stdin_commands(before=True, breakpoint=make_a_break) # the action itself is executed under all circumstances try: res = f(obj, *action_args, an=an, **kwargs) except Arcor2Exception: # this is actually not necessary at the moment as when exception is raised, the script ends anyway _executed_action = None # TODO maybe print ProjectException from here instead of from Resources' context manager? # ...could provide action_id from here raise # manage situation when we are getting out of (composite) action if action_mapping_provided: # for projects with logic - check based on action_id if action_id and _executed_action[0] == action_id: _executed_action = None print_event( ActionStateAfter( ActionStateAfter.Data(action_id, results_to_json(res)))) else: # for projects without logic - can be only based on checking the method if _executed_action[1] == f: # TODO shouldn't we sent ActionStateAfter even here? _executed_action = None handle_stdin_commands(before=False) return res
def test_plugin_from_instance() -> None: assert plugin_from_instance(ProjectRobotJoints("name", "robot_id", [Joint("name", 0.333)])) is JointsPlugin
def wrapper(*args: Union[Generic, Any], an: Optional[str] = None, **kwargs: Any) -> Any: global _executed_action action_args = args[1:] action_id: Optional[str] = None if HANDLE_ACTIONS: # if not set, ignore everything if _executed_action and an: raise Arcor2Exception("Inner actions should not have name specified.") if not _executed_action: # do not attempt to get id for inner actions try: action_id = args[0].action_name_to_id[an] # type: ignore except AttributeError: # mapping from action name to id not provided, ActionState won't be sent pass except KeyError: if an is None: raise Arcor2Exception("Mapping from action name to id provided, but action name not set.") raise Arcor2Exception(f"Mapping from action name to id is missing key {an}.") if _executed_action and not _executed_action[1].__action__.composite: # type: ignore msg = f"Outer action {_executed_action[1].__name__}/{_executed_action[0]} not flagged as composite." _executed_action = None raise Arcor2Exception(msg) if action_id: # can't do much without action_id print_event( ActionStateBefore( ActionStateBefore.Data( # TODO deal with kwargs parameters action_id, [plugin_from_instance(arg).value_to_json(arg) for arg in action_args], ) ) ) if _executed_action is None: _executed_action = action_id, f handle_stdin_commands() try: res = f(*args, an=an, **kwargs) except Arcor2Exception: # this is actually not necessary at the moment as when exception is raised, the script ends anyway _executed_action = None # TODO maybe print ProjectException from here instead of from Resources' context manager? # ...could provide action_id from here raise if HANDLE_ACTIONS: if action_id: # we are getting out of (composite) action if _executed_action and _executed_action[0] == action_id: _executed_action = None print_event(ActionStateAfter(ActionStateAfter.Data(action_id, results_to_json(res)))) handle_stdin_commands() return res