Coding errors are inevitable, and there are two basic ways to find out where errors occur:
- Add some form of print statement to your code to help you isolate the problem.
- Use an interactive debugger.
Using print statements
Using print statements to discover bugs is an obvious and common method. Since script tools have access to the tool progress dialog box, you can edit your script to include calls to AddMessage, AddWarning, or AddError to print values and checkpoint messages to the progress dialog box. Another variation is to use an independent method of returning messages, such as the win32ui module's MessageBoxmethod. This method displays a pop-up dialog box. Since you must click OK on the dialog box to continue execution, this method allows you to pace the execution of the script. Here's an example using both methods:
import arcpy
import win32ui
import win32con
n = 5
# Print message to progress dialog
#
arcpy.AddMessage("Value of n = {}".format(n))
# Issue a popup dialog with OK and Cancel button
#
val = win32ui.MessageBox("Value of n = {}".format(n), "title",
win32con.MB_OKCANCEL)
# Based on the button clicked, you can branch execution
#
if val == 1:
arcpy.AddMessage("You clicked OK")
else:
arcpy.AddError("You clicked Cancel")
raise arcpy.ExecuteError, "Execution stops due to Cancel button click"
arcpy.AddMessage("This statement reached")
Using debuggers
The other method is to use a Python integrated development environment (IDE) that supports debugging. Debuggers allow you to set break points; step into, out of, and over individual lines of code; and examine the contents of variables, all without modifying your code. Compared to inserting printstatements, debuggers are much more efficient and usually allow you to quickly isolate a bug.
Common IDEs include the following:
- Python IDE installed with Python
- PythonWin
- PyScripter
- Commercial systems, such as Wing IDE and PyCharm
One way to use a debugger is to open your script directly in the IDE, modify it so that all parameters have values, then proceed with debugging. This works reasonably well in easy cases. However, if your script uses layer or table view parameters, these variables must be created on the fly. Complex parameters like a field map or spatial reference are hard to create as variables.
Ideally, you want to be able to open your script tool dialog box, enter parameters, and have an 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 uses 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.
Execute and debug your tool
- Set Debugger (such as PythonWin) in Geoprocessing > Geoprocessing Options.
- In the Catalog window, right-click your tool and click Debug.
- Open the script tool from the toolbox, enter any parameters you want to set, then click OK. It may take a few moments for your IDE to open. Your script code is displayed, and you are free to interact with the debugging application as you would normally.
You can set a break point and let the script run to the break point and use any other options the debugger allows. Parameter values you entered in the dialog box are 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 functions like AddMessage, AddWarning, or AddError, these messages will appear in the application. If you are using progressor functions, the progressor will be updated in the tool dialog box as you walk through your script. Once the script is finished, you can return to the application by closing the debugger. Alternatively, if you are planning on debugging your script tool a second time, you can keep the debugger open and click Cancel on the tool's progress dialog box.