From b3b5e2e8a8d51ce6c22c6349fc944e6d8082080a Mon Sep 17 00:00:00 2001 From: kolo Date: Thu, 9 Oct 2025 20:23:52 +0300 Subject: [PATCH] extend arguments --- mock/mock_app/main.py | 11 ++-- pyproject.toml | 5 +- .../orchestrator/argparser/__init__.py | 8 +-- .../argparser/arguments/__init__.py | 6 +- .../argparser/arguments/models.py | 61 ++++++++++++++++--- src/argenta/orchestrator/argparser/entity.py | 26 +++++--- 6 files changed, 89 insertions(+), 28 deletions(-) diff --git a/mock/mock_app/main.py b/mock/mock_app/main.py index 67cc55f..af42553 100644 --- a/mock/mock_app/main.py +++ b/mock/mock_app/main.py @@ -3,26 +3,27 @@ from mock.mock_app.routers import work_router from argenta import App, Orchestrator from argenta.app import PredefinedMessages, DynamicDividingLine, AutoCompleter from argenta.orchestrator import ArgParser -from argenta.orchestrator.argparser import BooleanArgument +from argenta.orchestrator.argparser import BooleanArgument, ValueArgument, RequiredArgument -arg_parser = ArgParser(processed_args=[BooleanArgument("repeat")]) +arg_parser: ArgParser = ArgParser(processed_args=[BooleanArgument(name="repeat", is_deprecated=True), + ValueArgument(name="value", possible_values=["cat", "dog"]), + RequiredArgument(name="required", is_required=True)]) app: App = App( dividing_line=DynamicDividingLine(), autocompleter=AutoCompleter(), ) orchestrator: Orchestrator = Orchestrator(arg_parser) +print(orchestrator.get_input_args()) def main(): app.include_router(work_router) - print(f"\n\n{orchestrator.get_input_args()}") app.add_message_on_startup(PredefinedMessages.USAGE) app.add_message_on_startup(PredefinedMessages.AUTOCOMPLETE) app.add_message_on_startup(PredefinedMessages.HELP) - - orchestrator.start_polling(app) + # orchestrator.start_polling(app) if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index 88206d3..b63175f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,10 @@ exclude = [ "poetry.lock", ".__pycache__", "tests" - ] +] + +[tool.pyright] +typeCheckingMode = "strict" [build-system] requires = ["hatchling"] diff --git a/src/argenta/orchestrator/argparser/__init__.py b/src/argenta/orchestrator/argparser/__init__.py index 01d2f42..4a69e78 100644 --- a/src/argenta/orchestrator/argparser/__init__.py +++ b/src/argenta/orchestrator/argparser/__init__.py @@ -1,12 +1,12 @@ __all__ = [ "ArgParser", - "PositionalArgument", - "OptionalArgument", + "RequiredArgument", + "ValueArgument", "BooleanArgument" ] from argenta.orchestrator.argparser.entity import ArgParser from argenta.orchestrator.argparser.arguments import (BooleanArgument, - PositionalArgument, - OptionalArgument) + RequiredArgument, + ValueArgument) diff --git a/src/argenta/orchestrator/argparser/arguments/__init__.py b/src/argenta/orchestrator/argparser/arguments/__init__.py index 5b6270c..011299b 100644 --- a/src/argenta/orchestrator/argparser/arguments/__init__.py +++ b/src/argenta/orchestrator/argparser/arguments/__init__.py @@ -1,8 +1,8 @@ -__all__ = ["BooleanArgument", "PositionalArgument", "OptionalArgument"] +__all__ = ["BooleanArgument", "RequiredArgument", "ValueArgument"] from argenta.orchestrator.argparser.arguments.models import ( BooleanArgument, - PositionalArgument, - OptionalArgument, + RequiredArgument, + ValueArgument, ) diff --git a/src/argenta/orchestrator/argparser/arguments/models.py b/src/argenta/orchestrator/argparser/arguments/models.py index 1a74312..d922829 100644 --- a/src/argenta/orchestrator/argparser/arguments/models.py +++ b/src/argenta/orchestrator/argparser/arguments/models.py @@ -16,29 +16,65 @@ class BaseArgument(ABC): raise NotImplementedError -class PositionalArgument(BaseArgument): - def __init__(self, name: str): +class RequiredArgument(BaseArgument): + def __init__(self, name: str, *, + prefix: Literal["-", "--", "---"] = "--", + help: str = "Help for required argument", + default: str | None = None, + possible_values: list[str] | None = None, + is_required: bool = True, + is_deprecated: bool = False): """ Public. Required argument at startup :param name: name of the argument, must not start with minus (-) + :param prefix: prefix of the argument + :param help: help message for the argument + :param default: default value for the argument + :param possible_values: list of possible values for the argument + :param is_required: whether the argument is required + :param is_deprecated: whether the argument is deprecated """ self.name: str = name + self.prefix: Literal["-", "--", "---"] = prefix + self.help: str = help + self.default: str | None = default + self.possible_values: list[str] | None = possible_values + self.is_required: bool = is_required + self.is_deprecated: bool = is_deprecated + self.action: str = "store" @property @override def string_entity(self) -> str: - return self.name + return self.prefix + self.name -class OptionalArgument(BaseArgument): - def __init__(self, name: str, prefix: Literal["-", "--", "---"] = "--"): +class ValueArgument(BaseArgument): + def __init__(self, name: str, *, + prefix: Literal["-", "--", "---"] = "--", + help: str = "Help message for the value argument", + possible_values: list[str] | None = None, + default: str | None = None, + is_required: bool = False, + is_deprecated: bool = False): """ - Public. Optional argument, must have the value + Public. Value argument, must have the value :param name: name of the argument :param prefix: prefix of the argument + :param help: help message for the argument + :param possible_values: list of possible values for the argument + :param default: default value for the argument + :param is_required: whether the argument is required + :param is_deprecated: whether the argument is deprecated """ self.name: str = name self.prefix: Literal["-", "--", "---"] = prefix + self.help: str = help + self.possible_values: list[str] | None = possible_values + self.default: str | None = default + self.is_required: bool = is_required + self.is_deprecated: bool = is_deprecated + self.action: str = "store" @property @override @@ -47,14 +83,25 @@ class OptionalArgument(BaseArgument): class BooleanArgument(BaseArgument): - def __init__(self, name: str, prefix: Literal["-", "--", "---"] = "--"): + def __init__(self, name: str, *, + prefix: Literal["-", "--", "---"] = "--", + help: str = "Help message for the boolean argument", + is_required: bool = False, + is_deprecated: bool = False): """ Public. Boolean argument, does not require a value :param name: name of the argument :param prefix: prefix of the argument + :param help: help message for the argument + :param is_required: whether the argument is required + :param is_deprecated: whether the argument is deprecated """ self.name: str = name self.prefix: Literal["-", "--", "---"] = prefix + self.help: str = help + self.is_required: bool = is_required + self.is_deprecated: bool = is_deprecated + self.action: str = "store_true" @property @override diff --git a/src/argenta/orchestrator/argparser/entity.py b/src/argenta/orchestrator/argparser/entity.py index 5c3f29d..a5def0e 100644 --- a/src/argenta/orchestrator/argparser/entity.py +++ b/src/argenta/orchestrator/argparser/entity.py @@ -2,15 +2,15 @@ from argparse import ArgumentParser, Namespace from argenta.orchestrator.argparser.arguments.models import ( BooleanArgument, - OptionalArgument, - PositionalArgument, + ValueArgument, + RequiredArgument, ) class ArgParser: def __init__( self, - processed_args: list[PositionalArgument | OptionalArgument | BooleanArgument], *, + processed_args: list[RequiredArgument | ValueArgument | BooleanArgument], *, name: str = "Argenta", description: str = "Argenta available arguments", epilog: str = "github.com/koloideal/Argenta | made by kolo", @@ -27,13 +27,23 @@ class ArgParser: self._epilog: str = epilog self._entity: ArgumentParser = ArgumentParser(prog=name, description=description, epilog=epilog) - self._processed_args: list[PositionalArgument | OptionalArgument | BooleanArgument] = processed_args + self._processed_args: list[RequiredArgument | ValueArgument | BooleanArgument] = processed_args for arg in processed_args: - if isinstance(arg, PositionalArgument) or isinstance(arg, OptionalArgument): - _ = self._entity.add_argument(arg.string_entity) - else: - _ = self._entity.add_argument(arg.string_entity, action="store_true") + if isinstance(arg, BooleanArgument): + _ = self._entity.add_argument(arg.string_entity, + action=arg.action, + help=arg.help, + required=arg.is_required, + deprecated=arg.is_deprecated) + else: + _ = self._entity.add_argument(arg.string_entity, + action=arg.action, + help=arg.help, + default=arg.default, + choices=arg.possible_values, + required=arg.is_required, + deprecated=arg.is_deprecated) def parse_args(self) -> Namespace: return self._entity.parse_args()