как отлаживать приложение python click cli?

Я создал приложение cli, используя библиотеку кликов в python. Документации по отладке команд нет.

Без клика легко просто отлаживать файлы python в IDE, но когда мы используем клик, команды нужно запускать через настройку console_scripts в setup.py.


person vishal    schedule 30.03.2017    source источник


Ответы (6)


Это не очень хорошо документировано, но вы можете напрямую вызывать свои командные функции и, таким образом, запускать код в отладчике:

Пример кода:

import click

@click.command()
@click.option('--my_arg', default=1, help='a number')
def my_command(my_arg):
    click.echo("my_arg='%d'" % my_arg)

if __name__ == '__main__':
    my_command(['--my_arg', '3'])

Результат:

my_arg='3'
person Stephen Rauch    schedule 31.03.2017
comment
Как передать несколько аргументов? Особенно если один из них флаг? Спасибо! - person Alen Siljak; 17.02.2018
comment
@AlenSiljak, непонятно, о чем вы спрашиваете. И, если это не малейшие изменения в этом ответе, вероятно, должен быть новый вопрос. - person Stephen Rauch; 17.02.2018
comment
Это небольшое расширение этого примера. Что, если есть еще один параметр @click.option(--full, is_flag=True). Какой правильный синтаксис для его передачи в my_command? Если я добавлю другой массив с [--full, True], выполнение завершится ошибкой. Мне это нужно для отладки. - person Alen Siljak; 18.02.2018
comment
Это просто список. По сути, думайте как cmdlinestr.split() - person Stephen Rauch; 18.02.2018
comment
Степан, спасибо! Lint жалуется, что второй параметр отсутствует и это вводит в заблуждение, но это работает! - person Alen Siljak; 18.02.2018
comment
Остается ли этот вызов тривиальным, если приложение щелчка использует подкоманды и другие сложные шаблоны? Необходимость отладки в среде IDE связана с разработкой нетривиальных приложений. - person Jordan Stefanelli; 28.02.2019
comment
@JordanStefanelli, да, все осталось по-прежнему. - person Stephen Rauch; 28.02.2019
comment
Используя подход из ответа и при условии, что вы добавите import sys, вызов команды click в последнем условном выражении, просто добавив sys.argv[1:] в качестве параметра, команда получит полный набор параметров, поскольку она была вызвана из оболочки. - person blamblam; 19.06.2019
comment
@blamblam, это тестовый код. Гораздо лучше быть полным здесь... Кроме того, в реальной программе вы можете полностью отключить sys.argv[1:], и щелчок сделает это за вас. - person Stephen Rauch; 19.06.2019

Я опоздал на вечеринку на пару лет, но на случай, если кто-то еще придет сюда в поисках ответа, как я только что:

Вызов вашей функции с помощью CliRunner.invoke() вернет "Результат" объект с атрибутом "exc_info". Вы можете передать это traceback.print_exception() следующим образом:

runner = CliRunner()
result = runner.invoke(my_command)
traceback.print_exception(*result.exc_info)
person Jacob Jurmain    schedule 25.11.2019

setup.py генерирует:

  • console_script.exe
  • console_script-script.py

из командной строки:

console_app --help

расширяется до cmd конфигурации IDE:

python <absolute path to>\console_app-script.py --help

Протестировано в PyCharm 2018.2 — вы можете устанавливать и нажимать точки останова и сохранять ожидаемую парадигму cmdline/arg.

person Jordan Stefanelli    schedule 28.02.2019

Я обнаружил, что написание тестов — отличный способ отладки приложений Click CLI: http://click.pocoo.org/5/testing/

Начните очень просто с вашей функции и теста, затем добавьте к ней, убедившись, что тест говорит вам, что вам нужно...

Кроме того, установка значений по умолчанию помогает:

def run_files(input_file='/path/to/input_file', output_file='/path/to/output_file'): click.echo(input_file, output_file)

Я также обычно настраиваю ведение журнала и записываю все, когда начинаю:

logging.basicConfig(format='%(levelname)s %(message)s', level=logging.DEBUG)

Затем разбросайте их повсюду (у IU есть утилиты с отметками времени, но это не обязательно):

logging.info('[{0}] Blah blah selected...'.format(
             utils.get_timestamp()))

Вы также можете сделать это с помощью print или click.echo.

person nicorellius    schedule 05.05.2017

Вы можете использовать pdb следующим образом, поместив внутрь код, который вы хотите отлаживать:

import pdb
pdb.set_trace()

Например:

import click

@click.command()
def hello():
    msg = "hi"
    num = 3

    import pdb
    pdb.set_trace()

    click.echo('Hello1!')
    click.echo('Hello2!')
    click.echo(msg + num)

if __name__ == '__main__':
    hello()

Затем вы можете использовать pdb:

$ python hello.py 
> /home/eduardo/w/ifpb/cozer/hello.py(11)hello()
-> click.echo('Hello1!')
(Pdb) msg
'hi'
(Pdb) num
3
(Pdb) msg = hello
(Pdb) b 13
Breakpoint 1 at /home/eduardo/w/ifpb/cozer/hello.py:13
(Pdb) c
Hello1!
Hello2!
> /home/eduardo/w/ifpb/cozer/hello.py(13)hello()
-> click.echo(msg + num)
(Pdb) c
Traceback (most recent call last):
  File "hello.py", line 16, in <module>
    hello()
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "hello.py", line 13, in hello
    click.echo(msg + num)
TypeError: unsupported operand type(s) for +: 'Command' and 'int'

После ошибки мы можем попробовать еще раз решение:

$ python hello.py 
> /home/eduardo/w/ifpb/cozer/hello.py(11)hello()
-> click.echo('Hello1!')
(Pdb) msg
'hi'
(Pdb) num
3
(Pdb) b 13
Breakpoint 1 at /home/eduardo/w/ifpb/cozer/hello.py:13
(Pdb) c
Hello1!
Hello2!
> /home/eduardo/w/ifpb/cozer/hello.py(13)hello()
-> click.echo(msg + num)
(Pdb) num = str(num)
(Pdb) c
hi3
person Eduardo Santana    schedule 02.09.2019

Если вы хотите отладить модули/классы, которые выполняются после командных функций щелчка.

Доступным решением является создание скрипта, имитирующего поток, который выполняется после выполнения команды.

Затем, разместив точки отладки в необходимых строках, вы можете добиться функциональности отладки.

Это то, что я решил сделать после краткого поиска в Интернете.

person Mic    schedule 05.06.2017
comment
Не могли бы вы предоставить несколько примеров кода, чтобы показать, насколько это тривиально и доступно на самом деле? - person Jordan Stefanelli; 28.02.2019