From 1f15b4c093febf5979ae2b5104b8dafb698a3e86 Mon Sep 17 00:00:00 2001 From: kolo Date: Tue, 28 Oct 2025 10:34:34 +0300 Subject: [PATCH] docs --- docs/code_snippets/flag_snippet.py | 23 ++ docs/code_snippets/flag_snippet2.py | 19 ++ docs/code_snippets/flag_snippet3.py | 11 + docs/code_snippets/flag_snippet4.py | 12 + docs/code_snippets/flag_snippet5.py | 12 + docs/code_snippets/flag_snippet6.py | 21 ++ docs/code_snippets/flags_snippet2.py | 11 + docs/code_snippets/flags_snippet3.py | 20 ++ docs/code_snippets/flags_snippet4.py | 18 ++ docs/code_snippets/flags_snippet5.py | 16 ++ docs/code_snippets/flags_snippet6.py | 16 ++ .../code_snippets/predefined_flags_snippet.py | 33 +++ docs/root/api/command/flag.rst | 267 +++++++++++++++++- docs/root/api/command/flags.rst | 89 +----- 14 files changed, 488 insertions(+), 80 deletions(-) create mode 100644 docs/code_snippets/flag_snippet.py create mode 100644 docs/code_snippets/flag_snippet2.py create mode 100644 docs/code_snippets/flag_snippet3.py create mode 100644 docs/code_snippets/flag_snippet4.py create mode 100644 docs/code_snippets/flag_snippet5.py create mode 100644 docs/code_snippets/flag_snippet6.py create mode 100644 docs/code_snippets/flags_snippet2.py create mode 100644 docs/code_snippets/flags_snippet3.py create mode 100644 docs/code_snippets/flags_snippet4.py create mode 100644 docs/code_snippets/flags_snippet5.py create mode 100644 docs/code_snippets/flags_snippet6.py create mode 100644 docs/code_snippets/predefined_flags_snippet.py diff --git a/docs/code_snippets/flag_snippet.py b/docs/code_snippets/flag_snippet.py new file mode 100644 index 0000000..794cd63 --- /dev/null +++ b/docs/code_snippets/flag_snippet.py @@ -0,0 +1,23 @@ +from argenta.command import Flag, PossibleValues +import re + +# Простой флаг с любыми значениями +verbose_flag = Flag(name="verbose") + +# Флаг с коротким префиксом +short_flag = Flag(name="v", prefix="-") + +# Флаг без значения +help_flag = Flag(name="help", possible_values=PossibleValues.NEITHER) + +# Флаг со списком допустимых значений +format_flag = Flag( + name="format", + possible_values=["json", "xml", "csv"] +) + +# Флаг с регулярным выражением для валидации +email_flag = Flag( + name="email", + possible_values=re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") +) diff --git a/docs/code_snippets/flag_snippet2.py b/docs/code_snippets/flag_snippet2.py new file mode 100644 index 0000000..4a08657 --- /dev/null +++ b/docs/code_snippets/flag_snippet2.py @@ -0,0 +1,19 @@ +from argenta.command.flag.models import Flag, PossibleValues +import re + +# Флаг со списком допустимых значений +format_flag = Flag(name="format", possible_values=["json", "xml", "csv"]) + +# Валидация значений +print(format_flag.validate_input_flag_value("json")) # True +print(format_flag.validate_input_flag_value("pdf")) # False + +# Флаг без значения +help_flag = Flag(name="help", possible_values=PossibleValues.NEITHER) +print(help_flag.validate_input_flag_value(None)) # True +print(help_flag.validate_input_flag_value("value")) # False + +# Флаг с регулярным выражением +port_flag = Flag(name="port", possible_values=re.compile(r"^\d{1,5}$")) +print(port_flag.validate_input_flag_value("8080")) # True +print(port_flag.validate_input_flag_value("abc")) # False diff --git a/docs/code_snippets/flag_snippet3.py b/docs/code_snippets/flag_snippet3.py new file mode 100644 index 0000000..bad921a --- /dev/null +++ b/docs/code_snippets/flag_snippet3.py @@ -0,0 +1,11 @@ +from argenta.command import Flag + +# Создание флагов с разными префиксами +verbose_flag = Flag(name="verbose", prefix="--") +short_flag = Flag(name="v", prefix="-") +triple_flag = Flag(name="debug", prefix="---") + +# Получение строкового представления +print(verbose_flag.string_entity) # --verbose +print(short_flag.string_entity) # -v +print(triple_flag.string_entity) # ---debug diff --git a/docs/code_snippets/flag_snippet4.py b/docs/code_snippets/flag_snippet4.py new file mode 100644 index 0000000..a2cbb4f --- /dev/null +++ b/docs/code_snippets/flag_snippet4.py @@ -0,0 +1,12 @@ +from argenta.command import Flag + +help_flag = Flag(name="help") +version_flag = Flag(name="V", prefix="-") + +# Использование str() или print() +print(str(help_flag)) # --help +print(version_flag) # -V + +# Форматирование строк +message = f"Use {help_flag} to see help" +print(message) # Use --help to see help diff --git a/docs/code_snippets/flag_snippet5.py b/docs/code_snippets/flag_snippet5.py new file mode 100644 index 0000000..e61b8d5 --- /dev/null +++ b/docs/code_snippets/flag_snippet5.py @@ -0,0 +1,12 @@ +from argenta.command import Flag + +verbose_flag = Flag(name="verbose", prefix="--") +short_flag = Flag(name="v", prefix="-") + +# Отладочное представление +print(repr(verbose_flag)) # Flag +print(repr(short_flag)) # Flag + +# В интерактивной консоли или отладчике +# >>> verbose_flag +# Flag diff --git a/docs/code_snippets/flag_snippet6.py b/docs/code_snippets/flag_snippet6.py new file mode 100644 index 0000000..b6d7866 --- /dev/null +++ b/docs/code_snippets/flag_snippet6.py @@ -0,0 +1,21 @@ +from argenta.command import Flag, PossibleValues + +# Создание двух флагов с одинаковым именем и префиксом +flag1 = Flag(name="verbose", prefix="--") +flag2 = Flag(name="verbose", prefix="--") + +# Сравнение флагов +print(flag1 == flag2) # True + +# Флаги с разными префиксами не равны +flag3 = Flag(name="verbose", prefix="-") +print(flag1 == flag3) # False + +# Флаги с разными именами не равны +flag4 = Flag(name="help", prefix="--") +print(flag1 == flag4) # False + +# Разные possible_values не влияют на равенство +flag5 = Flag(name="verbose", prefix="--", possible_values=PossibleValues.NEITHER) +flag6 = Flag(name="verbose", prefix="--", possible_values=["value1", "value2"]) +print(flag5 == flag6) # True (сравнение только по string_entity) diff --git a/docs/code_snippets/flags_snippet2.py b/docs/code_snippets/flags_snippet2.py new file mode 100644 index 0000000..0f00ba3 --- /dev/null +++ b/docs/code_snippets/flags_snippet2.py @@ -0,0 +1,11 @@ +from argenta.command import Flags, Flag + +# Создание коллекции +flags: Flags = Flags() + +# Динамическое добавление флагов +flags.add_flag(Flag("config")) +flags.add_flag(Flag("debug")) +flags.add_flag(Flag("log-level", possible_values=["INFO", "DEBUG", "ERROR"])) + +print(len(flags.flags)) # 3 \ No newline at end of file diff --git a/docs/code_snippets/flags_snippet3.py b/docs/code_snippets/flags_snippet3.py new file mode 100644 index 0000000..5946a99 --- /dev/null +++ b/docs/code_snippets/flags_snippet3.py @@ -0,0 +1,20 @@ +from argenta.command import Flags, Flag +from argenta.command.flag.defaults import PredefinedFlags + +# Начальная коллекция +flags = Flags([ + PredefinedFlags.HOST +]) + +# Дополнительные флаги +additional_flags = [ + PredefinedFlags.PORT, + Flag("database"), + Flag("ssl"), + Flag("verbose") +] + +# Добавление списка флагов +flags.add_flags(additional_flags) + +print(len(flags.flags)) # 5 \ No newline at end of file diff --git a/docs/code_snippets/flags_snippet4.py b/docs/code_snippets/flags_snippet4.py new file mode 100644 index 0000000..85c7830 --- /dev/null +++ b/docs/code_snippets/flags_snippet4.py @@ -0,0 +1,18 @@ +from argenta.command import Flags, Flag +from argenta.command.flag.defaults import PredefinedFlags + +flags = Flags([ + PredefinedFlags.HOST, + PredefinedFlags.PORT, + Flag("verbose") +]) + +# Получение флага по имени +host_flag = flags.get_flag_by_name("host") +if host_flag: + print(f"Found flag: {host_flag.name}") + +# Поиск несуществующего флага +unknown_flag = flags.get_flag_by_name("nonexistent") +if unknown_flag is None: + print("Flag not found") \ No newline at end of file diff --git a/docs/code_snippets/flags_snippet5.py b/docs/code_snippets/flags_snippet5.py new file mode 100644 index 0000000..9f4d428 --- /dev/null +++ b/docs/code_snippets/flags_snippet5.py @@ -0,0 +1,16 @@ +from argenta.command import Flags, Flag +from argenta.command.flag.defaults import PredefinedFlags + +flags = Flags([ + PredefinedFlags.HOST, + PredefinedFlags.PORT, + Flag("verbose") +]) + +# Итерация по всем флагам +for flag in flags: + print(f"Flag: {flag.name} (type: {type(flag).__name__})") + +# Использование в list comprehension +flag_names = [flag.name for flag in flags] +print(f"All flags: {flag_names}") \ No newline at end of file diff --git a/docs/code_snippets/flags_snippet6.py b/docs/code_snippets/flags_snippet6.py new file mode 100644 index 0000000..6143e9f --- /dev/null +++ b/docs/code_snippets/flags_snippet6.py @@ -0,0 +1,16 @@ +from argenta.command import Flags, Flag + +flags = Flags([ + Flag("first"), + Flag("second"), + Flag("third") +]) + +print(flags[0].name) +# first + +print(flags[1].name) +# second + +print(flags[2].name) +# third \ No newline at end of file diff --git a/docs/code_snippets/predefined_flags_snippet.py b/docs/code_snippets/predefined_flags_snippet.py new file mode 100644 index 0000000..6602a33 --- /dev/null +++ b/docs/code_snippets/predefined_flags_snippet.py @@ -0,0 +1,33 @@ +from argenta.command.flag.defaults import PredefinedFlags +from argenta.command import Flags + +# Использование предопределенных флагов при создании команды +command_flags = Flags([ + PredefinedFlags.HELP, + PredefinedFlags.SHORT_HELP, + PredefinedFlags.INFO, +]) + +# Использование сетевых флагов +network_flags = Flags([ + PredefinedFlags.HOST, + PredefinedFlags.PORT, +]) + +# Валидация значений предопределенных флагов +print(PredefinedFlags.HOST.validate_input_flag_value("192.168.1.1")) # True +print(PredefinedFlags.HOST.validate_input_flag_value("invalid")) # False + +print(PredefinedFlags.PORT.validate_input_flag_value("8080")) # True +print(PredefinedFlags.PORT.validate_input_flag_value("99999")) # True +print(PredefinedFlags.PORT.validate_input_flag_value("abc")) # False + +# Флаги без значений +print(PredefinedFlags.HELP.validate_input_flag_value(None)) # True +print(PredefinedFlags.HELP.validate_input_flag_value("something")) # False + +# Проверка строковых представлений +print(PredefinedFlags.HELP.string_entity) # --help +print(PredefinedFlags.SHORT_HELP.string_entity) # -H +print(PredefinedFlags.HOST.string_entity) # --host +print(PredefinedFlags.SHORT_PORT.string_entity) # -P diff --git a/docs/root/api/command/flag.rst b/docs/root/api/command/flag.rst index c5de8b0..4452405 100644 --- a/docs/root/api/command/flag.rst +++ b/docs/root/api/command/flag.rst @@ -1,4 +1,269 @@ .. _root_api_command_flag: Flag -===== \ No newline at end of file +===== + +Объект ``Flag`` представляет собой сущность флага, регистрируемого для последующей обработки в приложении ``Argenta``. Его основная задача — определить параметры флага команды, включая имя, префикс и допустимые значения. ``Flag`` используется при создании команд с флагами и предоставляет механизм валидации входящих значений от пользователя. + +.. seealso:: + + Документация по :ref:`PossibleValues ` — сущность, определяющая допустимые значения флага. + + Документация по :ref:`InputFlag ` — объект распаршенного введённого флага. + + :ref:`Общая информация ` о флагах и их использовании в приложении ``Argenta`` + +----- + +Инициализация +------------- + +.. code-block:: python + :linenos: + + __init__( + self, name: str, *, + prefix: Literal["-", "--", "---"] = "--", + possible_values: list[str] | Pattern[str] | PossibleValues = PossibleValues.ALL, + ) -> None + +Создает новый флаг для регистрации в команде. + +* ``name`` : Имя флага (обязательный параметр) +* ``prefix`` : Префикс флага. По умолчанию ``"--"``. Возможные значения: ``"-"``, ``"--"``, ``"---"`` +* ``possible_values`` : Допустимые значения флага. По умолчанию ``PossibleValues.ALL``. Может быть списком строк, регулярным выражением или значением из enum ``PossibleValues`` + +**Атрибуты:** + +.. py:attribute:: name + + Имя флага в виде строки. + +.. py:attribute:: prefix + + Префикс флага. Один из: ``"-"``, ``"--"``, ``"---"``. + +.. py:attribute:: possible_values + + Определяет допустимые значения для флага. Может быть: + + * Списком строк — флаг принимает только значения из этого списка + * Регулярным выражением (``Pattern[str]``) — значение проверяется на соответствие паттерну + * Значением ``PossibleValues.ALL`` — флаг принимает любое значение + * Значением ``PossibleValues.NEITHER`` — флаг не должен иметь значения + +**Пример использования:** + +.. literalinclude:: ../../../code_snippets/flag_snippet.py + :linenos: + :language: python + +----- + +Свойства +-------- + +string_entity +~~~~~~~~~~~~~ + +.. code-block:: python + :linenos: + + @property + string_entity(self) -> str + +Возвращает строковое представление флага в формате ``prefix + name``. + +:return: Строковое представление флага + +Это свойство объединяет префикс и имя флага в единую строку, которая представляет, как флаг будет выглядеть в командной строке. + +**Пример использования:** + +.. literalinclude:: ../../../code_snippets/flag_snippet3.py + :linenos: + :language: python + +----- + +Магические методы +----------------- + +__str__ +~~~~~~~ + +.. code-block:: python + :linenos: + + __str__(self) -> str + +Возвращает строковое представление флага (аналогично ``string_entity``). + +:return: Строковое представление флага + +**Пример использования:** + +.. literalinclude:: ../../../code_snippets/flag_snippet4.py + :linenos: + :language: python + +----- + +__repr__ +~~~~~~~~ + +.. code-block:: python + :linenos: + + __repr__(self) -> str + +Возвращает отладочное представление объекта флага. + +:return: Строка в формате ``Flag`` + +**Пример использования:** + +.. literalinclude:: ../../../code_snippets/flag_snippet5.py + :linenos: + :language: python + +----- + +__eq__ +~~~~~~ + +.. code-block:: python + :linenos: + + __eq__(self, other: object) -> bool + +Сравнивает два флага на равенство по их строковому представлению. + +:param other: Объект для сравнения +:return: ``True``, если флаги равны, иначе ``False`` +:raises NotImplementedError: Если ``other`` не является экземпляром ``Flag`` + +Два флага считаются равными, если их ``string_entity`` идентичны. + +**Пример использования:** + +.. literalinclude:: ../../../code_snippets/flag_snippet6.py + :linenos: + :language: python + +----- + +PredefinedFlags +--------------- + +``argenta.command.flag.defaults.PredefinedFlags`` + +Класс ``PredefinedFlags`` предоставляет набор предопределенных флагов, которые можно использовать в приложениях без необходимости их ручного создания. Эти флаги покрывают наиболее распространенные сценарии использования и следуют общепринятым соглашениям командной строки. + +Все предопределенные флаги являются атрибутами класса и представляют собой готовые экземпляры ``Flag``. + +----- + +Доступные флаги +~~~~~~~~~~~~~~~ + +Информационные флаги + + +.. py:attribute:: PredefinedFlags.HELP + + Флаг для отображения справки: ``--help`` + + * ``name``: ``"help"`` + * ``prefix``: ``"--"`` (по умолчанию) + * ``possible_values``: ``PossibleValues.NEITHER`` + +.. py:attribute:: PredefinedFlags.SHORT_HELP + + Короткая версия флага справки: ``-H`` + + * ``name``: ``"H"`` + * ``prefix``: ``"-"`` + * ``possible_values``: ``PossibleValues.NEITHER`` + +.. py:attribute:: PredefinedFlags.INFO + + Флаг для отображения информации: ``--info`` + + * ``name``: ``"info"`` + * ``prefix``: ``"--"`` (по умолчанию) + * ``possible_values``: ``PossibleValues.NEITHER`` + +.. py:attribute:: PredefinedFlags.SHORT_INFO + + Короткая версия флага информации: ``-I`` + + * ``name``: ``"I"`` + * ``prefix``: ``"-"`` + * ``possible_values``: ``PossibleValues.NEITHER`` + +----- + +Флаги выбора +~~~~~~~~~~~~ + +.. py:attribute:: PredefinedFlags.ALL + + Флаг для выбора всех элементов: ``--all`` + + * ``name``: ``"all"`` + * ``prefix``: ``"--"`` + * ``possible_values``: ``PossibleValues.NEITHER`` + +.. py:attribute:: PredefinedFlags.SHORT_ALL + + Короткая версия флага выбора всех элементов: ``-A`` + + * ``name``: ``"A"`` + * ``prefix``: ``"-"`` + * ``possible_values``: ``PossibleValues.NEITHER`` + +----- + +Сетевые флаги +~~~~~~~~~~~~~ + +.. py:attribute:: PredefinedFlags.HOST + + Флаг для указания IP-адреса хоста: ``--host`` + + * ``name``: ``"host"`` + * ``prefix``: ``"--"`` (по умолчанию) + * ``possible_values``: Регулярное выражение для валидации IPv4: ``r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"`` + +.. py:attribute:: PredefinedFlags.SHORT_HOST + + Короткая версия флага хоста: ``-H`` + + * ``name``: ``"H"`` + * ``prefix``: ``"-"`` + * ``possible_values``: Регулярное выражение для валидации IPv4: ``r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"`` + +.. py:attribute:: PredefinedFlags.PORT + + Флаг для указания порта: ``--port`` + + * ``name``: ``"port"`` + * ``prefix``: ``"--"`` (по умолчанию) + * ``possible_values``: Регулярное выражение для валидации порта: ``r"^\d{1,5}$"`` + +.. py:attribute:: PredefinedFlags.SHORT_PORT + + Короткая версия флага порта: ``-P`` + + * ``name``: ``"P"`` + * ``prefix``: ``"-"`` + * ``possible_values``: Регулярное выражение для валидации порта: ``r"^\d{1,5}$"`` + +----- + +**Пример использования:** + +.. literalinclude:: ../../../code_snippets/predefined_flags_snippet.py + :linenos: + :language: python diff --git a/docs/root/api/command/flags.rst b/docs/root/api/command/flags.rst index 1ccdfcd..ee8ff86 100644 --- a/docs/root/api/command/flags.rst +++ b/docs/root/api/command/flags.rst @@ -63,20 +63,9 @@ add_flag **Пример использования:** -.. code-block:: python +.. literalinclude:: ../../../code_snippets/flags_snippet2.py :linenos: - - from argenta import Flags, ValueFlag, BooleanFlag - - # Создание коллекции - flags = Flags() - - # Динамическое добавление флагов - flags.add_flag(ValueFlag("config", help="Config file path")) - flags.add_flag(BooleanFlag("debug", help="Debug mode")) - flags.add_flag(ValueFlag("log-level", possible_values=["INFO", "DEBUG", "ERROR"])) - - print(len(flags.flags)) # 3 + :language: python ----- @@ -97,28 +86,9 @@ add_flags **Пример использования:** -.. code-block:: python +.. literalinclude:: ../../../code_snippets/flags_snippet3.py :linenos: - - from argenta import Flags, ValueFlag, BooleanFlag - - # Начальная коллекция - flags = Flags([ - ValueFlag("host", default="localhost") - ]) - - # Дополнительные флаги - additional_flags = [ - ValueFlag("port", default="8080"), - ValueFlag("database", help="Database name"), - BooleanFlag("ssl", help="Use SSL"), - BooleanFlag("verbose", help="Verbose output") - ] - - # Добавление списка флагов - flags.add_flags(additional_flags) - - print(len(flags.flags)) # 5 + :language: python ----- @@ -139,27 +109,9 @@ get_flag_by_name **Пример использования:** -.. code-block:: python +.. literalinclude:: ../../../code_snippets/flags_snippet4.py :linenos: - - from argenta import Flags, ValueFlag, BooleanFlag - - flags = Flags([ - ValueFlag("host", default="localhost"), - ValueFlag("port", default="8080"), - BooleanFlag("verbose") - ]) - - # Получение флага по имени - host_flag = flags.get_flag_by_name("host") - if host_flag: - print(f"Found flag: {host_flag.name}") - print(f"Default value: {host_flag.default}") - - # Поиск несуществующего флага - unknown_flag = flags.get_flag_by_name("nonexistent") - if unknown_flag is None: - print("Flag not found") + :language: python ----- @@ -180,24 +132,9 @@ __iter__ **Пример использования:** -.. code-block:: python +.. literalinclude:: ../../../code_snippets/flags_snippet5.py :linenos: - - from argenta import Flags, ValueFlag, BooleanFlag - - flags = Flags([ - ValueFlag("host", default="localhost"), - ValueFlag("port", default="8080"), - BooleanFlag("verbose") - ]) - - # Итерация по всем флагам - for flag in flags: - print(f"Flag: {flag.name} (type: {type(flag).__name__})") - - # Использование в list comprehension - flag_names = [flag.name for flag in flags] - print(f"All flags: {flag_names}") + :language: python ----- @@ -216,12 +153,6 @@ __getitem__ **Пример использования:** -.. code-block:: python +.. literalinclude:: ../../../code_snippets/flags_snippet6.py :linenos: - - from argenta import Flags, ValueFlag - - flags = Flags([ - ValueFlag("first"), - ValueFlag("second"), - ValueFlag("third") + :language: python