One of the things I initially found challenging about developing Python plugins for Maya is how tricky they can be to debug. There’s a tendency for them to crash Maya when something goes wrong, leaving nothing but vague stack traces in their wake.
For instance, in the screenshot to the right we’re told that an error occurred inside the setInternalValueInContext method but no specifics are given.
If you’ve experienced this problem for yourself then you know how frustrating it can be to track down that elusive little IndexError, which takes you five minutes to reproduce every time. I’m here to tell you it doesn’t have to be this way! There are a handful of very simple steps you can take that will make your life a whole lot easier.
Step the First: Reroute Python output to the terminal.
A lot of times, the most basic step you can take to debug your work is add some print statements. Unfortunately, they’re not going to help you very much if they’re being routed to the history in Maya’s Script Editor, which just happens to conveniently disappear along w/ your crashed Maya session.
Don’t worry though, this one’s easy to fix! Simply run the following lines in a Python tab of the Script Editor or add them to the beginning of your plugin:
This will route all Python output to the terminal from which you launched Maya. Now, even if Maya crashes, you’ll still have a record of all the stuff your plugin printed!
Step the Second: Prevent errors from crashing Maya.
Obviously, the best way to prevent crashes is to fix your bugs. But wouldn’t it be nice if you didn’t have to relaunch Maya everytime you needed to test your bug fix or reproduce the problem? Plus if there was a way to see a more detailed traceback, that’d make it a lot easier to identify and fix whatever’s going wrong in your code.
Fortunately, there’s a way to do both by using Python’s try except mechanism combined with the traceback module. First, make sure both the sys and traceback modules are imported into your plugin.
Typically, I have three major methods in my plugins where things tend to break:
In the case of the get/setInternalValueInContext methods, I recommend setting them up like this:
That way if anything goes wrong inside the method, it’ll be harmlessly caught, the traceback will be printed (thanks traceback module!), and Maya will continue going about its business. Honestly, nine times out of ten, the information printed by traceback is enough to identify and fix whatever’s going wrong.
For the compute method, the setup is just as simple:
#INSERT CODE HERE
Step the Third: Use pdb to interactively debug code.
Ok, we’re now at a place where our development workflow isn’t at risk of being interrupted by a crash and errors are reported in an informative and non-fatal manner. At this point, if you’re still getting errors that can’t be easily debugged, it’s time to reach for a bigger gun: pdb!
As you may be aware, pdb is an interactive debugging tool that’s included with the Python standard library. It’s usage is very simple. Just make sure you have the pdb module imported into your code.
Then, insert the following line wherever you want to start debugging:
Once Maya reaches that line in your code, it will halt execution and let you step through line by line, query local values, run expressions, and more.
Since pdb is very well documented, I’m not going to reinvent the wheel by going through its usage here. Instead, I recommend you take a look at the following excellent references:
pdb (Python Module of the Week)
Suffice to say, pdb can be a very powerful tool in your debugging arsenal. It’s helped me track down issues in minutes that may have otherwise taken hours to resolve. It’s also a lot cleaner than inserting a thousand print statements.