Understanding cancellation behavior in script tools

When a tool is running, a cancel button is available to stop the tool from further processing. By default, when a script tool or Python toolbox tool is cancelled, the script will be cancelled after the current line of code and the tool will fail with an appropriate error message ('Cancelled script <tool_name>... (<tool_name>) aborted by User.'). When this occurs, the cancel is final; there is no opportunity to execute any code after the cancellation takes place. For some scripts, this is all that is required, but in other cases, steps may be needed after the cancellation to clean up data, provide custom tool messages, or other behaviors.

The arcpy.env class includes two properties, autoCancelling and isCancelled for controlling cancellation behaviors. By default autoCancelling is set to True so that when a tool is cancelled, the cancellation will happen after the current line. If autoCancelling has been set to False, the script will continue to run until you choose to stop. When a tool has been cancelled, the read-only isCancelled property will switch from False to True.

PropertyDescription

arcpy.env.autoCancelling

When autoCancelling is set to True, a cancellation will end the script on the current line. If False, a cancellation will set the isCancelled property to True and continue executing. autoCancelling is set to True by default.

arcpy.env.isCancelled

When autoCancelling is set to False and the tool has been cancelled, isCancelled will be set to True. isCancelled is False by default and is a read-only property.

The following example represents a demonstration tool that takes a series of tables, makes a copy, and merges those intermediate tables together. If autoCancelling is left to it's default value of True, when cancelled the script will stop after the current line. The nature of this particular tool is that it creates several intermediate tables behind and we want to clean them up in any case, including a cancellation. By setting autoCancelling to False, the cancellation is delayed and the script can watch for any interval or place in the code we choose by evaluating the isCancelled property. Once isCancelled has flipped to True, we know that the tool has been cancelled and the immediate data will be deleted before finishing.

import arcpy

arcpy.env.autoCancelling = False


class CustomCancelException(Exception):
    """Custom exception for geoprocessing tool cancellations"""
    pass


def my_function(tables, output):
    temp_tables = []
    try:
        for table in tables:
            temp_tables.append(arcpy.CopyRows_management(table, '#')[0])

            # If isCancelled is True this means that the cancel button
            # has been pressed
            if arcpy.env.isCancelled:
                raise CustomCancelException('Tool has been cancelled')

        arcpy.Merge_management(tables, output)

    except CustomCancelException as err:
        arcpy.AddError(err)
    finally:
        # If tool is cancelled or finishes successfully, clean up intermediate data
        if temp_tables:
            for temp_table in temp_tables:
                arcpy.Delete_management(temp_table)
      

if __name__ == '__main__':
    inputs = arcpy.GetParameter(0)
    out_fc = arcpy.GetParameterAsText(1)

    my_function(inputs, out_fc)