Сообщить об ошибке.

Типы опций и параметров в модуле click

Передаваемые значения опциям и параметрам сценария командной строки всегда извлекаются как тип str, и могут конвертироваться в разные типы Python. Типы могут быть реализованы с различным поведением, и некоторые из них встроены в модуль click.

Встроенные типы модуля click передаются в качестве значения аргументу type. Аргумент type принимается декораторами @click.option() и @click.argument(), и конвертирует извлекаемое строковое значение опции или параметра в соответствующий тип Python.

Содержание:


Пример применения встроенных типов модуля click:

import click

@click.command()
@click.option('--str-date')
# указываем тип опции
@click.option('--date', type=click.DateTime(['%d.%m.%Y', '%Y-%m-%d']))
def test(date, str_date):
    click.echo(f'date = {date} ({type(date)})')
    click.echo(f'str-date = {str_date} ({type(str_date)})')

if __name__ == '__main__':
    test()

Вывод сценария:

$ python3 test.py --date 7.09.2021 --str-date 7.09.2021
# date = 2021-09-07 00:00:00 (<class 'datetime.datetime'>)
# str-date = 7.09.2021 (<class 'str'>)

$ python test.py --date 2021-09-07 --str-date 2021-09-07
# date = 2021-09-07 00:00:00 <class 'datetime.datetime'>
# str-date = 2021-09-07 <class 'str'>

$ python test.py --help
# Usage: test.py [OPTIONS]
# Options:
#   --date [%d.%m.%Y|%Y-%m-%d]
#   --str-date TEXT
#   --help        Show this message and exit.

Встроенные вспомогательные типы модуля click.

click.STRING::

Тип click.STRING - это извлекаемый тип по умолчанию, который указывает строки Unicode. Так же, вместо него можно указывать встроенный в Python тип str.

click.INT::

Тип click.INT принимает только целые числа. Так же, вместо него можно указывать встроенный в Python тип int.

click.FLOAT::

Тип click.FLOAT принимает значения с плавающей запятой. Так же, вместо него можно указывать встроенный в Python тип float.

click.BOOL::

Тип click.BOOL принимает логические значения. Так же, вместо него можно указывать встроенный в Python тип bool.

Такие строковые значения как '1', 'true', 't', 'yes', 'y', и 'on' автоматически будут конвертироваться в True, а '0', 'false', 'f', 'no', 'n', и 'off' будут конвертироваться в False.

click.UUID::

Тип click.UUID принимает значения UUID. Он не угадывается, а представляется как uuid.UUID.

click.File(mode='r', encoding=None, errors='strict', lazy=None, atomic=False):

Тип click.File() объявляет параметр как файл для чтения или записи. Файл автоматически закрывается после разрыва контекста (после завершения работы команды).

Файлы можно открывать для чтения mode='r' или записи mode='w'. Специальное значение - указывает на stdin или stdout в зависимости от режима mode.

По умолчанию файл открывается для чтения текстовых данных, но его также можно открыть в двоичном режиме ('rb' или 'wb'). Аргумент encoding может использоваться для принудительного применения определенной кодировки.

Флаг lazy определяет, следует ли открывать файл немедленно или при первом вводе-выводе. По умолчанию это режим lazy=False для стандартных входных и выходных потоков, а также для файлов, открытых для чтения, в противном случае включен режим lazy=True. При ленивом открытии файла для чтения он все равно временно открывается для проверки, но не будет оставаться открытым до первого ввода-вывода. Режим lazy=True в основном полезен при открытии файлов для записи, чтобы избежать создания файла до тех пор, пока он не понадобится.

Начиная с Click 2.0, файлы также можно открывать атомарно, и в этом случае все записи переходят в отдельный файл в той же папке, а по завершении файл будет перемещен в исходное расположение. Такое поведение полезно, если файл, регулярно читается и изменяется другими пользователями.

click.Path(exists=False, file_okay=True, dir_okay=True, writable=False, readable=True, resolve_path=False, allow_dash=False, path_type=None):

Тип click.Path() аналогичен типу click.File(), но выполняет другие проверки. Прежде всего, вместо возврата дескриптора открытого файла он возвращает только имя файла. Во-вторых, он может выполнять различные базовые проверки того, каким должен быть файл или каталог.

