4 Commits

Author SHA1 Message Date
kolo d30515c1a2 v0.3.9 2025-03-11 20:44:06 +03:00
kolo 5a6fc1d8ca first step 2025-03-08 13:49:29 +03:00
kolo e5d6ead38e v0.3.8 2025-03-06 01:35:28 +03:00
kolo b61c151e1c v0.3.8 2025-03-06 01:35:18 +03:00
21 changed files with 104 additions and 75 deletions
+4 -3
View File
@@ -56,7 +56,7 @@ if __name__ == '__main__':
import re
from argenta.router import Router
from argenta.command import Command
from argenta.command.params.flag import FlagsGroup, Flag
from argenta.command.flag import FlagsGroup, Flag
router = Router()
@@ -305,6 +305,7 @@ Router(title: str = 'Commands group title:',
- `TooManyTransferredArgsException` - Слишком много зарегистрированных аргументов у обработчика команды
- `RequiredArgumentNotPassedException` - Не зарегистрирован обязательный аргумент у обработчика команды(аргумент, через который будут переданы флаги введённой команды)
- `IncorrectNumberOfHandlerArgsException` - У обработчика нестандартного поведения зарегистрировано неверное количество аргументов(в большинстве случаев у него должен быть один аргумент)
- `TriggerCannotContainSpacesException` - У регистрируемой команды в триггере содержатся пробелы
---
@@ -363,9 +364,9 @@ Command(trigger: str,
### Конструктор
```python
Flag(flag_name: str,
flag_prefix: Literal['-', '--', '---'] = '-',
flag_prefix: typing.Literal['-', '--', '---'] = '-',
ignore_flag_value_register: bool = False,
possible_flag_values: list[str] | Pattern[str] = False)
possible_flag_values: list[str] | typing.Pattern[str] = False)
```
---
+1
View File
@@ -1,3 +1,4 @@
from pprint import pprint
from typing import Callable
from inspect import getfullargspec
import re
+13 -11
View File
@@ -1,16 +1,15 @@
from .params.flag.entity import Flag
from .params.flag.flags_group.entity import FlagsGroup
from argenta.command.flag.entity import Flag
from argenta.command.flag.flags_group import FlagsGroup
from .exceptions import (UnprocessedInputFlagException,
RepeatedInputFlagsException,
EmptyInputCommandException)
from typing import Generic, TypeVar
from typing import Generic, TypeVar, cast, Literal
CommandType = TypeVar('CommandType')
T = TypeVar('T')
class Command(Generic[T]):
class Command(Generic[CommandType]):
def __init__(self, trigger: str,
description: str = None,
flags: Flag | FlagsGroup = None):
@@ -57,7 +56,7 @@ class Command(Generic[T]):
return self._input_flags
@staticmethod
def parse_input_command(raw_command: str) -> 'Command[T]':
def parse_input_command(raw_command: str) -> 'Command[CommandType]':
if not raw_command:
raise EmptyInputCommandException()
list_of_tokens = raw_command.split()
@@ -67,7 +66,7 @@ class Command(Generic[T]):
flags: FlagsGroup = FlagsGroup()
current_flag_name = None
current_flag_value = None
for _ in list_of_tokens:
for k, _ in enumerate(list_of_tokens):
if _.startswith('-'):
flag_prefix_last_symbol_index = _.rfind('-')
if current_flag_name or len(_) < 2 or len(_[:flag_prefix_last_symbol_index]) > 3:
@@ -79,12 +78,15 @@ class Command(Generic[T]):
raise UnprocessedInputFlagException()
else:
current_flag_value = _
if current_flag_name and current_flag_value:
if current_flag_name:
if not len(list_of_tokens) == k+1:
if not list_of_tokens[k+1].startswith('-'):
continue
flag_prefix_last_symbol_index = current_flag_name.rfind('-')
flag_prefix = current_flag_name[:flag_prefix_last_symbol_index+1]
flag_name = current_flag_name[flag_prefix_last_symbol_index+1:]
input_flag = Flag(flag_name=flag_name,
flag_prefix=flag_prefix)
flag_prefix=cast(Literal['-', '--', '---'], flag_prefix))
input_flag.set_value(current_flag_value)
all_flags = [x.get_string_entity() for x in flags.get_flags()]
+1 -1
View File
@@ -1,4 +1,4 @@
from .params.flag.entity import Flag
from argenta.command.flag.entity import Flag
class UnprocessedInputFlagException(Exception):
+18
View File
@@ -0,0 +1,18 @@
from argenta.command.flag import Flag
import re
help_flag = Flag(flag_name='help', possible_flag_values=False)
short_help_flag = Flag(flag_name='h', flag_prefix='-', possible_flag_values=False)
info_flag = Flag(flag_name='info', possible_flag_values=False)
short_info_flag = Flag(flag_name='i', flag_prefix='-', possible_flag_values=False)
all_flag = Flag(flag_name='all', possible_flag_values=False)
short_all_flag = Flag(flag_name='a', flag_prefix='-', possible_flag_values=False)
host_flag = Flag(flag_name='host', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
short_host_flag = Flag(flag_name='h', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
port_flag = Flag(flag_name='port', possible_flag_values=re.compile(r'^\d{1,5}$'))
short_port_flag = Flag(flag_name='p', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,5}$'))
@@ -4,12 +4,10 @@ from typing import Literal, Pattern
class Flag:
def __init__(self, flag_name: str,
flag_prefix: Literal['-', '--', '---'] = '--',
ignore_flag_value_register: bool = False,
possible_flag_values: list[str] | Pattern[str] = False):
possible_flag_values: list[str] | Pattern[str] | False = True):
self._flag_name = flag_name
self._flag_prefix = flag_prefix
self.possible_flag_values = possible_flag_values
self.ignore_flag_value_register = ignore_flag_value_register
self._flag_value = None
@@ -29,23 +27,23 @@ class Flag:
def set_value(self, value):
self._flag_value = value
def validate_input_flag_value(self, input_flag_value: str):
if isinstance(self.possible_flag_values, Pattern):
def validate_input_flag_value(self, input_flag_value: str | None):
if self.possible_flag_values is False:
if input_flag_value is None:
return True
else:
return False
elif isinstance(self.possible_flag_values, Pattern):
is_valid = bool(self.possible_flag_values.match(input_flag_value))
if bool(is_valid):
return True
else:
return False
if isinstance(self.possible_flag_values, list):
if self.ignore_flag_value_register:
if input_flag_value.lower() in [x.lower() for x in self.possible_flag_values]:
return True
else:
return False
elif isinstance(self.possible_flag_values, list):
if input_flag_value in self.possible_flag_values:
return True
else:
if input_flag_value in self.possible_flag_values:
return True
else:
return False
return True
return False
else:
return True
@@ -0,0 +1 @@
from .entity import FlagsGroup
@@ -1,8 +1,8 @@
from argenta.command.params.flag.entity import Flag
from argenta.command.flag.entity import Flag
class FlagsGroup:
def __init__(self, flags: list[Flag] = None):
def __init__(self, *flags: Flag):
self._flags: list[Flag] = [] if not flags else flags
def get_flags(self) -> list[Flag]:
View File
+6 -3
View File
@@ -2,13 +2,14 @@ from typing import Callable, Any
from inspect import getfullargspec
from ..command.entity import Command
from ..command.params.flag.entity import Flag
from ..command.params.flag.flags_group.entity import FlagsGroup
from argenta.command.flag.entity import Flag
from argenta.command.flag.flags_group import FlagsGroup
from ..router.exceptions import (RepeatedCommandException,
RepeatedFlagNameException,
TooManyTransferredArgsException,
RequiredArgumentNotPassedException,
IncorrectNumberOfHandlerArgsException)
IncorrectNumberOfHandlerArgsException,
TriggerCannotContainSpacesException)
class Router:
@@ -71,6 +72,8 @@ class Router:
def _validate_command(self, command: Command):
command_name: str = command.get_trigger()
if command_name.find(' ') != -1:
raise TriggerCannotContainSpacesException()
if command_name in self.get_all_commands():
raise RepeatedCommandException()
if self._ignore_command_register:
+5
View File
@@ -21,3 +21,8 @@ class RequiredArgumentNotPassedException(Exception):
class IncorrectNumberOfHandlerArgsException(Exception):
def __str__(self):
return "Handler has incorrect number of arguments"
class TriggerCannotContainSpacesException(Exception):
def __str__(self):
return "Command trigger cannot contain spaces"
+2 -10
View File
@@ -1,11 +1,3 @@
import re
from typing import cast, Literal
def set_description_message_pattern(pattern: str) -> None:
first_check = re.match(r'.*command.*', pattern)
second_check = re.match(r'.*{description}.*', pattern)
if bool(first_check) and bool(second_check):
print('Success')
set_description_message_pattern('Invalid des{ommand}cription pattern')
print(cast(Literal['-', '--', '---'], '----'))
+4 -13
View File
@@ -2,9 +2,9 @@ import re
from pprint import pprint
from rich.console import Console
from argenta.command.entity import Command
from argenta.command.params.flag.entity import Flag
from argenta.command.params.flag.flags_group.entity import FlagsGroup
from argenta.command import Command
from argenta.command.flag import Flag, FlagsGroup
from argenta.command.flag.defaults import host_flag, port_flag
from argenta.router import Router
from .handlers_implementation.help_command import help_command
@@ -18,21 +18,12 @@ settings_router: Router = Router(title='Settings points:')
console = Console()
flags = FlagsGroup(flags=[
Flag(flag_name='host',
flag_prefix='--',
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
Flag(flag_name='port',
flag_prefix='--', )
])
@work_router.command(Command(trigger='0', description='Get Help'))
def command_help():
help_command()
@work_router.command(Command(trigger='P', description='Start Solving', flags=flags))
@work_router.command(Command(trigger='j', description='Start Solving', flags=FlagsGroup(host_flag, port_flag)))
def command_start_solving(args: dict):
print('Solving...')
pprint(args)
+3 -6
View File
@@ -3,16 +3,13 @@ from art import text2art
from rich.console import Console
from argenta.app import App
from argenta.router import Router
from argenta.command import Command
from argenta.command.params.flag import Flag, FlagsGroup
app: App = App(prompt='[italic white bold]What do you want to do(enter number of action)?',
line_separate=f'\n{"[bold green]-[/bold green][bold red]-[/bold red]"*25}\n',
print_func=Console().print,
command_group_description_separate='',
repeat_command_groups=True)
repeat_command_groups=True,
ignore_exit_command_register=False)
def main():
@@ -29,7 +26,7 @@ def main():
app.set_farewell_message(goodbye_message)
app.set_invalid_input_flags_handler(lambda raw_command: print(f"Invalid input flags: {raw_command}"))
app.set_unknown_command_handler(lambda command: print(f"Unknown command: {command.get_string_entity()}"))
app.set_unknown_command_handler(lambda command: print(f"Unknown command: {command.get_trigger()}"))
app.set_repeated_input_flags_handler(lambda raw_command: print(f"Repeated input flags: {raw_command}"))
app.set_description_message_pattern('[bold red][{command}][/bold red] [blue]*=*=*[/blue] [bold yellow italic]{description}')
+2 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "argenta"
version = "0.3.7"
version = "0.3.9"
description = "python library for creating custom shells"
authors = [
{name = "kolo", email = "kolo.is.main@gmail.com"}
@@ -33,4 +33,5 @@ numpy = "^2.2.2"
word2number = "^1.1"
numexpr = "^2.10.2"
requests = "^2.32.3"
pyreadline3 = "^3.5.4"
-4
View File
@@ -10,10 +10,6 @@ class TestCommand(unittest.TestCase):
def test_parse_correct_raw_command(self):
self.assertEqual(Command.parse_input_command('ssh --host 192.168.0.3').get_trigger(), 'ssh')
def test_parse_raw_command_with_flag_name_without_value(self):
with self.assertRaises(UnprocessedInputFlagException):
Command.parse_input_command('ssh --host')
def test_parse_raw_command_without_flag_name_with_value(self):
with self.assertRaises(UnprocessedInputFlagException):
Command.parse_input_command('ssh 192.168.0.3')
+17 -1
View File
@@ -1,4 +1,4 @@
from argenta.command.params.flag import Flag
from argenta.command.flag import Flag
import unittest
import re
@@ -52,6 +52,22 @@ class TestFlag(unittest.TestCase):
flag = Flag(flag_name='test', possible_flag_values=re.compile(r'192.168.\d+.\d+'))
self.assertEqual(flag.validate_input_flag_value('192.168.9.8'), True)
def test_validate_correct_empty_flag_value_without_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=False)
self.assertEqual(flag.validate_input_flag_value(None), True)
def test_validate_correct_empty_flag_value_with_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=True)
self.assertEqual(flag.validate_input_flag_value(None), True)
def test_validate_incorrect_random_flag_value_without_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=False)
self.assertEqual(flag.validate_input_flag_value('random value'), False)
def test_validate_correct_random_flag_value_with_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=True)
self.assertEqual(flag.validate_input_flag_value('random value'), True)
+2 -2
View File
@@ -1,4 +1,4 @@
from argenta.command.params.flag import Flag, FlagsGroup
from argenta.command.flag import Flag, FlagsGroup
import unittest
@@ -31,7 +31,7 @@ class TestFlagsGroup(unittest.TestCase):
Flag('test2'),
Flag('test3'),
]
flags = FlagsGroup(list_of_flags)
flags = FlagsGroup(*list_of_flags)
serialized_flags = flags.unparse_to_dict()
needed_result = {'test1': {'name': 'test1',
'prefix': '--',
+9 -2
View File
@@ -1,7 +1,7 @@
from argenta.command.params.flag import FlagsGroup, Flag
from argenta.command.flag import FlagsGroup, Flag
from argenta.router import Router
from argenta.command import Command
from argenta.router.exceptions import RepeatedCommandException
from argenta.router.exceptions import RepeatedCommandException, TriggerCannotContainSpacesException
import unittest
@@ -109,6 +109,13 @@ class TestRouter(unittest.TestCase):
def test():
return 'correct result'
def test_register_command_with_spaces_in_trigger(self):
router = Router()
with self.assertRaises(TriggerCannotContainSpacesException):
@router.command(Command(trigger='command with spaces'))
def test():
return 'correct result'