From 1c54f11f3135755c20dee75f153b6be20ca0cdf5 Mon Sep 17 00:00:00 2001 From: kolo Date: Sat, 24 Jan 2026 00:04:28 +0300 Subject: [PATCH] benchs --- metrics/benchmarks/__init__.py | 3 +- metrics/benchmarks/core/exceptions.py | 6 +- metrics/benchmarks/entity.py | 2 +- metrics/benchmarks/flag_validation.py | 102 +++++++++++++++++++++++++ metrics/handlers.py | 26 +++++-- metrics/services/system_info_reader.py | 2 +- mock/local_test.py | 18 ++--- src/argenta/app/models.py | 2 +- src/argenta/command/flag/models.py | 4 +- 9 files changed, 136 insertions(+), 29 deletions(-) create mode 100644 metrics/benchmarks/flag_validation.py diff --git a/metrics/benchmarks/__init__.py b/metrics/benchmarks/__init__.py index 631b500..37d80b8 100644 --- a/metrics/benchmarks/__init__.py +++ b/metrics/benchmarks/__init__.py @@ -2,4 +2,5 @@ from .pre_cycle_setup import * from .most_similar_command import * from .finds_appropriate_handler import * from .validate_routers_for_collisions import * -from .input_command_parse import * \ No newline at end of file +from .input_command_parse import * +from .flag_validation import * \ No newline at end of file diff --git a/metrics/benchmarks/core/exceptions.py b/metrics/benchmarks/core/exceptions.py index b849974..bf199c1 100644 --- a/metrics/benchmarks/core/exceptions.py +++ b/metrics/benchmarks/core/exceptions.py @@ -2,7 +2,7 @@ class BenchmarkNotFound(Exception): def __init__(self, benchmark_name: str): self.benchmark_name = benchmark_name - def __str__(self): + def __str__(self) -> str: return f"Benchmark with name '{self.benchmark_name}' not found" @@ -10,11 +10,11 @@ class BenchmarksNotFound(Exception): def __init__(self, type_: str): self.type_ = type_ - def __str__(self): + def __str__(self) -> str: return f"Benchmarks with type '{self.type_}' not found" class BenchmarksWithSameNameAlreadyExists(Exception): def __init__(self, benchmark_name: str): self.benchmark_name = benchmark_name - def __str__(self): + def __str__(self) -> str: return f"Benchmarks with name '{self.benchmark_name}' already exists" diff --git a/metrics/benchmarks/entity.py b/metrics/benchmarks/entity.py index 6722849..2365dee 100644 --- a/metrics/benchmarks/entity.py +++ b/metrics/benchmarks/entity.py @@ -1,3 +1,3 @@ -from metrics.benchmarks.core.models import Benchmarks +from .core.models import Benchmarks benchmarks = Benchmarks() \ No newline at end of file diff --git a/metrics/benchmarks/flag_validation.py b/metrics/benchmarks/flag_validation.py new file mode 100644 index 0000000..c3144f1 --- /dev/null +++ b/metrics/benchmarks/flag_validation.py @@ -0,0 +1,102 @@ +__all__ = [ + "benchmark_validate_all_single_flag", + "benchmark_validate_neither_single_flag", + "benchmark_validate_list_small", + "benchmark_validate_list_large", + "benchmark_validate_regex_simple", + "benchmark_validate_regex_complex", + "benchmark_validate_multiple_flags_10", + "benchmark_validate_multiple_flags_50", + "benchmark_validate_extreme_100_flags" +] + +import re + +from argenta.command.flag import Flag, InputFlag, PossibleValues + +from .entity import benchmarks + + +@benchmarks.register(type_="flag_validation", description="Single flag with PossibleValues.ALL") +def benchmark_validate_all_single_flag() -> None: + flag = Flag("test", possible_values=PossibleValues.ALL) + flag.validate_input_flag_value("some_value") + + +@benchmarks.register(type_="flag_validation", description="Single flag with PossibleValues.NEITHER") +def benchmark_validate_neither_single_flag() -> None: + flag = Flag("test", possible_values=PossibleValues.NEITHER) + flag.validate_input_flag_value("") + + +@benchmarks.register(type_="flag_validation", description="List validation (5 possible values)") +def benchmark_validate_list_small() -> None: + flag = Flag("env", possible_values=["dev", "staging", "prod", "test", "local"]) + flag.validate_input_flag_value("prod") + + +@benchmarks.register(type_="flag_validation", description="List validation (50 possible values)") +def benchmark_validate_list_large() -> None: + possible_values = [f"value{i}" for i in range(50)] + flag = Flag("option", possible_values=possible_values) + flag.validate_input_flag_value("value25") + + +@benchmarks.register(type_="flag_validation", description="Regex validation (simple pattern)") +def benchmark_validate_regex_simple() -> None: + pattern = re.compile(r"^\d+$") + flag = Flag("port", possible_values=pattern) + flag.validate_input_flag_value("8080") + + +@benchmarks.register(type_="flag_validation", description="Regex validation (complex pattern)") +def benchmark_validate_regex_complex() -> None: + pattern = re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") + flag = Flag("email", possible_values=pattern) + flag.validate_input_flag_value("user@example.com") + + +@benchmarks.register(type_="flag_validation", description="Multiple flags validation (10 flags)") +def benchmark_validate_multiple_flags_10() -> None: + flags = [ + Flag(f"flag{i}", possible_values=PossibleValues.ALL) + for i in range(10) + ] + input_flags = [ + InputFlag(f"flag{i}", input_value=f"value{i}") + for i in range(10) + ] + + for flag, input_flag in zip(flags, input_flags): + flag.validate_input_flag_value(input_flag.input_value) + + +@benchmarks.register(type_="flag_validation", description="Multiple flags validation (50 flags)") +def benchmark_validate_multiple_flags_50() -> None: + flags = [ + Flag(f"flag{i}", possible_values=PossibleValues.ALL) + for i in range(50) + ] + input_flags = [ + InputFlag(f"flag{i}", input_value=f"value{i}") + for i in range(50) + ] + + for flag, input_flag in zip(flags, input_flags): + flag.validate_input_flag_value(input_flag.input_value) + + +@benchmarks.register(type_="flag_validation", description="Extreme (100 flags with regex validation)") +def benchmark_validate_extreme_100_flags() -> None: + pattern = re.compile(r"^[a-zA-Z0-9_-]+$") + flags = [ + Flag(f"flag{i}", possible_values=pattern) + for i in range(100) + ] + input_flags = [ + InputFlag(f"flag{i}", input_value=f"valid_value_{i}") + for i in range(100) + ] + + for flag, input_flag in zip(flags, input_flags): + flag.validate_input_flag_value(input_flag.input_value) diff --git a/metrics/handlers.py b/metrics/handlers.py index 06e47ee..ee65b94 100644 --- a/metrics/handlers.py +++ b/metrics/handlers.py @@ -18,16 +18,22 @@ router = Router(title="Metrics commands:") Command( "run-all", description="Print all benchmarks results", - flags=Flag('without-gc', possible_values=PossibleValues.NEITHER) + flags=Flags([ + Flag('without-gc', possible_values=PossibleValues.NEITHER), + Flag('without-system-info', possible_values=PossibleValues.NEITHER) + ]) ) ) def all_print_handler(response: Response) -> None: report_generator = ReportGenerator(get_system_info()) - console.print(report_generator.generate_system_info_header()) - console.print(report_generator.generate_system_info_table()) + + without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID) + if not without_system_info: + console.print(report_generator.generate_system_info_header()) + console.print(report_generator.generate_system_info_table()) is_gc_disabled = response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID) - type_grouped_benchmarks: list[BenchmarkGroupResult] = registered_benchmarks.run_benchmarks_grouped_by_type(is_gc_disabled=is_gc_disabled) + type_grouped_benchmarks: list[BenchmarkGroupResult] = registered_benchmarks.run_benchmarks_grouped_by_type(is_gc_disabled=bool(is_gc_disabled)) for benchmark_group_result in type_grouped_benchmarks: console.print(report_generator.generate_benchmark_table_header(benchmark_group_result)) @@ -54,7 +60,8 @@ def list_types_handler(_: Response) -> None: description="Run benchmarks by specific type", flags=Flags([ Flag('type', possible_values=registered_benchmarks.get_types()), - Flag('without-gc', possible_values=PossibleValues.NEITHER) + Flag('without-gc', possible_values=PossibleValues.NEITHER), + Flag('without-system-info', possible_values=PossibleValues.NEITHER) ]) ) ) @@ -77,11 +84,14 @@ def run_type_handler(response: Response) -> None: return report_generator = ReportGenerator(get_system_info()) - console.print(report_generator.generate_system_info_header()) - console.print(report_generator.generate_system_info_table()) + + without_system_info = response.input_flags.get_flag_by_name("without-system-info", with_status=ValidationStatus.VALID) + if not without_system_info: + console.print(report_generator.generate_system_info_header()) + console.print(report_generator.generate_system_info_table()) is_gc_disabled = response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID, default=False) - benchmark_group_result = registered_benchmarks.run_benchmarks_by_type(benchmark_type, is_gc_disabled=is_gc_disabled) + benchmark_group_result = registered_benchmarks.run_benchmarks_by_type(benchmark_type, is_gc_disabled=bool(is_gc_disabled)) console.print(report_generator.generate_benchmark_table_header(benchmark_group_result)) console.print(report_generator.generate_benchmark_report_table(benchmark_group_result)) diff --git a/metrics/services/system_info_reader.py b/metrics/services/system_info_reader.py index 4d369fe..6f832b2 100644 --- a/metrics/services/system_info_reader.py +++ b/metrics/services/system_info_reader.py @@ -90,7 +90,7 @@ def get_cpu_info() -> CPUInfo: cpu_physical_cores = psutil.cpu_count(logical=False) cpu_logical_cores = psutil.cpu_count(logical=True) - cpu_freq = psutil.cpu_freq() or "N/A" + cpu_freq = psutil.cpu_freq() cpu_max_frequency = cpu_freq.max return CPUInfo( diff --git a/mock/local_test.py b/mock/local_test.py index 3e47833..1982580 100644 --- a/mock/local_test.py +++ b/mock/local_test.py @@ -1,14 +1,8 @@ -from argenta.app import AutoCompleter +from importlib.metadata import version, PackageNotFoundError +try: + __version__ = version("argenta") +except PackageNotFoundError: + __version__ = "unknown" -if __name__ == "__main__": - test_commands: set[str] = {"start", "qwertyu", "stop", "exit"} - hist_file: str = "history.txt" - - ac: AutoCompleter = AutoCompleter(autocomplete_button='tab') - ac.initial_setup(test_commands) - - while True: - inp: str = ac.prompt(">>> ").strip() - if inp == "exit": - break +print("__version__ = {}".format(__version__)) \ No newline at end of file diff --git a/src/argenta/app/models.py b/src/argenta/app/models.py index 93c35c3..22c256f 100644 --- a/src/argenta/app/models.py +++ b/src/argenta/app/models.py @@ -52,7 +52,7 @@ class BaseApp: self._prompt: str | HTML = prompt self._print_func: Printer = print_func self._exit_command: Command = exit_command - self._dividing_line: StaticDividingLine | DynamicDividingLine = dividing_line + self._dividing_line: StaticDividingLine | DynamicDividingLine | None = dividing_line self._repeat_command_groups_printing: bool = repeat_command_groups_printing self._override_system_messages: bool = override_system_messages self._autocompleter: AutoCompleter = autocompleter diff --git a/src/argenta/command/flag/models.py b/src/argenta/command/flag/models.py index 3eaae40..9355362 100644 --- a/src/argenta/command/flag/models.py +++ b/src/argenta/command/flag/models.py @@ -2,7 +2,7 @@ __all__ = ["PossibleValues", "ValidationStatus", "Flag", "InputFlag", "InputFlag from enum import Enum from re import Pattern -from typing import Literal, override, TypeVar, Generic, Iterator, Any +from typing import Literal, override, TypeVar, Generic, Iterator, Any, Container PREFIX_TYPE = Literal["-", "--", "---"] @@ -24,7 +24,7 @@ class Flag: name: str, *, prefix: PREFIX_TYPE = "--", - possible_values: list[str] | Pattern[str] | PossibleValues = PossibleValues.ALL, + possible_values: Container[str] | Pattern[str] | PossibleValues = PossibleValues.ALL, ) -> None: """ Public. The entity of the flag being registered for subsequent processing