Передаваемые аргументы:

  • exists (bool) - если True, то файл или каталог должны существовать, чтобы это значение было допустимым. Если это не требуется и файл действительно не существует, все дальнейшие проверки автоматически пропускаются.
  • file_okay: (bool) - проверяет, является ли путь файлом.
  • dir_okay: (bool) - проверяет, является ли путь каталогом.
  • writable: (bool) - если True, то выполняется проверка с возможностью записи.
  • readable: (bool) - если True, то выполняется проверка возможности чтения.
  • resolve_path: (bool) - если True, то путь будет полностью разрешен до того, как значение будет передано дальше. Это означает, что он абсолютен, и символические ссылки разрешены. Он не будет расширять префикс ~, так как это должно выполняться только оболочкой.
  • allow_dash: (bool) - если True, то допускается использование одной черточки для обозначения стандартных потоков.
  • path_type: преобразует значение входящего пути в указанный тип. Если преобразование невозможно, то сохранит тип str. Полезно преобразовать в файл pathlib.Path.

Изменено в версии 8.0: Вместо встроенного типа click.Path теперь можно указывать pathlib.Path, например: type=pathlib.Path.

click.Choice(choices, case_sensitive=True):

Тип click.Choice() позволяет сравнивать значение с фиксированным набором поддерживаемых значений. Все эти значения должны быть строками.

Важно! Аргумент choices принимает только список или кортеж. Другие итерации (например, генераторы) могут привести к неожиданным результатам. Помните, если передать строку, то она будет интерпретироваться как кортеж символов!

Аргумент case_sensitive по умолчанию имеет значение True, т.е. чувствителен к регистру символов. Установите значение False, чтобы сделать выбор нечувствительным к регистру.

Результирующее значение всегда будет одним из первоначально переданных элементов, независимо от того, указан ли case_sensitive или какой-либо ctx.token_normalize_func.

click.IntRange(min=None, max=None, min_open=False, max_open=False, clamp=False):

Тип click.IntRange() ограничивает значение click.INT диапазоном допустимых значений.

Если аргументы min или max не переданы, то в этом направлении принимается любое значение. Если аргументы min_open или max_open (тип bool) включены, то соответствующая граница не включается в диапазон.

Если аргумент clamp=True, то значение вне диапазона фиксируется на границе min или max, при этом ошибка не выдается.

Изменено в версии 8.0: Добавлены параметры min_open и max_open.

click.FloatRange(min=None, max=None, min_open=False, max_open=False, clamp=False):

Метод click.FloatRange() ограничивает значение click.FLOAT диапазоном допустимых значений.

Если аргументы min или max не переданы, то в этом направлении принимается любое значение. Если аргументы min_open или max_open (тип bool) включены, то соответствующая граница не включается в диапазон.

Если аргумент clamp=True, то значение вне диапазона фиксируется на границе min или max, при этом ошибка не выдается. Это поведение не поддерживается, если какая-либо граница min или max не имеет значения (открыта).

Изменено в версии 8.0: Добавлены параметры min_open и max_open.

click.DateTime(formats=None):

Метод click.DateTime() преобразует строки даты в объекты datetime.datetime.

Проверяемые строки формата formats можно настроить, но по умолчанию используются некоторые распространенные (без учета часовых поясов) форматы ISO 8601.

При указании аргумента formats следует передавать только список или кортеж из форматов даты в том порядке, в котором они должны быть опробованы. Другие итерации (например, генераторы) могут привести к неожиданным результатам. Помните, если передать строку формата, то она будет интерпретироваться как кортеж символов!

Строки формата обрабатываются с использованием datetime.strptime, и это, следовательно, определяет допустимые строки формата.

Разбор выполняется с использованием каждого формата, переданного списка форматов, по порядку, и используется первый формат, который был успешно проанализирован.

По умолчанию используется кортеж с форматами: ('%Y-%m-%d', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%d %H:%M:%S').

Реализация пользовательских типов.

Чтобы реализовать собственный настраиваемый тип, необходимо создать подкласс класса click.ParamType. Чтобы преобразовать значение из строки в правильный тип, необходимо переопределить метод convert().

Следующий код реализует целочисленный тип, который принимает шестнадцатеричные и восьмеричные числа в дополнение к обычным целым числам и преобразует их в обычные целые числа.

import click

class BasedIntParamType(click.ParamType):
    name = "integer"

    def convert(self, value, param, ctx):
        if isinstance(value, int):
            return value

        try:
            if value[:2].lower() == "0x":
                return int(value[2:], 16)
            elif value[:1] == "0":
                return int(value, 8)
            return int(value, 10)
        except ValueError:
            self.fail(f"{value!r} is not a valid integer", param, ctx)

BASED_INT = BasedIntParamType()

Атрибут name не является обязательным и используется для документации. если преобразование не удалось, то необходимо вызвать метод self.fail(). В некоторых случаях, например, в приглашениях, аргументы param и ctx могут иметь значение None.

Значения из пользовательского ввода или командной строки будут строками, но значения по умолчанию и аргументы Python могут уже иметь правильный тип. Пользовательский тип должен проверять вверху, действительно ли значение уже допустимо, и передавать его для поддержки этих случаев.