diff --git a/.gitignore b/.gitignore index 3e452dd..8cd22e2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,8 @@ argenta/__pycache__/ argenta/command/__pycache__ argenta/command/params/__pycache__ argenta/command/params/flag/__pycache__ -argenta/command/params/flags_group/__pycache__ -argenta/command/params/input_flag/__pycache__ +argenta/command/params/flag/flags_group/__pycache__ +argenta/command/params/flag/input_flag/__pycache__ dist poetry.lock tests/__pycache__ diff --git a/argenta/app/entity.py b/argenta/app/entity.py index d31447b..37a0dda 100644 --- a/argenta/app/entity.py +++ b/argenta/app/entity.py @@ -1,7 +1,7 @@ from typing import Callable from ..command.entity import Command from argenta.command.input_comand.entity import InputCommand -from argenta.command.input_comand.exceptions import InvalidInputFlagsException +from argenta.command.input_comand.exceptions import InvalidInputFlagException from ..router.entity import Router from .exceptions import (InvalidRouterInstanceException, InvalidDescriptionMessagePatternException, @@ -68,26 +68,25 @@ class App: raw_command: str = input() try: - command: Command = InputCommand.parse(raw_command=raw_command) - except InvalidInputFlagsException: + input_command: InputCommand = InputCommand.parse(raw_command=raw_command) + except InvalidInputFlagException: self.print_func(self.line_separate) self.print_func(self.command_group_description_separate) if not self.repeat_command_groups: self.print_func(self.prompt) continue - - self._checking_command_for_exit_command(command.get_string_entity()) + self._checking_command_for_exit_command(input_command.get_string_entity()) self.print_func(self.line_separate) - is_unknown_command: bool = self._check_is_command_unknown(command.get_string_entity()) + is_unknown_command: bool = self._check_is_command_unknown(input_command.get_string_entity()) if is_unknown_command: if not self.repeat_command_groups: self.print_func(self.prompt) continue for router in self._routers: - router.input_command_handler(command) + router.input_command_handler(input_command) self.print_func(self.line_separate) self.print_func(self.command_group_description_separate) @@ -208,7 +207,7 @@ class App: if self.ignore_command_register: return False else: - if command_entity['command'] == command: + if command_entity['command'].get_string_entity() == command: return False self._app_main_router.unknown_command_handler(command) self.print_func(self.line_separate) diff --git a/argenta/command/entity.py b/argenta/command/entity.py index e457a54..1a59f21 100644 --- a/argenta/command/entity.py +++ b/argenta/command/entity.py @@ -1,8 +1,9 @@ from .params.flag.entity import Flag -from .params.flags_group.entity import FlagsGroup +from .params.flag.flags_group.entity import FlagsGroup from .exceptions import (InvalidCommandInstanceException, InvalidDescriptionInstanceException, InvalidFlagsInstanceException) +from .params.flag.input_flag.entity import InputFlag class Command: @@ -13,7 +14,7 @@ class Command: self._description = description self._flags = flags - self._input_flags = None + self._input_flags: FlagsGroup | None = None def get_string_entity(self): return self._command @@ -39,3 +40,15 @@ class Command: if not (isinstance(self._flags, Flag) or not isinstance(self._flags, FlagsGroup)) or not self._flags is None: raise InvalidFlagsInstanceException + def validate_input_flag(self, flag: InputFlag): + registered_flags: FlagsGroup = self._flags + if registered_flags: + for registered_flag in registered_flags: + if registered_flag.get_string_entity() == flag.get_string_entity(): + is_valid = registered_flag.validate_input_flag_value(flag) + if is_valid: + return True + return False + + + diff --git a/argenta/command/input_comand/__pycache__/__init__.cpython-313.pyc b/argenta/command/input_comand/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..427b945 Binary files /dev/null and b/argenta/command/input_comand/__pycache__/__init__.cpython-313.pyc differ diff --git a/argenta/command/input_comand/__pycache__/entity.cpython-313.pyc b/argenta/command/input_comand/__pycache__/entity.cpython-313.pyc new file mode 100644 index 0000000..4484f6b Binary files /dev/null and b/argenta/command/input_comand/__pycache__/entity.cpython-313.pyc differ diff --git a/argenta/command/input_comand/__pycache__/exceptions.cpython-313.pyc b/argenta/command/input_comand/__pycache__/exceptions.cpython-313.pyc new file mode 100644 index 0000000..cf07c72 Binary files /dev/null and b/argenta/command/input_comand/__pycache__/exceptions.cpython-313.pyc differ diff --git a/argenta/command/input_comand/entity.py b/argenta/command/input_comand/entity.py index 4d2ed93..db332dc 100644 --- a/argenta/command/input_comand/entity.py +++ b/argenta/command/input_comand/entity.py @@ -1,35 +1,40 @@ -from argenta.command.input_comand.exceptions import InvalidInputFlagsException +from ..input_comand.exceptions import IncorrectInputFlagException from ..entity import Command -from ..params.flags_group.entity import FlagsGroup -from ..params.input_flag.entity import InputFlag +from ..params.flag.flags_group.entity import FlagsGroup +from ..params.flag.input_flag.entity import InputFlag + +from typing import Generic, TypeVar -class InputCommand(Command): - def set_input_flags(self, input_flags: list[InputFlag]): +T = TypeVar('T') + + +class InputCommand(Command, Generic[T]): + def set_input_flags(self, input_flags: FlagsGroup): self._input_flags = input_flags - def get_input_flags(self) -> list[InputFlag]: + def get_input_flags(self) -> FlagsGroup: return self._input_flags @staticmethod - def parse(raw_command: str) -> Command: + def parse(raw_command: str) -> 'InputCommand[T]': list_of_tokens = raw_command.split() command = list_of_tokens[0] list_of_tokens.pop(0) - flags = [] + flags: FlagsGroup = FlagsGroup() current_flag_name = None current_flag_value = None for _ in list_of_tokens: flag_prefix_last_symbol_index = _.rfind('-') if _.startswith('-'): if current_flag_name or len(_) < 2 or len(_[:flag_prefix_last_symbol_index]) > 3: - raise InvalidInputFlagsException + raise IncorrectInputFlagException() else: current_flag_name = _ else: if not current_flag_name: - raise InvalidInputFlagsException + raise IncorrectInputFlagException() else: current_flag_value = _ if current_flag_name and current_flag_value: @@ -40,15 +45,15 @@ class InputCommand(Command): flag_prefix=flag_prefix) input_flag.set_value(current_flag_value) - flags.append(input_flag) + flags.add_flag(input_flag) current_flag_name = None current_flag_value = None - - if len(flags) == 0: - return Command(command=command) + if len(flags.get_flags()) == 0: + return InputCommand(command=command) else: - flags = FlagsGroup(flags=flags) - return Command(command=command, flags=flags) + input_command = InputCommand(command=command) + input_command.set_input_flags(flags) + return input_command diff --git a/argenta/command/input_comand/exceptions.py b/argenta/command/input_comand/exceptions.py index 7dd5ebd..4cf0ec0 100644 --- a/argenta/command/input_comand/exceptions.py +++ b/argenta/command/input_comand/exceptions.py @@ -1,3 +1,16 @@ -class InvalidInputFlagsException(Exception): +from ..params.flag.input_flag.entity import InputFlag + + +class InvalidInputFlagException(Exception): + def __init__(self, flag: InputFlag): + self.flag = flag def __str__(self): - return "Invalid Input Flags" + return ("Invalid Input Flags\n" + f"Unknown or invalid input flag: '{self.flag.get_string_entity()} {self.flag.get_value()}'") + +class IncorrectInputFlagException(Exception): + def __str__(self): + return "Incorrect Input Flags" + + + diff --git a/argenta/command/params/flag/entity.py b/argenta/command/params/flag/entity.py index c772a4d..8953a0f 100644 --- a/argenta/command/params/flag/entity.py +++ b/argenta/command/params/flag/entity.py @@ -18,6 +18,7 @@ class Flag: string_entity: str = self.flag_prefix + self.flag_name.lower() else: string_entity: str = self.flag_prefix + self.flag_name + print(string_entity) return string_entity def get_value(self): diff --git a/argenta/command/params/flags_group/__init__.py b/argenta/command/params/flag/flags_group/__init__.py similarity index 100% rename from argenta/command/params/flags_group/__init__.py rename to argenta/command/params/flag/flags_group/__init__.py diff --git a/argenta/command/params/flag/flags_group/entity.py b/argenta/command/params/flag/flags_group/entity.py new file mode 100644 index 0000000..a27e4f4 --- /dev/null +++ b/argenta/command/params/flag/flags_group/entity.py @@ -0,0 +1,22 @@ +from argenta.command.params.flag.entity import Flag +from argenta.command.params.flag.input_flag.entity import InputFlag + + +class FlagsGroup: + def __init__(self, flags: list[Flag | InputFlag] = None): + self._flags: list[Flag | InputFlag] = [] if not flags else flags + + def get_flags(self): + return self._flags + + def add_flag(self, flag: Flag | InputFlag): + self._flags.append(flag) + + def add_flags(self, flags: list[Flag | InputFlag]): + self._flags.extend(flags) + + def __iter__(self): + return iter(self._flags) + + def __next__(self): + return next(iter(self)) diff --git a/argenta/command/params/input_flag/__init__.py b/argenta/command/params/flag/input_flag/__init__.py similarity index 100% rename from argenta/command/params/input_flag/__init__.py rename to argenta/command/params/flag/input_flag/__init__.py diff --git a/argenta/command/params/input_flag/entity.py b/argenta/command/params/flag/input_flag/entity.py similarity index 79% rename from argenta/command/params/input_flag/entity.py rename to argenta/command/params/flag/input_flag/entity.py index 7ceb968..47f167b 100644 --- a/argenta/command/params/input_flag/entity.py +++ b/argenta/command/params/flag/input_flag/entity.py @@ -1,4 +1,4 @@ -from ...params.flag.entity import Flag +from ...flag.entity import Flag class InputFlag(Flag): diff --git a/argenta/command/params/flags_group/entity.py b/argenta/command/params/flags_group/entity.py deleted file mode 100644 index 14e5150..0000000 --- a/argenta/command/params/flags_group/entity.py +++ /dev/null @@ -1,6 +0,0 @@ -from argenta.command.params.flag.entity import Flag - - -class FlagsGroup: - def __init__(self, flags: list[Flag]): - self.flags = flags diff --git a/argenta/router/entity.py b/argenta/router/entity.py index 31e910d..b4de5e2 100644 --- a/argenta/router/entity.py +++ b/argenta/router/entity.py @@ -1,5 +1,7 @@ from typing import Callable, Any from ..command.entity import Command +from ..command.input_comand.entity import InputCommand +from ..command.input_comand.exceptions import InvalidInputFlagException from ..router.exceptions import (UnknownCommandHandlerHasAlreadyBeenCreatedException, RepeatedCommandException) @@ -43,15 +45,29 @@ class Router: return wrapper - def input_command_handler(self, input_command: Command): + def input_command_handler(self, input_command: InputCommand): input_command_name: str = input_command.get_string_entity() for command_entity in self._command_entities: - if input_command_name.lower() == command_entity['command'].get_string_entity(): + if input_command_name.lower() == command_entity['command'].get_string_entity().lower(): if self.ignore_command_register: - return command_entity['handler_func']() - else: - if input_command == command_entity['command']: + if input_command.get_input_flags(): + for flag in input_command.get_input_flags(): + is_valid = command_entity['command'].validate_input_flag(flag) + if not is_valid: + raise InvalidInputFlagException(flag) + return command_entity['handler_func'](input_command.get_input_flags()) + else: return command_entity['handler_func']() + else: + if input_command_name == command_entity['command'].get_string_entity(): + if input_command.get_input_flags(): + for flag in input_command.get_input_flags(): + is_valid = command_entity['command'].validate_input_flag(flag) + if not is_valid: + raise InvalidInputFlagException(flag) + return command_entity['handler_func'](input_command.get_input_flags()) + else: + return command_entity['handler_func']() def unknown_command_handler(self, unknown_command): diff --git a/tests/mock_app/handlers/routers.py b/tests/mock_app/handlers/routers.py index 6f0f4d0..bfb5d98 100644 --- a/tests/mock_app/handlers/routers.py +++ b/tests/mock_app/handlers/routers.py @@ -1,12 +1,10 @@ from rich.console import Console from argenta.command.entity import Command +from argenta.command.params.flag.flags_group.entity import FlagsGroup from argenta.router import Router from ..handlers.handlers_implementation.help_command import help_command -from ..handlers.handlers_implementation.solving_command import start_solving_command -from ..handlers.handlers_implementation.upgrade_command import upgrade_command - work_router: Router = Router(title='Work points:') settings_router: Router = Router(title='Settings points:') @@ -15,7 +13,9 @@ console = Console() @work_router.command(command=Command(command='0', description='Get Help')) -def command_help(): +def command_help(args: FlagsGroup): + print(args.get_flags()) + print('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') help_command() diff --git a/tests/test.py b/tests/test.py index 4fe3d3c..e9feaf5 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1,6 +1,9 @@ -from typing import Literal, LiteralString +class Entity: + pass -x: LiteralString = '---' -m: LiteralString = input() -if m == '-': - x = m +class Person(Entity): + pass + +a: Entity = Entity() +print(a) +a = Person() \ No newline at end of file