I just thought I’d share my setup that I use for debugging Toolkit code. Note that I’m using the paid version of PyCharm in order to do this. I believe it should be possible with Visual Studio Code as well, and I may add details on that later if I can get it working.
Why use a debugger?
Using a debugger can be extremely useful, as you can do all sorts of things like
Add breakpoints in your code.
Pause and step through the live execution
Read variable values as you go.
If you’re running your code through an IDE, then you can usually make use of the IDE’s debugger, however, it’s not so easy to debug your code when you need to run it in a DCC such as Maya or Nuke. That’s where remote debugging can come in. Typically this is used when you want to debug code that is running on another computer, but we can also use it to debug code that is running in a different process.
Please note that this isn’t something that Shotgun directly supports, I’ve added it here as a hopefully useful suggestion.
Setting it up
How you approach remote debugging will depend entirely on what IDE you’re using, and some may not support it at all. You should check out your IDE’s documentation to find out what’s possible.
Two IDEs that do support remote debugging are PyCharm (professional edition only) and Visual Studio Code (Free). There may be others as well.
Here is an example of how to get this up and running with PyCharm.
Make sure that you’re working in a sandbox configuration and that the code for the app, engine, or framework you want to debug is local to your machine.
Set your Toolkit configuration to point to your local copy of the app/engine/framework, by modifying the location descriptor to become a path/dev descriptor.
Open up the same app code in an existing project or as a new project in PyCharm.
In PyCharm you can set up Python Remote Debug just like in their documentation, however, rather than pointing at a different machine, you can point at localhost.
The above code can either be inserted into your Hook or App, or you can run it separately in your software’s Python editor once it’s launched.
Once you’ve run the above code, the Software will likely freeze until you resume from PyCharm. Now all that is left to do is to add your breakpoints to your code and start debugging.
So I managed to get the Visual Studio Code remote debugging working as well on Windows.
I couldn’t get it to work on Mac, due to the fact that it refused to download a more recent version of the Python Extension than 2018.6.0 which has a bug that means it can’t connect. That might just be problem isolated to me, but be warned, first check your Python extension is up to date. I have also not tried Linux
So as I mentioned in my first post, you can get Visual Studio Code and set this up for free.
Setting it up
So I essentially followed these steps:
Open the app folder in VS Code. It must be the folder, not just the individual python file you want to debug.
Ensure the python extension is installed and uptodate:
The port doesn’t matter too much as long as it doesn’t clash with a different process.
The localRoot and remoteRoot should be "${workspaceFolder}", unless Toolkit is running the code from a different location, then the folder you opened in VS Code.
Download ptvsd. The easiest way I found of doing this, was to pip install it to my local python intepreter. But since we need to import it in something like Maya, which has its own python intepretter, I copied the ptvsd folder from the site-packages folder to a separate location. The reason I did this, is because it is never a good idea to sys.path.append the site-packages folder from a different interpreter, as some libraries might be compiled specifically for a given interpreter. Therefore you might see errors if Maya’s native Python interpreter libs clash with your system installed libs.
Now you can either add the following code to your app, or run it in the Software’s native python script editor:
import sys
# Change the path to match where ever you copied the `ptvsd` package.
sys.path.append("E:\\python_libs")
import ptvsd
# Allow other computers to attach to ptvsd at this IP address and port.
ptvsd.enable_attach(address=('localhost', 5678), redirect_output=True)
# Pause the program until a remote debugger is attached
ptvsd.wait_for_attach()
Start the debugger in VS Code:
Now it should stop at any breakpoints you’ve added in your code!
Happy bug hunting!
This is great! Any suggestions on how to enable / disable remote debugging on-demand in ShotGrid? Where can I put some code to do it instead of adding the ptvsd.enable_attach() call in arbitrary files?
@jrapczak I run attach cmd directly from within apps console once it gets started. No need to insert it to the code at all. Of course you have to do it again if the app is restarted.
# installed debugpy with pip install -t to this directory
import sys; sys.path.append("C:/Users/myuser/Code/python-libs")
import debugpy
# required for hosted Python (e.g. Maya)
# got it from pyenv python >>> print(sys.executable)
debugpy.configure(python=r"C:\Users\myuser\.pyenv\pyenv-win\versions\3.9.13\python.exe")
try:
debugpy.listen(("127.0.0.1", 5678))
except RuntimeError as e:
if "Only one usage of each socket address" in str(e):
pass
debugpy.wait_for_client()
debugpy.breakpoint()
The reason behind the try block is because once the debugger is attached to a running Maya process, the listen function will fail if it runs again. Wrapping it in a try can let vscode attach the debugger to the same Maya process and keep debugging.
Let me know if you find ways to improve this update. I’ll be happy to discuss.