Tips and Tricks - Debugging Python script tools

If you create your own script tools using Python, you'll appreciate these tips and tricks on debugging.

Coding errors are inevitable and there are two basic ways to find out where the error occurred:

    - Add some form of print statements to your code that help you isolate the problem.
    - Use an interactive debugger.

Using print statements to discover bugs is an obvious and common method. Since script tools have access to the tool progress dialog, you can edit your script to include calls to AddMessage(), AddWarning(), or AddError() to print values and checkpoint messages to the progress dialog. Another variation is to use an independent method of returning messages, like the win32ui module's MessageBox method. This method displays a popup dialog. Since you have to click OK on the dialog to continue execution, this method allows you to pace the execution of the script. Here's an example using both methods:

import arcgisscripting, win32ui, win32con
gp = arcgisscripting.create()
n = 5

# Print message to progress dialog
#
gp.AddMessage("Value of n = " + str(n))

# Issue a popup dialog with OK and Cancel button
#
val = win32ui.MessageBox("Value of n = " + str(n), "title", win32con.MB_OKCANCEL)

# Based on the button clicked, you can branch execution
#
if val == 1:
gp.AddMessage("You clicked OK")
else:
gp.AddError("You clicked Cancel")
raise arcgisscripting.ExecuteError, "Execution stops due to Cancel button click"

gp.AddMessage("This statement reached")

The other method is to use a Python IDE (Integrated Development Environment) that supports debugging, such as:

    - Python IDE that is installed with Python
    - PythonWin, available on the web at https://sourceforge.net/projects/pywin32
    - Commercial systems, such as Wing IDE (http://wingware.com)

Debuggers allow you to set breakpoints, step in, out, and over individual lines of code, and examine the contents of variables, all without modifying your code. Compared to inserting print statements, debuggers are much more efficient and usually allow you to quickly isolate your bug.  The illustration below shows how to use debug mode in PythonWin.

 

One way to use a debugger is to open your script directly in your IDE, modify it so that all parameters have values, and then proceed with debugging. This works reasonably well in simple cases. However, if your script uses layer or table view parameters, these variables need created on the fly. Complex parameters like a Field Map or Spatial Reference are hard to create as variables.

Ideally, you'd like to be able to open your script tool dialog, enter parameters, and then have the Python IDE launch with your code ready to be debugged. You can do this with a few simple changes,  described below.

Use GetParameterAsText()

The first step is to modify your script so that it used GetParameterAsText() instead of sys.argv[], as discussed in Understanding script tool parameters

This is a modification you can keep - there is no need to change your code back to using sys.argv[].

Create a .bat file that launches your IDE with your .py as an argument

The next step is to create a one-line batch file that will be the source of your script tool (instead of your .py file). This single line contains the pathname to your IDE plus the full path to the .py file, as illustrated below.

 

Below are 3 examples of how to set your batch (.bat) file for commonly used IDEs. You'll need to confirm that the path is correct for your computer. Other debuggers are of course valid options, and can be called in a similar fashion.

Python IDLE
"C:\Python25\pythonw.exe" "C:\Python25\Lib\idlelib\idle.pyw" "C:\mytools\myscript.py"

PythonWin
"C:\Python25\Lib\site-packages\pythonwin\Pythonwin.exe" "C:\mytools\myscript.py"

Wing IDE 2.1
"C:\Program Files\Wing IDE 2.1\bin\wing.exe" "C:\mytools\myscript.py"

Reset script tool path to the .bat file

The next step is to change your script tool properties to use this new batch file. In the ArcToolbox window, right-click your script tool and click Properties. Click the Source tab and change the script file to be the new .bat file you created, as illustrated below. Click OK.


 

Execute and debug your tool

Now you can open the script tool from the ArcToolbox window, enter the parameters, and click OK. Shortly afterwards, the debugging application specified in your batch file will open with your Python script displayed. At this point, you are free to interact with the debugging application as you would normally. You can set a breakpoint and let the script run to the breakpoint and use any other options the debugger allows. Parameter values you entered in the dialog will get picked up by GetParameterAsText().

When running the script, any interaction you would normally expect between the script and the application will still occur. So, if you're using methods like AddMessage(), AddWarning(), or AddError(), these messages will show up in the application. If you are using progressor methods (new at 9.3), the progressor will be updated in the tool dialog as you walk through your script. Once the script is finished, you can return back to the application by closing your debugger.

Reset the script tool source

Once you have fixed your bugs, you can reset the source to the script file from the .bat file back to the .py file.


Looking ahead to future releases, we will have integrated options that will make this process smoother. But for now, and with a few little tricks, you can easily perform your script tool debugging.

Published Monday, September 01, 2008 3:02 PM by dmhoneycutt

Comments

 

nilsbabel said:

Hi, great post.  I'm trying to get the batch file trick to work.  Is pythonwin supposed to start debugging when it starts up?  My script opens in PythonWin, but then I have to set the parameters and run it in the debugger.  Not very useful since I can just run it there to begin with.  I have some complex parameters (layers, etc.) and would like to debug it while executing the script tool.  What am I doing wrong?

September 3, 2008 12:53 PM
 

nilsbabel said:

Got it to work.  Basically you just start debugging.  You won't see your parameters but the script does pick them up.  Great trick.  Wish I would have known this a year ago.

September 4, 2008 12:31 PM
 

dwynne said:

Yes, exactly.  You wouldn't see the arguments in the 'Run script' dialog, but the arguments will get picked up with GetParameterAsText.

September 4, 2008 1:16 PM
 

curtvprice said:

I had an idea. Instead of a separate .bat file, could you insert something like this at the top of your python script?

blnDebug = True

if blnDebug:

 ## << collect parameters into list lstParms

 ## with a loop on gp.GetParameterAsText >>

 lstParms = [sys.argv[0]] + lstParms  # add script path

 os.execv(r"e:\program files\wing ide 3.1\bin\wing.exe", lstParms)

 sys.exit(0)

July 24, 2009 1:19 PM
Anonymous comments are disabled