From 2a9281a421609576caf13d33382d69c7451901b2 Mon Sep 17 00:00:00 2001 From: kolo Date: Wed, 28 Jan 2026 02:23:40 +0300 Subject: [PATCH] benchs --- metrics/handlers.py | 6 +- metrics/services/__init__.py | 4 +- ...generator.py => report_table_generator.py} | 2 +- mock/local_test.py | 24 +++- mock/mock_app/main.py | 7 +- mock/mock_app/routers.py | 7 +- src/argenta/app/autocompleter/entity.py | 4 +- src/argenta/app/models.py | 110 ++++++++++-------- src/argenta/command/models.py | 9 +- 9 files changed, 107 insertions(+), 66 deletions(-) rename metrics/services/{report_generator.py => report_table_generator.py} (99%) diff --git a/metrics/handlers.py b/metrics/handlers.py index 996257c..4f42044 100644 --- a/metrics/handlers.py +++ b/metrics/handlers.py @@ -12,7 +12,7 @@ from argenta.response import Response from argenta.router import Router from .benchmarks.core.models import BenchmarkGroupResult from .benchmarks.entity import benchmarks as registered_benchmarks -from .services.report_generator import ReportGenerator +from .services.report_table_generator import ReportTableGenerator from .services.system_info_reader import get_system_info from .services.diagram_generator import DiagramGenerator from .services.release_generator import ReleaseGenerator @@ -34,7 +34,7 @@ POSITIVE_INTEGER_PATTERN = re.compile(r"^[1-9]\d*$") ) ) def all_print_handler(response: Response) -> None: - report_generator = ReportGenerator(get_system_info()) + report_generator = ReportTableGenerator(get_system_info()) without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID) if not without_system_info: @@ -92,7 +92,7 @@ def run_type_handler(response: Response) -> None: console.print(f" • {t}") return - report_generator = ReportGenerator(get_system_info()) + report_generator = ReportTableGenerator(get_system_info()) without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID) if not without_system_info: diff --git a/metrics/services/__init__.py b/metrics/services/__init__.py index fd0f6e0..ee3ba46 100644 --- a/metrics/services/__init__.py +++ b/metrics/services/__init__.py @@ -1,6 +1,6 @@ from .diagram_generator import DiagramGenerator -from .report_generator import ReportGenerator +from .report_table_generator import ReportTableGenerator from .system_info_reader import get_system_info from .release_generator import ReleaseGenerator -__all__ = ["DiagramGenerator", "ReportGenerator", "get_system_info", "ReleaseGenerator"] +__all__ = ["DiagramGenerator", "ReportTableGenerator", "get_system_info", "ReleaseGenerator"] diff --git a/metrics/services/report_generator.py b/metrics/services/report_table_generator.py similarity index 99% rename from metrics/services/report_generator.py rename to metrics/services/report_table_generator.py index 5c383fb..658020d 100644 --- a/metrics/services/report_generator.py +++ b/metrics/services/report_table_generator.py @@ -6,7 +6,7 @@ from ..benchmarks.core.models import BenchmarkGroupResult from metrics.services.system_info_reader import SystemInfo -class ReportGenerator: +class ReportTableGenerator: def __init__(self, system_info: SystemInfo): self.system_info = system_info self._cached_benchmark_tables: dict[int, Table] = {} diff --git a/mock/local_test.py b/mock/local_test.py index ddfa8c5..f912443 100644 --- a/mock/local_test.py +++ b/mock/local_test.py @@ -1,4 +1,22 @@ -from argenta import App +from prompt_toolkit.shortcuts import checkboxlist_dialog +from prompt_toolkit.styles import Style -app = App() -app._autocompleter.initial_setup(set()) \ No newline at end of file +results = checkboxlist_dialog( + title="CheckboxList dialog", + text="What would you like in your breakfast ?", + values=[ + ("eggs", "Eggs"), + ("bacon", "Bacon"), + ("croissants", "20 Croissants"), + ("daily", "The breakfast of the day") + ], + style=Style.from_dict({ + 'dialog': 'bg:#cdbbb3', + 'button': 'bg:#bf99a4', + 'checkbox': '#e8612c', + 'dialog.body': 'bg:#a9cfd0', + 'dialog shadow': 'bg:#c98982', + 'frame.label': '#fcaca3', + 'dialog.body label': '#fd8bb6', + }) +).run() \ No newline at end of file diff --git a/mock/mock_app/main.py b/mock/mock_app/main.py index 1305567..745baf9 100644 --- a/mock/mock_app/main.py +++ b/mock/mock_app/main.py @@ -1,10 +1,13 @@ +from prompt_toolkit import HTML + from argenta import App, Orchestrator -from argenta.app import PredefinedMessages +from argenta.app import PredefinedMessages, StaticDividingLine, AutoCompleter from argenta.app.dividing_line.models import DynamicDividingLine from mock.mock_app.routers import work_router app: App = App( - dividing_line=DynamicDividingLine('^'), + dividing_line=StaticDividingLine('~'), + prompt=HTML('\n>>>') ) orchestrator: Orchestrator = Orchestrator() diff --git a/mock/mock_app/routers.py b/mock/mock_app/routers.py index a6d4123..3aafb75 100644 --- a/mock/mock_app/routers.py +++ b/mock/mock_app/routers.py @@ -1,7 +1,8 @@ from argenta import Command, Response, Router from argenta.command import Flag, Flags +from argenta.command.flag import ValidationStatus -work_router: Router = Router(title="Base points:", disable_redirect_stdout=True) +work_router: Router = Router(title="Base points:") @work_router.command( @@ -13,5 +14,5 @@ work_router: Router = Router(title="Base points:", disable_redirect_stdout=True) description="Hello, world!") ) def command_help(response: Response): - c = input("Enter your name: ") - print(f"Hello, {c}!") + n = input('sfgdheth') + print(f"Hello,{n} {response.input_flags.get_flag_by_name('test', with_status=ValidationStatus.VALID)}") diff --git a/src/argenta/app/autocompleter/entity.py b/src/argenta/app/autocompleter/entity.py index 6c92982..bdddf0c 100644 --- a/src/argenta/app/autocompleter/entity.py +++ b/src/argenta/app/autocompleter/entity.py @@ -6,6 +6,7 @@ from typing import Callable, Iterable from prompt_toolkit import PromptSession, HTML from prompt_toolkit.auto_suggest import AutoSuggestFromHistory from prompt_toolkit.completion import Completer, Completion, CompleteEvent, ThreadedCompleter +from prompt_toolkit.cursor_shapes import CursorShape from prompt_toolkit.document import Document from prompt_toolkit.formatted_text import StyleAndTextTuples from prompt_toolkit.history import History, ThreadedHistory, FileHistory, InMemoryHistory @@ -136,5 +137,6 @@ class AutoCompleter: if self._session is None: raise RuntimeError("Call initial_setup() before using prompt()") return self._session.prompt( - HTML(prompt_text) if isinstance(prompt_text, str) else prompt_text + HTML(prompt_text) if isinstance(prompt_text, str) else prompt_text, + cursor=CursorShape.BLINKING_BEAM ) \ No newline at end of file diff --git a/src/argenta/app/models.py b/src/argenta/app/models.py index ec1b4c4..f4169bd 100644 --- a/src/argenta/app/models.py +++ b/src/argenta/app/models.py @@ -163,45 +163,23 @@ class BaseApp: :param text: framed text :return: None """ - if isinstance(self._dividing_line, DynamicDividingLine): - clear_text = _ANSI_ESCAPE_RE.sub("", text) - 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 + match self._dividing_line: + case (StaticDividingLine() as dividing_line) | (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( - self._dividing_line.get_full_dynamic_line( - length=max_length_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 + ) ) - ) - - elif isinstance(self._dividing_line, StaticDividingLine): - self._print_func( - self._dividing_line.get_full_static_line( - is_override=self._override_system_messages - ) - ) - print(text.strip("\n")) - self._print_func( - self._dividing_line.get_full_static_line( - is_override=self._override_system_messages - ) - ) - elif self._dividing_line is None: - print('\n' + text.strip("\n") + '\n') - else: - raise NotImplementedError + 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: """ @@ -307,7 +285,8 @@ class BaseApp: Private. Sets up default app view :return: None """ - self._prompt = f"\n{self._prompt}" + if isinstance(self._prompt, str): + self._prompt = f"\n{self._prompt}" self._initial_message = ( "\n" + f"[bold red]{text2art(self._initial_message, font='tarty1')}" ) @@ -354,15 +333,11 @@ class BaseApp: """ self._setup_system_router() self._validate_routers_for_collisions() - self._autocompleter.initial_setup(self.registered_routers.get_triggers()) self._print_func(self._initial_message) + self._print_func('\n'.join(self._messages_on_startup)) - for message in self._messages_on_startup: - self._print_func(message) - if self._messages_on_startup: - print("\n") if not self._repeat_command_groups_printing: self._print_command_group_description() @@ -372,13 +347,48 @@ class BaseApp: if not processing_router: raise RuntimeError(f"Router for '{input_command.trigger}' not found. Panic!") - if processing_router.disable_redirect_stdout: - processing_router.finds_appropriate_handler(input_command) - else: - stdout_result = self._capture_stdout( - lambda: processing_router.finds_appropriate_handler(input_command) - ) - self._print_framed_text(stdout_result) + match (self._dividing_line, processing_router.disable_redirect_stdout): + 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 (None, bool()): + processing_router.finds_appropriate_handler(input_command) + case _: + raise NotImplementedError(f'Dividing line with type {self._dividing_line} is not implemented') AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine diff --git a/src/argenta/command/models.py b/src/argenta/command/models.py index 7996c22..7f56c19 100644 --- a/src/argenta/command/models.py +++ b/src/argenta/command/models.py @@ -90,7 +90,14 @@ class InputCommand: :param raw_command: raw input command :return: model of the input command, after parsing as InputCommand """ - tokens = shlex.split(raw_command) + lexer = shlex.shlex(raw_command, posix=True) + lexer.whitespace_split = True + lexer.commenters = "" + + try: + tokens = list(lexer) + except ValueError as e: + raise UnprocessedInputFlagException from e if not tokens: raise EmptyInputCommandException