From 24aa75eb37480872e16819b8c92030cac45f99e4 Mon Sep 17 00:00:00 2001 From: kolo Date: Sun, 1 Feb 2026 00:26:25 +0300 Subject: [PATCH] viewr --- docs/code_snippets/testing/app_e2e_test.py | 2 +- metrics/__main__.py | 3 +- mock/local_test.py | 3 + src/argenta/app/behavior_handlers/entity.py | 4 +- src/argenta/app/dividing_line/models.py | 8 +- src/argenta/app/models.py | 128 ++++-------------- src/argenta/app/presentation/renderers.py | 18 +-- src/argenta/app/presentation/viewers.py | 73 +++++++++- src/argenta/router/entity.py | 98 +++++++------- ...t_system_handling_non_standard_behavior.py | 18 +-- .../test_system_handling_normal_behavior.py | 18 +-- 11 files changed, 187 insertions(+), 186 deletions(-) diff --git a/docs/code_snippets/testing/app_e2e_test.py b/docs/code_snippets/testing/app_e2e_test.py index 6d0d4a9..10a3be7 100644 --- a/docs/code_snippets/testing/app_e2e_test.py +++ b/docs/code_snippets/testing/app_e2e_test.py @@ -19,7 +19,7 @@ def test_input_incorrect_command(capsys: CaptureFixture[str]): def test(response: Response) -> None: print('test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) app.set_unknown_command_handler( lambda command: print(f'Unknown command: {command.trigger}') diff --git a/metrics/__main__.py b/metrics/__main__.py index 48a38af..803eced 100644 --- a/metrics/__main__.py +++ b/metrics/__main__.py @@ -1,8 +1,9 @@ from argenta import App, Orchestrator +from argenta.app import DynamicDividingLine from .handlers import router -app = App(initial_message="metrics", override_system_messages=False) +app = App(initial_message="metrics", dividing_line=DynamicDividingLine('~'), override_system_messages=True) orchestrator = Orchestrator() diff --git a/mock/local_test.py b/mock/local_test.py index e69de29..dae5011 100644 --- a/mock/local_test.py +++ b/mock/local_test.py @@ -0,0 +1,3 @@ +from rich.console import Console + +Console().print('[red]hi[/red]') \ No newline at end of file diff --git a/src/argenta/app/behavior_handlers/entity.py b/src/argenta/app/behavior_handlers/entity.py index 3e14fcf..db195e2 100644 --- a/src/argenta/app/behavior_handlers/entity.py +++ b/src/argenta/app/behavior_handlers/entity.py @@ -1,6 +1,6 @@ from rich.markup import escape -from argenta import Response +from argenta.response.entity import Response from argenta.app.presentation.renderers import Renderer from argenta.app.protocols import ( NonStandardBehaviorHandler, @@ -53,7 +53,7 @@ class BehaviorHandlersFabric: return unknown_command_handler def generate_exit_command_handler(self, farewell_message: str) -> NonStandardBehaviorHandler[Response]: - return lambda _: self._printer(self._renderer.render_farewell_message(farewell_message)) + return lambda _: self._printer(farewell_message) def generate_description_message_generator(self) -> DescriptionMessageGenerator: return lambda command, description: self._renderer.render_text_for_description_message_generator( diff --git a/src/argenta/app/dividing_line/models.py b/src/argenta/app/dividing_line/models.py index f64bbc1..52574ee 100644 --- a/src/argenta/app/dividing_line/models.py +++ b/src/argenta/app/dividing_line/models.py @@ -41,9 +41,9 @@ class StaticDividingLine(BaseDividingLine): :return: full line of dividing line as str """ if is_override: - return f"\n{self.length * self.get_unit_part()}\n" + return self.length * self.get_unit_part() else: - return f"\n[dim]{self.length * self.get_unit_part()}[/dim]\n" + return f"[dim]{self.length * self.get_unit_part()}[/dim]" class DynamicDividingLine(BaseDividingLine): @@ -63,6 +63,6 @@ class DynamicDividingLine(BaseDividingLine): :return: full line of dividing line as str """ if is_override: - return f"\n{length * self.get_unit_part()}\n" + return length * self.get_unit_part() else: - return f"\n[dim]{self.get_unit_part() * length}[/dim]\n" + return f"[dim]{self.get_unit_part() * length}[/dim]" diff --git a/src/argenta/app/models.py b/src/argenta/app/models.py index 17e6327..13d79e8 100644 --- a/src/argenta/app/models.py +++ b/src/argenta/app/models.py @@ -1,9 +1,6 @@ __all__ = ["App"] -import io -import re -from contextlib import redirect_stdout -from typing import Callable, Never, TypeAlias +from typing import Never, TypeAlias from rich.console import Console @@ -31,7 +28,6 @@ from argenta.router import Router Matches: TypeAlias = list[str] | list[Never] -_ANSI_ESCAPE_RE: re.Pattern[str] = re.compile(r"\u001b\[[0-9;]*m") class BaseApp: @@ -47,10 +43,10 @@ class BaseApp: repeat_command_groups_printing: bool, override_system_messages: bool, autocompleter: AutoCompleter, - print_func: Printer, + printer: Printer, ) -> None: self._prompt: str = prompt - self._print_func: Printer = print_func + self._printer: Printer = printer self._exit_command: Command = exit_command self._dividing_line: StaticDividingLine | DynamicDividingLine | None = dividing_line self._repeat_command_groups_printing: bool = repeat_command_groups_printing @@ -58,7 +54,6 @@ class BaseApp: self._autocompleter: AutoCompleter = autocompleter self._system_router: Router = Router(title=system_router_title) - self._stdout_buffer: io.StringIO = io.StringIO() self.registered_routers: RegisteredRouters = RegisteredRouters() self._messages_on_startup: list[str] = [] @@ -67,11 +62,16 @@ class BaseApp: else: self._renderer: Renderer = RichRenderer() - self._viewer: Viewer = Viewer(self._print_func, self._renderer) + self._viewer: Viewer = Viewer( + printer=self._printer, + renderer=self._renderer, + dividing_line=self._dividing_line, + override_system_messages=self._override_system_messages, + ) self._handlers_fabric: BehaviorHandlersFabric = BehaviorHandlersFabric( - self._print_func, - self._renderer, - self._most_similar_command + printer=self._printer, + renderer=self._renderer, + most_similar_command_getter=self._most_similar_command ) self._initial_message: str = self._renderer.render_initial_message(initial_message) @@ -131,34 +131,6 @@ class BaseApp: """ self._exit_command_handler = _ - def _print_static_framed_text(self, text: str) -> None: - """ - Private. Outputs text by framing it in a static or dynamic split strip - :param text: framed text - :return: None - """ - match self._dividing_line: - case StaticDividingLine() as dividing_line: - self._print_func(dividing_line.get_full_static_line(is_override=self._override_system_messages)) - print(text.strip("\n")) - self._print_func(dividing_line.get_full_static_line(is_override=self._override_system_messages)) - case DynamicDividingLine() as dividing_line: - self._print_func( - StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line( - is_override=self._override_system_messages - ) - ) - print(text.strip("\n")) - self._print_func( - StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line( - is_override=self._override_system_messages - ) - ) - case None: - print("\n" + text.strip("\n") + "\n") - case _: - raise NotImplementedError(f"Dividing line with type {self._dividing_line} is not implemented") - def _is_exit_command(self, command: InputCommand) -> bool: """ Private. Checks if the given command is an exit command @@ -178,18 +150,6 @@ class BaseApp: return True return False - def _capture_stdout(self, func: Callable[[], None]) -> str: - """ - Private. Captures stdout from a function call using a reusable buffer - :param func: function to execute with captured stdout - :return: captured stdout as string - """ - self._stdout_buffer.seek(0) - self._stdout_buffer.truncate(0) - with redirect_stdout(self._stdout_buffer): - func() - return self._stdout_buffer.getvalue() - def _error_handler(self, error: InputCommandException, raw_command: str) -> None: """ Private. Handles parsing errors of the entered command @@ -276,46 +236,14 @@ class BaseApp: if not processing_router: raise RuntimeError(f"Router for '{input_command.trigger}' not found. Panic!") - match (self._dividing_line, processing_router.disable_redirect_stdout): - case (None, bool()): - processing_router.finds_appropriate_handler(input_command) - case (DynamicDividingLine(), False): - stdout_result = self._capture_stdout(lambda: processing_router.finds_appropriate_handler(input_command)) - clear_text = _ANSI_ESCAPE_RE.sub("", stdout_result) - max_length_line = max([len(line) for line in clear_text.split("\n")]) - max_length_line = ( - max_length_line if 10 <= max_length_line <= 100 else 100 if max_length_line > 100 else 10 - ) - - self._print_func( - self._dividing_line.get_full_dynamic_line( - length=max_length_line, is_override=self._override_system_messages - ) - ) - print(clear_text.strip("\n")) - self._print_func( - self._dividing_line.get_full_dynamic_line( - length=max_length_line, is_override=self._override_system_messages - ) - ) - case (StaticDividingLine() as dividing_line, bool()) | (DynamicDividingLine() as dividing_line, True): - self._print_func( - StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line( - is_override=self._override_system_messages - ) - ) - processing_router.finds_appropriate_handler(input_command) - self._print_func( - StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line( - is_override=self._override_system_messages - ) - ) - case _: - raise NotImplementedError(f"Dividing line with type {self._dividing_line} is not implemented") + self._viewer.view_framed_text_from_generator( + output_text_generator=lambda: processing_router.finds_appropriate_handler(input_command), + is_stdout_redirected_by_router=processing_router.is_redirect_stdout_disabled + ) -AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine -DEFAULT_PRINT_FUNC: Printer = Console().print +AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine | None +DEFAULT_PRINTER: Printer = Console().print DEFAULT_EXIT_COMMAND: Command = Command("q", description="Exit command") @@ -328,11 +256,11 @@ class App(BaseApp): farewell_message: str = "See you", exit_command: Command = DEFAULT_EXIT_COMMAND, system_router_title: str = "System points:", - dividing_line: AVAILABLE_DIVIDING_LINES | None = None, + dividing_line: AVAILABLE_DIVIDING_LINES = None, repeat_command_groups_printing: bool = False, override_system_messages: bool = False, autocompleter: AutoCompleter | None = None, - print_func: Printer = DEFAULT_PRINT_FUNC, + printer: Printer = DEFAULT_PRINTER, ) -> None: """ Public. The essence of the application itself. @@ -346,7 +274,7 @@ class App(BaseApp): :param repeat_command_groups_printing: whether to repeat the available commands and their description :param override_system_messages: whether to redefine the default formatting of system messages :param autocompleter: the entity of the autocompleter - :param print_func: system messages text output function + :param printer: system messages text output function :return: None """ super().__init__( @@ -359,7 +287,7 @@ class App(BaseApp): repeat_command_groups_printing=repeat_command_groups_printing, override_system_messages=override_system_messages, autocompleter=autocompleter or AutoCompleter(), - print_func=print_func, + printer=printer, ) def run_polling(self) -> None: @@ -367,7 +295,7 @@ class App(BaseApp): Private. Starts the user input processing cycle :return: None """ - self._print_func(self._initial_message) + self._viewer.view_initial_message(self._initial_message) self._pre_cycle_setup() while True: if self._repeat_command_groups_printing: @@ -380,10 +308,9 @@ class App(BaseApp): try: input_command: InputCommand = InputCommand.parse(raw_command=raw_command) except InputCommandException as error: # noqa F841 - stderr_result = self._capture_stdout( - lambda: self._error_handler(error, raw_command) # noqa F821 + self._viewer.view_framed_text_from_generator( + output_text_generator=lambda: self._error_handler(error, raw_command) ) - self._print_static_framed_text(stderr_result) continue if self._is_exit_command(input_command): @@ -391,8 +318,9 @@ class App(BaseApp): return if self._is_unknown_command(input_command): - stdout_res = self._capture_stdout(lambda: self._unknown_command_handler(input_command)) - self._print_static_framed_text(stdout_res) + self._viewer.view_framed_text_from_generator( + output_text_generator=lambda: self._unknown_command_handler(input_command) + ) continue self._process_exist_and_valid_command(input_command) diff --git a/src/argenta/app/presentation/renderers.py b/src/argenta/app/presentation/renderers.py index 7e20d30..47ff1de 100644 --- a/src/argenta/app/presentation/renderers.py +++ b/src/argenta/app/presentation/renderers.py @@ -78,7 +78,7 @@ class RichRenderer(Renderer): @staticmethod def render_messages_on_startup(messages: Iterable[str]) -> str: - return "\n".join(messages) + return "\n" + "\n".join(messages) @staticmethod def render_command_groups_description( @@ -87,10 +87,10 @@ class RichRenderer(Renderer): ) -> str: command_groups_description = "" for registered_router in registered_routers: - command_groups_description += "\n" + registered_router.title + command_groups_description += "\n\n" + registered_router.title for command_handler in registered_router.command_handlers: handled_command = command_handler.handled_command - command_groups_description += description_message_generator( + command_groups_description += '\n' + description_message_generator( handled_command.trigger, handled_command.description, ) @@ -114,7 +114,7 @@ class RichRenderer(Renderer): most_similar_command_trigger: str | None ) -> str: return ( - f"[red]Unknown command:[/red][blue]{command_trigger}[/blue]" + f"[red]Unknown command:[/red] [blue]{command_trigger}[/blue]" + (f"[red], most similar:[/red][blue]{most_similar_command_trigger}[/blue]" if most_similar_command_trigger else "") ) @@ -131,14 +131,14 @@ class PlainRenderer(Renderer): @staticmethod def render_farewell_message(text: str) -> str: - return f"{text} | [https://github.com/koloideal/Argenta](https://github.com/koloideal/Argenta) | made by kolo" + return f"\n{text} | https://github.com/koloideal/Argenta | made by kolo" @staticmethod def render_text_for_description_message_generator(command: str, description: str) -> str: return f"{command} *=*=* {description}" def render_messages_on_startup(self, messages: Iterable[str]) -> str: - return "\n".join(messages) + return "\n" + "\n".join(messages) @staticmethod def render_command_groups_description( @@ -147,10 +147,10 @@ class PlainRenderer(Renderer): ) -> str: command_groups_description = "" for registered_router in registered_routers: - command_groups_description += "\n" + registered_router.title + command_groups_description += "\n\n" + registered_router.title for command_handler in registered_router.command_handlers: handled_command = command_handler.handled_command - command_groups_description += description_message_generator( + command_groups_description += "\n" + description_message_generator( handled_command.trigger, handled_command.description, ) @@ -175,7 +175,7 @@ class PlainRenderer(Renderer): ) -> str: return ( f"Unknown command: {command_trigger}" - + (f", most similar:{most_similar_command_trigger}" + + (f", most similar: {most_similar_command_trigger}" if most_similar_command_trigger else "") ) diff --git a/src/argenta/app/presentation/viewers.py b/src/argenta/app/presentation/viewers.py index decb547..a6698fe 100644 --- a/src/argenta/app/presentation/viewers.py +++ b/src/argenta/app/presentation/viewers.py @@ -1,14 +1,43 @@ -from typing import Iterable +__all__ = ["Viewer"] +import re +from contextlib import redirect_stdout +from io import StringIO +from typing import Iterable, Callable, TypeAlias + +from rich.text import Text + +from argenta.app import StaticDividingLine, DynamicDividingLine from argenta.app.presentation.renderers import Renderer from argenta.app.protocols import Printer, DescriptionMessageGenerator from argenta.app.registered_routers.entity import RegisteredRouters +AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine | None + + class Viewer: - def __init__(self, printer: Printer, renderer: Renderer): + ANSI_ESCAPE_RE: re.Pattern[str] = re.compile(r"\u001b\[[0-9;]*m") + + def __init__( + self, + printer: Printer, + renderer: Renderer, + dividing_line: AVAILABLE_DIVIDING_LINES, + override_system_messages: bool + ): self._printer = printer self._renderer = renderer + self._dividing_line = dividing_line + self._override_system_messages = override_system_messages + self._stdout_buffer: StringIO = StringIO() + + def _capture_stdout(self, func: Callable[[], None]) -> str: + self._stdout_buffer.seek(0) + self._stdout_buffer.truncate(0) + with redirect_stdout(self._stdout_buffer): + func() + return self._stdout_buffer.getvalue() def view_messages_on_startup(self, messages: Iterable[str]) -> None: self._printer(self._renderer.render_messages_on_startup(messages)) @@ -25,3 +54,43 @@ class Viewer: ) ) + def view_initial_message(self, initial_message: str) -> None: + self._printer(initial_message) + + def view_framed_text_from_generator( + self, + output_text_generator: Callable[[], None], + is_stdout_redirected_by_router: bool = False, + ) -> None: + match (self._dividing_line, is_stdout_redirected_by_router): + case (None, bool()): + output_text_generator() + case (DynamicDividingLine(), False): + stdout_result = self._capture_stdout( + lambda: output_text_generator() + ) + clear_text = self.ANSI_ESCAPE_RE.sub("", stdout_result) + max_length_line = max([len(line) for line in clear_text.split("\n")]) + max_length_line = ( + max_length_line + if 10 <= max_length_line <= 100 + else 100 + if max_length_line > 100 + else 10 + ) + dividing_line_as_str: str = self._dividing_line.get_full_dynamic_line( + length=max_length_line, is_override=self._override_system_messages + ) + self._printer(dividing_line_as_str + "\n") + self._printer(Text.from_ansi(stdout_result.strip("\n")).markup) + self._printer('\n' + dividing_line_as_str) + + case (StaticDividingLine() as dividing_line, bool()) | (DynamicDividingLine() as dividing_line, True): + dividing_line_as_str: str = StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line( + is_override=self._override_system_messages + ) + self._printer(dividing_line_as_str + '\n') + output_text_generator() + self._printer('\n' + dividing_line_as_str) + case _: + raise NotImplementedError(f"Dividing line with type {self._dividing_line} is not implemented") diff --git a/src/argenta/router/entity.py b/src/argenta/router/entity.py index d339639..9a6de00 100644 --- a/src/argenta/router/entity.py +++ b/src/argenta/router/entity.py @@ -35,7 +35,7 @@ class Router: :return: None """ self.title: str = title - self.disable_redirect_stdout: bool = disable_redirect_stdout + self.is_redirect_stdout_disabled: bool = disable_redirect_stdout self.command_handlers: CommandHandlers = CommandHandlers() self.aliases: set[str] = set() @@ -56,7 +56,7 @@ class Router: self._update_routing_keys(redefined_command) def decorator(func: HandlerFunc) -> HandlerFunc: - _validate_func_args(func) + self._validate_func_args(func) self.command_handlers.add_handler(CommandHandler(func, redefined_command)) return func @@ -116,7 +116,7 @@ class Router: handle_command = command_handler.handled_command if handle_command.registered_flags.flags: if input_command_flags.flags: - response: Response = _structuring_input_flags(handle_command, input_command_flags) + response: Response = self._structuring_input_flags(handle_command, input_command_flags) command_handler.handling(response) else: response = Response(ResponseStatus.ALL_FLAGS_VALID) @@ -133,53 +133,53 @@ class Router: response = Response(ResponseStatus.ALL_FLAGS_VALID) command_handler.handling(response) + @staticmethod + def _structuring_input_flags(handled_command: Command, input_flags: InputFlags) -> Response: + """ + Private. Validates flags of input command + :param handled_command: entity of the handled command + :param input_flags: + :return: entity of response as Response + """ + invalid_value_flags, undefined_flags = False, False -def _structuring_input_flags(handled_command: Command, input_flags: InputFlags) -> Response: - """ - Private. Validates flags of input command - :param handled_command: entity of the handled command - :param input_flags: - :return: entity of response as Response - """ - invalid_value_flags, undefined_flags = False, False + for flag in input_flags: + flag_status: ValidationStatus = handled_command.validate_input_flag(flag) + flag.status = flag_status + if flag_status == ValidationStatus.INVALID: + invalid_value_flags = True + elif flag_status == ValidationStatus.UNDEFINED: + undefined_flags = True - for flag in input_flags: - flag_status: ValidationStatus = handled_command.validate_input_flag(flag) - flag.status = flag_status - if flag_status == ValidationStatus.INVALID: - invalid_value_flags = True - elif flag_status == ValidationStatus.UNDEFINED: - undefined_flags = True - - status = ResponseStatus.from_flags( - has_invalid_value_flags=invalid_value_flags, - has_undefined_flags=undefined_flags - ) - - return Response(status=status, input_flags=input_flags) - - -def _validate_func_args(func: HandlerFunc) -> None: - """ - Private. Validates the arguments of the handler - :param func: entity of the handler func - :return: None if func is valid else raise exception - """ - transferred_args = getfullargspec(func).args - if len(transferred_args) == 0: - raise RequiredArgumentNotPassedException() - - response_arg: str = transferred_args[0] - func_annotations: dict[str, None] = get_annotations(func) - - response_arg_annotation = func_annotations.get(response_arg) - - if response_arg_annotation is not None and response_arg_annotation is not Response: - source_line: int = getsourcelines(func)[1] - Console().print( - f'\nFile "{getsourcefile(func)}", line {source_line}\n[b red]WARNING:[/b red] [i]The typehint ' - + f"of argument([green]{response_arg}[/green]) passed to the handler must be [/i][bold blue]{Response}[/bold blue]," - + f" [i]but[/i] [bold blue]{response_arg_annotation}[/bold blue] [i]is specified[/i]", - highlight=False, + status = ResponseStatus.from_flags( + has_invalid_value_flags=invalid_value_flags, + has_undefined_flags=undefined_flags ) + + return Response(status=status, input_flags=input_flags) + + @staticmethod + def _validate_func_args(func: HandlerFunc) -> None: + """ + Private. Validates the arguments of the handler + :param func: entity of the handler func + :return: None if func is valid else raise exception + """ + transferred_args = getfullargspec(func).args + if len(transferred_args) == 0: + raise RequiredArgumentNotPassedException() + + response_arg: str = transferred_args[0] + func_annotations: dict[str, None] = get_annotations(func) + + response_arg_annotation = func_annotations.get(response_arg) + + if response_arg_annotation is not None and response_arg_annotation is not Response: + source_line: int = getsourcelines(func)[1] + Console().print( + f'\nFile "{getsourcefile(func)}", line {source_line}\n[b red]WARNING:[/b red] [i]The typehint ' + + f"of argument([green]{response_arg}[/green]) passed to the handler must be [/i][bold blue]{Response}[/bold blue]," + + f" [i]but[/i] [bold blue]{response_arg_annotation}[/bold blue] [i]is specified[/i]", + highlight=False, + ) \ No newline at end of file diff --git a/tests/system_tests/test_system_handling_non_standard_behavior.py b/tests/system_tests/test_system_handling_non_standard_behavior.py index 5a489de..4a65aba 100644 --- a/tests/system_tests/test_system_handling_non_standard_behavior.py +++ b/tests/system_tests/test_system_handling_non_standard_behavior.py @@ -35,7 +35,7 @@ def test_empty_input_triggers_empty_command_handler(monkeypatch: pytest.MonkeyPa def test(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) app.set_empty_command_handler(lambda: print('Empty input command')) orchestrator.start_polling(app) @@ -61,7 +61,7 @@ def test_unknown_command_triggers_unknown_command_handler(monkeypatch: pytest.Mo def test(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) app.set_unknown_command_handler(lambda command: print(f'Unknown command: {command.trigger}')) orchestrator.start_polling(app) @@ -82,7 +82,7 @@ def test_mixed_valid_and_unknown_commands_handled_correctly(monkeypatch: pytest. def test(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) app.set_unknown_command_handler(lambda command: print(f'Unknown command: {command.trigger}')) orchestrator.start_polling(app) @@ -107,7 +107,7 @@ def test_multiple_commands_with_unknown_command_in_between(monkeypatch: pytest.M def test1(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('more command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) app.set_unknown_command_handler(lambda command: print(f'Unknown command: {command.trigger}')) orchestrator.start_polling(app) @@ -135,7 +135,7 @@ def test_unregistered_flag_without_value_is_accessible(monkeypatch: pytest.Monke if undefined_flag and undefined_flag.status == ValidationStatus.UNDEFINED: print(f'test command with undefined flag: {undefined_flag.string_entity}') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -159,7 +159,7 @@ def test_unregistered_flag_with_value_is_accessible(monkeypatch: pytest.MonkeyPa else: raise - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -182,7 +182,7 @@ def test_registered_and_unregistered_flags_coexist(monkeypatch: pytest.MonkeyPat if undefined_flag and undefined_flag.status == ValidationStatus.UNDEFINED: print(f'connecting to host with flag: {undefined_flag.string_entity} {undefined_flag.input_value}') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -207,7 +207,7 @@ def test_flag_without_value_triggers_incorrect_syntax_handler(monkeypatch: pytes def test(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) app.set_incorrect_input_syntax_handler(lambda command: print(f'Incorrect flag syntax: "{command}"')) orchestrator.start_polling(app) @@ -233,7 +233,7 @@ def test_repeated_flags_trigger_repeated_flags_handler(monkeypatch: pytest.Monke def test(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) app.set_repeated_input_flags_handler(lambda command: print(f'Repeated input flags: "{command}"')) orchestrator.start_polling(app) diff --git a/tests/system_tests/test_system_handling_normal_behavior.py b/tests/system_tests/test_system_handling_normal_behavior.py index dbb5cac..e7bf0de 100644 --- a/tests/system_tests/test_system_handling_normal_behavior.py +++ b/tests/system_tests/test_system_handling_normal_behavior.py @@ -36,7 +36,7 @@ def test_simple_command_executes_successfully(monkeypatch: pytest.MonkeyPatch, c def test(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -60,7 +60,7 @@ def test_two_commands_execute_sequentially(monkeypatch: pytest.MonkeyPatch, caps def test2(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('some command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -88,7 +88,7 @@ def test_three_commands_execute_sequentially(monkeypatch: pytest.MonkeyPatch, ca def test2(_response: Response) -> None: # pyright: ignore[reportUnusedFunction] print('more command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -116,7 +116,7 @@ def test_custom_flag_without_value_is_recognized(monkeypatch: pytest.MonkeyPatch if valid_flag and valid_flag.status == ValidationStatus.VALID: print(f'\nhelp for {valid_flag.name} flag\n') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -139,7 +139,7 @@ def test_custom_flag_with_regex_validation_accepts_valid_value(monkeypatch: pyte if valid_flag and valid_flag.status == ValidationStatus.VALID: print(f'flag value for {valid_flag.name} flag : {valid_flag.input_value}') - app = App(override_system_messages=True, repeat_command_groups_printing=True, print_func=print) + app = App(override_system_messages=True, repeat_command_groups_printing=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -167,7 +167,7 @@ def test_predefined_short_help_flag_is_recognized(monkeypatch: pytest.MonkeyPatc if valid_flag and valid_flag.status == ValidationStatus.VALID: print(f'help for {valid_flag.name} flag') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -190,7 +190,7 @@ def test_predefined_info_flag_is_recognized(monkeypatch: pytest.MonkeyPatch, cap if valid_flag and valid_flag.status == ValidationStatus.VALID: print('info about test command') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -213,7 +213,7 @@ def test_predefined_host_flag_with_value_is_recognized(monkeypatch: pytest.Monke if valid_flag and valid_flag.status == ValidationStatus.VALID: print(f'connecting to host {valid_flag.input_value}') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app) @@ -242,7 +242,7 @@ def test_two_predefined_flags_are_recognized_together(monkeypatch: pytest.Monkey if (host_flag and host_flag.status == ValidationStatus.VALID) and (port_flag and port_flag.status == ValidationStatus.VALID): print(f'connecting to host {host_flag.input_value} and port {port_flag.input_value}') - app = App(override_system_messages=True, print_func=print) + app = App(override_system_messages=True, printer=print) app.include_router(router) orchestrator.start_polling(app)