Como posso depurar aplicativos de linha de comando console_script do Python com o depurador VSCode?

Oct 27 2020

Tenho um pacote Python package_nameque fornece um aplicativo de linha de comando command-line-app-namecomo console_script:

setup.py:

setup(
    ...
    entry_points={"console_scripts": ["command-line-app-name=package_name.cli:main"]},
    ...
)

O virtualenv está localizado <project>/.venve gerenciado com pipenv. pipenvos venvs gerenciados devem oferecer suporte à integração de depuração VSCode. Criei um launch.jsonarquivo de configuração do depurador definindo o caminho Python para venv ( pythonPath):

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: command-line-app-name",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "program": "command-line-app-name",
            "linux": {
                "pythonPath": "${workspaceFolder}/.venv/bin/python", "args": ["-r", "/home/florian/gitlab/package_name/data/Test_MRM.d"] }, "windows": { "pythonPath": "${workspaceFolder}/.venv/Scripts/python.exe",
                "args": ["-r", "D:\\MassHunter\\Data\\demo_0000.d"],
            },
            "console": "integratedTerminal"
        }
    ]
}

O executável venv python específico para Windows e Linux e os argumentos de linha de comando não devem ter impacto. Se eu executar o depurador eu recebo: FileNotFoundError: [Errno 2] No such file or directory: '/home/florian/gitlab/package-name/command-line-app-name'. Parece que estou interpretando mal a documentação de alguma forma. Tentei encontrar ajuda para wrt vscode-python , bem como debugpy, sem sucesso. Como posso depurar um aplicativo de linha de comando de script de console (em vez de um módulo de pacote)?

Respostas

thinwybk Oct 27 2020 at 16:24

console_scriptsnão pode ser depurado pronto para uso. A solução é chamar a função do ponto de entrada diretamente ( "program": "${workspaceRoot}/package_name/cli.py",). Isso requer adicionar o if __name__ == '__main__':idioma no módulo correspondente (aqui cli.py:). No meu caso, o analisador de argumento da linha de comando usado é click. No entanto, o pseudo-código deve ser muito semelhante para outras bibliotecas de analisador de linha de comando.

package_name/cli.py:

@click.command()
@click.option(...)
def main(<args>, <kwargs>):
    ...


if __name__ == '__main__':
    main()  # pylint: disable=no-value-for-parameter

.vscode/launch.json:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: command-line-app-name",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "program": "${workspaceRoot}/package_name/cli.py",
            "linux": {
                "pythonPath": "${workspaceFolder}/.venv/bin/python", "args": ["-r", "/home/florian/gitlab/package_name/data/Test_MRM.d"] }, "windows": { "pythonPath": "${workspaceFolder}/.venv/Scripts/python.exe",
                "args": ["-r", "D:\\MassHunter\\Data\\demo_0000.d"],
            },
            "console": "integratedTerminal"
        }
    ]
}

NOTA : A ferramenta usada para gerenciar o venv faz a diferença. Esta solução funciona caso o venv seja gerenciado com pipenv. A solução não funciona caso o venv seja gerenciado com poetry.