7

I've a Python package package_name which provides a command line application command-line-app-name as console_script:

setup.py:

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

The virtualenv is located in <project>/.venv and managed with pipenv. pipenv managed venvs should support VSCode debugging integration. I've created a debugger configuration launch.json file with setting the Python path to the 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"
        }
    ]
}

The Windows and Linux specific venv python executable and command line arguments should not have an impact. If I run the debugger I get: FileNotFoundError: [Errno 2] No such file or directory: '/home/florian/gitlab/package-name/command-line-app-name'. It seems like I'm miss-interpreting the documentation somehow. I tried to find help w.r.t. vscode-python as well as debugpy without success. How can I debug a console script command line app (instead of a package module)?

3 Answers 3

8

console_scripts cannot be debugged out-of-the-box. The solution is to call the entry point function directly instead ("program": "${workspaceRoot}/package_name/cli.py",). This requires to add the if __name__ == '__main__': idiom in the corresponding module (here: cli.py). In my case the command line argument parser used is click. However the pseudo-code should be very similar for other command line parser libs.

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"
        }
    ]
}

NOTE: The tool used to manage the venv makes a difference. This solution does work in case the venv is managed with pipenv. The solution does not work in case the venv is managed with poetry.

Sign up to request clarification or add additional context in comments.

Comments

1

Here is a launch.json that worked for me to debug mkdocs plugins:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "console": "integratedTerminal",
            "module": "mkdocs",
            "args": ["serve"]
        }
    ]
}

mkdocs provides the mkdocs entry point that accepts several arguments such as build and serve. This launch.json allowed me to set a breakpoint in a mkdocs plugin python file and stop at that breakpoing after running the mkdocs build/serve process.

1 Comment

Running as a module, i.e. python -m mkdocs ..., is not the same thing as running a console script, which would just look like mkdocs ....
0

I managed to debug a CLI python package by using the generated Python executable located in the .venv/bin folder. Here is the launch.json file:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug python package CLI",
            "type": "debugpy",
            "request": "launch",
            "program": "${workspaceFolder}/.venv/bin/project-name", // Replace <project-name> with your package name
            "args": [
                "..."
            ],
            "console": "integratedTerminal",
            "cwd": "${workspaceFolder}",
            "env": {},
            "envFile": "${workspaceFolder}/.env",
        }
    ]
 }

Steps to Configure the Environment

1: Set up the virtual environment and install the package locally:

python -m venv .venv && source .venv/bin/activate && pip install -e .

Use the pip install -e . command to install the package in "editable" mode. This allows you to modify the code and debug it directly without needing to reinstall every time.

2: Start debugging using the Debug Python CLI configuration in VS Code as show in debug code VSC

Tip: Make sure the path to the executable (program field) points to the correct file in your virtual environment's bin directory (.venv/bin/project-name.py)

Hope this helps!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.