If your launch script allows you to specify a python target (and finishes quickly enough), you can use pythonArgs in launch.json to insert a shim.
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch via Shell Script",
"type": "python",
"pythonArgs": ["debug_shim.py", "launch.sh"],
"args": ["your", "app", "args"],
"request": "launch",
"program": "app.py"
}
]
}
debug_shim.py
import os, subprocess, sys
launcher, debugger, debugger_args = sys.argv[1], sys.argv[2], sys.argv[3:]
sys.exit(subprocess.run(
args=[launcher] + debugger_args,
env=dict(os.environ, LAUNCH_TARGET=debugger),
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stderr,
).returncode)
launch.sh
#!/usr/bin/env bash
# Or target could be passed along the command line as well.
# LAUNCH_TARGET="${1?}"
# ...stuff...
python "${LAUNCH_TARGET-app.py}" "${@}"
In my setup of v1.80.0 on WSL2, the debugger call is like so:
python python_args... debugger debugger_args... app app_args...
Then the call stack will be vscode -> shim -> launcher -> debugger -> app and the debugger will connect seamlessly, although if it takes more than several seconds VSCode will time out.
If your launch script allows you to specify a python target (and finishes quickly enough), you can use pythonArgs in launch.json to insert a shim.
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch via Shell Script",
"type": "python",
"pythonArgs": ["debug_shim.py", "launch.sh"],
"args": ["your", "app", "args"],
"request": "launch",
"program": "app.py"
}
]
}
debug_shim.py
import os, subprocess, sys
launcher, debugger, debugger_args = sys.argv[1], sys.argv[2], sys.argv[3:]
sys.exit(subprocess.run(
args=[launcher] + debugger_args,
env=dict(os.environ, LAUNCH_TARGET=debugger),
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stderr,
).returncode)
launch.sh
#!/usr/bin/env bash
# Or target could be passed along the command line as well.
# LAUNCH_TARGET="${1?}"
# ...stuff...
python "${LAUNCH_TARGET-app.py}" "${@}"
In my setup of v1.80.0 on WSL2, the debugger call is like so:
python python_args... debugger debugger_args... app app_args...
Then the call stack will be vscode -> shim -> launcher -> debugger -> app and the debugger will connect seamlessly, although if it takes more than several seconds VSCode will time out.
Adding the setup scripts to your .bashrc file will ensure that they are sourced before vscode begins debugging your program. The ROS2 documentation supports this method and provides an example.
In your .bashrc file add the following:
source /opt/ros/${ROS_DISTRO}/setup.bash
source ~/ros2_ws/install/local_setup.bash
Execute a command in the same shell before debugging
visual studio code - How to make VScode launch.json for a Python module - Stack Overflow
Debugging an active python file that creates launch.json is debugging launch.json
How do I run a Python script on a set of JSON files? - Stack Overflow
Videos
Hey everyone,
I want to debug a Python Skript using a different arch (x86_64 instead of arm64) then my default terminal. I was looking for ways to define a terminal profile (see also on stackoverflow) using the launch.json, but I haven't found a way yet. I started trying to use the argument preLaunchTask, but this seems to be executed outside of the terminal (and it also freezes for this specific task). Any ideas how to fix this?
// launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python (x86_64): script.py",
"type": "python",
"request": "launch",
"program": "/path/to/script.py",
"console": "integratedTerminal",
"justMyCode": true,
"preLaunchTask": "x86_64"
}
]
}
//tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "x86_64",
"type": "shell",
"command": "arch -x86_64 zsh"
}
]
}Specify the module you want to run with "module": "torch.distributed.launch"
You can ignore the -m flag. Put everything else under the args key.
Note: Make sure to include --nproc_per_node and the name of file (main_swav.py) in the list of arguments
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "debugpy",
"module": "torch.distributed.launch",
"request": "launch",
"console": "integratedTerminal",
"args": [
"--nproc_per_node", "1",
"main_swav.py",
"--data_path", "/dataset/imagenet/train",
]
}
]
}
Read more here: https://code.visualstudio.com/docs/python/debugging#_module
This is an example of my launch.json that I use to debug Python modules.
It has an additional configuration to debug "current file" (not as module) which is useful to keep.
{
linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "path.to.module",
"args": ["run_example --arg <arg>"],
"justMyCode": true
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true
}
]
}
This would replicate a terminal command to run a Python module like so:
python -m path.to.module run_example --arg <arg>
Mind that providing arguments in launch.json works like described until you need key/value pair args.
For example, the command
$ python main.py --verbose --name Test
has to be coded inside the launch.json arguments line like this:
"args": ["--verbose", "--name=Test"],
Find a nearly hidden hint in the "Watson" example in Python debug configurations in Visual Studio Code.
AAargh.. I just wasted 30 minutes of my life trying to figure out how to clearly define arguments with values. Sometimes things worked and sometimes total fail. I was just looking at the last error message: // Use IntelliSense to learn about possible attributes.
Turns out I had both my python program and the file launch.json active in the VScode open editor. I was making changes to launch.json, but FAILING to click on my python file before starting up the debugger.
Doh! Its not a surprise that a python interpreter fails when trying to run a .json file. Need to carefully read the complete error message. (The error message should say... hey you big dummy.. you should be using a .py file when executing python!)
Info shared here in case anybody else makes the same dumb mistake.
Here's the structure and code you are looking for:
$ python -m json.tool test2.json
[
"mkdir -p /home/ec2-user/data2/opt/ODS",
"mkdir -p /home/ec2-user/data4/opt/ODS",
"mkdir -p /home/ec2-user/data5/opt/ODS"
]
Python:
$ cat parse.py
import json
import sys
import subprocess
from pprint import pprint
jdata = open(sys.argv[1])
data = json.load(jdata)
print "start"
print(data)
for command in data:
subprocess.call(command, shell=True)
print "end"
jdata.close()
Output:
$ python parse.py test2.json
start
[u'mkdir -p /home/ec2-user/data2/opt/ODS', u'mkdir -p /home/ec2-user/data4/opt/ODS', u'mkdir -p /home/ec2-user/data5/opt/ODS']
end
In your example it would be better, to use os.makedirs.
But if you REALLY need subprocess module - i suggest you to exec command with single subprocess instance. For example:
subprocess.call('; '.join(data.values()), shell=True)
Actually, there is a very simple option to do this I found by accident while trying to edit the launch.json file.
"type": "python",
"request": "launch",
"pythonPath": "D:\\ProgramData\\Anaconda3\\envs\\simulec\\python.exe",
"module": "my_module.my_file",
Simply specify the module in the module key "module": "my_module.my_file"
The -m is not useful any more.
To add slightly to dzada's answer, which helped me a lot, a Visual Studio Code variable can be used to make this general for debugging any file that is in your module.
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "my_module.${fileBasenameNoExtension}"
}
]
}
Which is probably what you want to do.