mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 18:15:28 +03:00
perf
This commit is contained in:
@@ -6,7 +6,9 @@ from typing import Never
|
|||||||
|
|
||||||
|
|
||||||
class AutoCompleter:
|
class AutoCompleter:
|
||||||
def __init__(self, history_filename: str | None = None, autocomplete_button: str = "tab") -> None:
|
def __init__(
|
||||||
|
self, history_filename: str | None = None, autocomplete_button: str = "tab"
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Public. Configures and implements auto-completion of input command
|
Public. Configures and implements auto-completion of input command
|
||||||
:param history_filename: the name of the file for saving the history of the autocompleter
|
:param history_filename: the name of the file for saving the history of the autocompleter
|
||||||
@@ -23,12 +25,18 @@ class AutoCompleter:
|
|||||||
:param state: the current cursor position is relative to the beginning of the line
|
:param state: the current cursor position is relative to the beginning of the line
|
||||||
:return: the desired candidate as str or None
|
:return: the desired candidate as str or None
|
||||||
"""
|
"""
|
||||||
matches: list[str] = sorted(cmd for cmd in _get_history_items() if cmd.startswith(text))
|
matches: list[str] = sorted(
|
||||||
|
cmd for cmd in _get_history_items() if cmd.startswith(text)
|
||||||
|
)
|
||||||
if len(matches) > 1:
|
if len(matches) > 1:
|
||||||
common_prefix = matches[0]
|
common_prefix = matches[0]
|
||||||
for match in matches[1:]:
|
for match in matches[1:]:
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(common_prefix) and i < len(match) and common_prefix[i] == match[i]:
|
while (
|
||||||
|
i < len(common_prefix)
|
||||||
|
and i < len(match)
|
||||||
|
and common_prefix[i] == match[i]
|
||||||
|
):
|
||||||
i += 1
|
i += 1
|
||||||
common_prefix = common_prefix[:i]
|
common_prefix = common_prefix[:i]
|
||||||
if state == 0:
|
if state == 0:
|
||||||
@@ -72,13 +80,17 @@ class AutoCompleter:
|
|||||||
raw_history = history_file.read()
|
raw_history = history_file.read()
|
||||||
pretty_history: list[str] = []
|
pretty_history: list[str] = []
|
||||||
for line in set(raw_history.strip().split("\n")):
|
for line in set(raw_history.strip().split("\n")):
|
||||||
if _is_command_exist(line.split()[0], all_commands, ignore_command_register):
|
if _is_command_exist(
|
||||||
|
line.split()[0], all_commands, ignore_command_register
|
||||||
|
):
|
||||||
pretty_history.append(line)
|
pretty_history.append(line)
|
||||||
with open(self.history_filename, "w") as history_file:
|
with open(self.history_filename, "w") as history_file:
|
||||||
_ = history_file.write("\n".join(pretty_history))
|
_ = history_file.write("\n".join(pretty_history))
|
||||||
|
|
||||||
|
|
||||||
def _is_command_exist(command: str, existing_commands: list[str], ignore_command_register: bool) -> bool:
|
def _is_command_exist(
|
||||||
|
command: str, existing_commands: list[str], ignore_command_register: bool
|
||||||
|
) -> bool:
|
||||||
if ignore_command_register:
|
if ignore_command_register:
|
||||||
return command.lower() in existing_commands
|
return command.lower() in existing_commands
|
||||||
return command in existing_commands
|
return command in existing_commands
|
||||||
@@ -89,4 +101,7 @@ def _get_history_items() -> list[str] | list[Never]:
|
|||||||
Private. Returns a list of all commands entered by the user
|
Private. Returns a list of all commands entered by the user
|
||||||
:return: all commands entered by the user as list[str] | list[Never]
|
:return: all commands entered by the user as list[str] | list[Never]
|
||||||
"""
|
"""
|
||||||
return [readline.get_history_item(i) for i in range(1, readline.get_current_history_length() + 1)]
|
return [
|
||||||
|
readline.get_history_item(i)
|
||||||
|
for i in range(1, readline.get_current_history_length() + 1)
|
||||||
|
]
|
||||||
|
|||||||
@@ -272,7 +272,6 @@ class BaseApp:
|
|||||||
def _(response: Response) -> None:
|
def _(response: Response) -> None:
|
||||||
self._exit_command_handler(response)
|
self._exit_command_handler(response)
|
||||||
|
|
||||||
self.system_router.command_register_ignore = self._ignore_command_register
|
|
||||||
self.registered_routers.add_registered_router(self.system_router)
|
self.registered_routers.add_registered_router(self.system_router)
|
||||||
|
|
||||||
def _validate_routers_for_collisions(self) -> None:
|
def _validate_routers_for_collisions(self) -> None:
|
||||||
@@ -519,7 +518,6 @@ class App(BaseApp):
|
|||||||
:param router: registered router
|
:param router: registered router
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
router.command_register_ignore = self._ignore_command_register
|
|
||||||
self.registered_routers.add_registered_router(router)
|
self.registered_routers.add_registered_router(router)
|
||||||
|
|
||||||
def include_routers(self, *routers: Router) -> None:
|
def include_routers(self, *routers: Router) -> None:
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ __all__ = ["NonStandardBehaviorHandler", "EmptyCommandHandler", "Printer", "Desc
|
|||||||
|
|
||||||
from typing import Protocol, TypeVar
|
from typing import Protocol, TypeVar
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T", contravariant=True) # noqa: WPS111
|
T = TypeVar("T", contravariant=True) # noqa: WPS111
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
__all__ = ["RegisteredRouters"]
|
__all__ = ["RegisteredRouters"]
|
||||||
|
|
||||||
from typing import Iterator, Optional
|
from typing import Iterator
|
||||||
|
|
||||||
from argenta.router import Router
|
from argenta.router import Router
|
||||||
|
|
||||||
|
|
||||||
class RegisteredRouters:
|
class RegisteredRouters:
|
||||||
def __init__(self, registered_routers: Optional[list[Router]] = None) -> None:
|
def __init__(self, registered_routers: list[Router] | None = None) -> None:
|
||||||
"""
|
"""
|
||||||
Private. Combines registered routers
|
Private. Combines registered routers
|
||||||
:param registered_routers: list of the registered routers
|
:param registered_routers: list of the registered routers
|
||||||
@@ -14,6 +14,8 @@ class RegisteredRouters:
|
|||||||
"""
|
"""
|
||||||
self.registered_routers: list[Router] = registered_routers if registered_routers else []
|
self.registered_routers: list[Router] = registered_routers if registered_routers else []
|
||||||
|
|
||||||
|
self._matching_lower_triggers_with_routers
|
||||||
|
|
||||||
def add_registered_router(self, router: Router, /) -> None:
|
def add_registered_router(self, router: Router, /) -> None:
|
||||||
"""
|
"""
|
||||||
Private. Adds a new registered router
|
Private. Adds a new registered router
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from enum import Enum
|
|||||||
from re import Pattern
|
from re import Pattern
|
||||||
from typing import Literal, override
|
from typing import Literal, override
|
||||||
|
|
||||||
|
|
||||||
PREFIX_TYPE = Literal["-", "--", "---"]
|
PREFIX_TYPE = Literal["-", "--", "---"]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
__all__ = ["Command", "InputCommand"]
|
__all__ = ["Command", "InputCommand"]
|
||||||
|
|
||||||
import shlex
|
import shlex
|
||||||
from typing import Never, Self, cast, Literal
|
from typing import Literal, Never, Self, cast
|
||||||
|
|
||||||
from argenta.command.exceptions import (
|
from argenta.command.exceptions import (
|
||||||
EmptyInputCommandException,
|
EmptyInputCommandException,
|
||||||
@@ -38,30 +38,38 @@ class Command:
|
|||||||
:param flags: processed commands
|
:param flags: processed commands
|
||||||
:param aliases: string synonyms for the main trigger
|
:param aliases: string synonyms for the main trigger
|
||||||
"""
|
"""
|
||||||
self.registered_flags: Flags = flags if isinstance(flags, Flags) else Flags([flags])
|
pretty_flags = flags if isinstance(flags, Flags) else Flags([flags])
|
||||||
|
self.registered_flags: Flags = pretty_flags
|
||||||
self.trigger: str = trigger
|
self.trigger: str = trigger
|
||||||
self.description: str = description
|
self.description: str = description
|
||||||
self.aliases: set[str] | set[Never] = aliases
|
self.aliases: set[str] | set[Never] = aliases
|
||||||
|
|
||||||
|
self._paired_string_entity_flag: dict[str, Flag] = {
|
||||||
|
flag.string_entity: flag for flag in pretty_flags
|
||||||
|
}
|
||||||
|
|
||||||
def validate_input_flag(self, flag: InputFlag) -> ValidationStatus:
|
def validate_input_flag(self, flag: InputFlag) -> ValidationStatus:
|
||||||
"""
|
"""
|
||||||
Private. Validates the input flag
|
Private. Validates the input flag
|
||||||
:param flag: input flag for validation
|
:param flag: input flag for validation
|
||||||
:return: is input flag valid as bool
|
:return: is input flag valid as bool
|
||||||
"""
|
"""
|
||||||
registered_flags: Flags = self.registered_flags
|
if registered_flag := self._paired_string_entity_flag.get(flag.string_entity):
|
||||||
for registered_flag in registered_flags:
|
is_valid = registered_flag.validate_input_flag_value(flag.input_value)
|
||||||
if registered_flag.string_entity == flag.string_entity:
|
if is_valid:
|
||||||
is_valid = registered_flag.validate_input_flag_value(flag.input_value)
|
return ValidationStatus.VALID
|
||||||
if is_valid:
|
else:
|
||||||
return ValidationStatus.VALID
|
return ValidationStatus.INVALID
|
||||||
else:
|
|
||||||
return ValidationStatus.INVALID
|
|
||||||
return ValidationStatus.UNDEFINED
|
return ValidationStatus.UNDEFINED
|
||||||
|
|
||||||
|
|
||||||
class InputCommand:
|
class InputCommand:
|
||||||
def __init__(self, trigger: str, *, input_flags: InputFlag | InputFlags = DEFAULT_WITHOUT_INPUT_FLAGS):
|
def __init__(
|
||||||
|
self,
|
||||||
|
trigger: str,
|
||||||
|
*,
|
||||||
|
input_flags: InputFlag | InputFlags = DEFAULT_WITHOUT_INPUT_FLAGS,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Private. The model of the input command, after parsing
|
Private. The model of the input command, after parsing
|
||||||
:param trigger:the trigger of the command
|
:param trigger:the trigger of the command
|
||||||
@@ -70,7 +78,9 @@ class InputCommand:
|
|||||||
"""
|
"""
|
||||||
self.trigger: str = trigger
|
self.trigger: str = trigger
|
||||||
self.input_flags: InputFlags = (
|
self.input_flags: InputFlags = (
|
||||||
input_flags if isinstance(input_flags, InputFlags) else InputFlags([input_flags])
|
input_flags
|
||||||
|
if isinstance(input_flags, InputFlags)
|
||||||
|
else InputFlags([input_flags])
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -115,7 +125,7 @@ class InputCommand:
|
|||||||
name=name,
|
name=name,
|
||||||
prefix=cast(PREFIX_TYPE, prefix), # pyright: ignore[reportUnnecessaryCast]
|
prefix=cast(PREFIX_TYPE, prefix), # pyright: ignore[reportUnnecessaryCast]
|
||||||
input_value=input_value,
|
input_value=input_value,
|
||||||
status=None
|
status=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
if input_flag in flags:
|
if input_flag in flags:
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
from argenta.metrics.main import get_time_of_pre_cycle_setup as get_time_of_pre_cycle_setup
|
from argenta.metrics.main import \
|
||||||
|
get_time_of_pre_cycle_setup as get_time_of_pre_cycle_setup
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
from argenta.orchestrator.argparser.arguments.models import BooleanArgument as BooleanArgument
|
from argenta.orchestrator.argparser.arguments.models import \
|
||||||
|
BooleanArgument as BooleanArgument
|
||||||
from argenta.orchestrator.argparser.arguments.models import InputArgument as InputArgument
|
from argenta.orchestrator.argparser.arguments.models import InputArgument as InputArgument
|
||||||
from argenta.orchestrator.argparser.arguments.models import ValueArgument as ValueArgument
|
from argenta.orchestrator.argparser.arguments.models import ValueArgument as ValueArgument
|
||||||
|
|||||||
@@ -7,12 +7,9 @@ import sys
|
|||||||
from argparse import ArgumentParser, Namespace
|
from argparse import ArgumentParser, Namespace
|
||||||
from typing import Never, Self
|
from typing import Never, Self
|
||||||
|
|
||||||
from argenta.orchestrator.argparser.arguments.models import (
|
from argenta.orchestrator.argparser.arguments.models import (BaseArgument,
|
||||||
BaseArgument,
|
BooleanArgument,
|
||||||
BooleanArgument,
|
InputArgument, ValueArgument)
|
||||||
InputArgument,
|
|
||||||
ValueArgument,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ArgSpace:
|
class ArgSpace:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
__all__ = ["ResponseStatus"]
|
__all__ = ["ResponseStatus"]
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Self
|
|
||||||
|
|
||||||
|
|
||||||
class ResponseStatus(Enum):
|
class ResponseStatus(Enum):
|
||||||
@@ -11,7 +10,7 @@ class ResponseStatus(Enum):
|
|||||||
UNDEFINED_AND_INVALID_FLAGS = "UNDEFINED_AND_INVALID_FLAGS"
|
UNDEFINED_AND_INVALID_FLAGS = "UNDEFINED_AND_INVALID_FLAGS"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_flags(cls, *, has_invalid_value_flags: bool, has_undefined_flags: bool) -> Self:
|
def from_flags(cls, *, has_invalid_value_flags: bool, has_undefined_flags: bool) -> "ResponseStatus":
|
||||||
key = (has_invalid_value_flags, has_undefined_flags)
|
key = (has_invalid_value_flags, has_undefined_flags)
|
||||||
status_map: dict[tuple[bool, bool], ResponseStatus] = {
|
status_map: dict[tuple[bool, bool], ResponseStatus] = {
|
||||||
(True, True): cls.UNDEFINED_AND_INVALID_FLAGS,
|
(True, True): cls.UNDEFINED_AND_INVALID_FLAGS,
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
__all__ = ["CommandHandler", "CommandHandlers"]
|
__all__ = ["CommandHandler", "CommandHandlers"]
|
||||||
|
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from typing import Callable
|
from typing import Callable, Never
|
||||||
|
|
||||||
from argenta.command import Command
|
from argenta.command import Command
|
||||||
from argenta.response import Response
|
from argenta.response import Response
|
||||||
|
|
||||||
|
|
||||||
HandlerFunc = Callable[..., None]
|
HandlerFunc = Callable[..., None]
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +29,7 @@ class CommandHandler:
|
|||||||
|
|
||||||
|
|
||||||
class CommandHandlers:
|
class CommandHandlers:
|
||||||
def __init__(self, command_handlers: tuple[CommandHandler] = tuple()):
|
def __init__(self, command_handlers: tuple[CommandHandler] | tuple[Never, ...] = tuple()):
|
||||||
"""
|
"""
|
||||||
Private. The model that unites all CommandHandler of the routers
|
Private. The model that unites all CommandHandler of the routers
|
||||||
:param command_handlers: list of CommandHandlers for register
|
:param command_handlers: list of CommandHandlers for register
|
||||||
@@ -49,7 +48,7 @@ class CommandHandlers:
|
|||||||
for alias in command_handler.handled_command.aliases:
|
for alias in command_handler.handled_command.aliases:
|
||||||
self.paired_command_handler_trigger[alias.lower()] = command_handler
|
self.paired_command_handler_trigger[alias.lower()] = command_handler
|
||||||
|
|
||||||
def get_command_handler_by_trigger(self, trigger: str):
|
def get_command_handler_by_trigger(self, trigger: str) -> CommandHandler | None:
|
||||||
print(self.paired_command_handler_trigger)
|
print(self.paired_command_handler_trigger)
|
||||||
return self.paired_command_handler_trigger.get(trigger)
|
return self.paired_command_handler_trigger.get(trigger)
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,14 @@ from rich.console import Console
|
|||||||
|
|
||||||
from argenta.command import Command, InputCommand
|
from argenta.command import Command, InputCommand
|
||||||
from argenta.command.flag import ValidationStatus
|
from argenta.command.flag import ValidationStatus
|
||||||
from argenta.command.flag.flags import Flags, InputFlags
|
from argenta.command.flag.flags import InputFlags
|
||||||
from argenta.response import Response, ResponseStatus
|
from argenta.response import Response, ResponseStatus
|
||||||
from argenta.router.command_handler.entity import CommandHandler, CommandHandlers
|
from argenta.router.command_handler.entity import CommandHandler, CommandHandlers
|
||||||
from argenta.router.exceptions import (
|
from argenta.router.exceptions import (RepeatedAliasNameException,
|
||||||
RepeatedAliasNameException,
|
RepeatedFlagNameException,
|
||||||
RepeatedFlagNameException,
|
RepeatedTriggerNameException,
|
||||||
RepeatedTriggerNameException,
|
RequiredArgumentNotPassedException,
|
||||||
RequiredArgumentNotPassedException,
|
TriggerContainSpacesException)
|
||||||
TriggerContainSpacesException,
|
|
||||||
)
|
|
||||||
|
|
||||||
HandlerFunc: TypeAlias = Callable[..., None]
|
HandlerFunc: TypeAlias = Callable[..., None]
|
||||||
|
|
||||||
@@ -42,8 +40,6 @@ class Router:
|
|||||||
self.disable_redirect_stdout: bool = disable_redirect_stdout
|
self.disable_redirect_stdout: bool = disable_redirect_stdout
|
||||||
|
|
||||||
self.command_handlers: CommandHandlers = CommandHandlers()
|
self.command_handlers: CommandHandlers = CommandHandlers()
|
||||||
self.command_register_ignore: bool = False
|
|
||||||
|
|
||||||
self.aliases: set[str] = set()
|
self.aliases: set[str] = set()
|
||||||
self.triggers: set[str] = set()
|
self.triggers: set[str] = set()
|
||||||
|
|
||||||
@@ -87,12 +83,11 @@ class Router:
|
|||||||
if overlapping := (self.aliases | self.triggers) & set(map(lambda x: x.lower(), command.aliases)):
|
if overlapping := (self.aliases | self.triggers) & set(map(lambda x: x.lower(), command.aliases)):
|
||||||
raise RepeatedAliasNameException(overlapping)
|
raise RepeatedAliasNameException(overlapping)
|
||||||
|
|
||||||
flags: Flags = command.registered_flags
|
flags_name: list[str] = [flag.string_entity.lower() for flag in command.registered_flags]
|
||||||
flags_name: list[str] = [flag.string_entity.lower() for flag in flags]
|
|
||||||
if len(set(flags_name)) < len(flags_name):
|
if len(set(flags_name)) < len(flags_name):
|
||||||
raise RepeatedFlagNameException()
|
raise RepeatedFlagNameException()
|
||||||
|
|
||||||
def _update_routing_keys(self, registered_command: Command):
|
def _update_routing_keys(self, registered_command: Command) -> None:
|
||||||
redefined_command_aliases_in_lower = set(map(lambda x: x.lower(), registered_command.aliases))
|
redefined_command_aliases_in_lower = set(map(lambda x: x.lower(), registered_command.aliases))
|
||||||
self.aliases.update(redefined_command_aliases_in_lower)
|
self.aliases.update(redefined_command_aliases_in_lower)
|
||||||
self.triggers.add(registered_command.trigger.lower())
|
self.triggers.add(registered_command.trigger.lower())
|
||||||
|
|||||||
Reference in New Issue
Block a user