import inspect import warnings from typing import Callable from UniTAP.dev.modules.opf.handlers.base import OpfHandlerBase, OPFDialogAnswer,\ WrongOPFFunctionSignature from UniTAP.dev.modules.opf.parsers import OPFParametersParser class OpfHandlerDefault(OpfHandlerBase): """ Class `OpfHandlerDefault` inherit functionality from `OpfHandlerBase` and allows overriding opf functions. Function `assign_function_for_opf_id` allows doing it. """ def __init__(self): super().__init__() self.__user_callback_dict = {} self.__parser = OPFParametersParser() def handle(self, opf_id, reply_answer, *args) -> OPFDialogAnswer: base_opf_handler = super()._is_opf_processed(opf_id) user_opf_handler = self.__user_callback_dict.get(opf_id, None) is not None if not user_opf_handler and not base_opf_handler: warnings.warn(f"Test requested operator feedback dialog with id: {opf_id}, but user " f"function was not provided. Test will be aborted.") return reply_answer(OPFDialogAnswer.ABORT) if user_opf_handler: opf_params_for_user = self.__parser.parse(opf_id, *args) return reply_answer(self.__user_callback_dict.get(opf_id, None)(*opf_params_for_user)) else: return super().handle(opf_id, reply_answer, *args) def assign_function_for_opf_id(self, opf_id: int, func: Callable): """ Assign new function for doing required actions from OPF. Arguments: opf_id (`int`) - id of OPF. func (`Callable`) - object of function """ signature = inspect.getfullargspec(func) if signature.annotations['return'] != OPFDialogAnswer: raise WrongOPFFunctionSignature(f"Function MUST declare {OPFDialogAnswer} " f"as return value") self.__user_callback_dict[opf_id] = func