ToolValidator class

For an overview of the ToolValidator class and use of parameter methods, see Customizing script tool behavior.

Parameter object

Access the tool parameters

Every tool parameter has an associated parameter object with properties and methods that are useful in tool validation. Parameters are contained in a list. The standard practice is to create the list of parameters in the ToolValidator class __init__ method, as shown in the code below.

def __init__(self):
    self.params = arcpy.GetParameterInfo()

You can also access parameters in a script (as opposed to the ToolValidator class) as shown below. The only reason to access the parameter list in a script is to set the symbology property.

params = arcpy.GetParameterInfo()

Parameter order

A tool's parameters and their order are defined on the Parameters tab of the tool's properties, as illustrated below.

Parameters and their order
Note:

The list of parameters is zero based, so the first parameter is at position zero in the list. To access the third parameter, you would enter p3 = self.params[2].

Methods

Method nameUsage description

setErrorMessage(message)

Marks the parameter as having an error (Error) with the supplied message. Tools do not execute if any of the parameters have an error.

setWarningMessage(message)

Marks the parameter as having a warning (Warning) with the supplied message. Unlike errors, tools do execute with warning messages.

setIDMessage(messageType, messageID, {AddArgument1}, {AddArgument2})

Allows you to set a system message. The arguments are the same as the AddIDMessage function.

clearMessage()

Clears out any message text and sets the status to informative (no error or warning).

hasError()

Returns true if the parameter contains an error.

hasWarning()

Returns true if the parameter contains a warning.

isInputValueDerived()

Returns true if the tool is being validated inside a model and the input value is the output of another tool in the model.

Parameter object methods

Properties

Property nameRead/WriteValueDescription

name

Read-only

String

Parameter name as defined on the Parameters tab of the tool's properties.

direction

Read-only

String: "Input", "Output"

Input/Output direction of the parameter as defined on the Parameters tab of the tool's properties.

datatype

Read-only

String

Data type as defined on the Parameters tab of the tool's properties.

parameterType

Read-only

String: "Required", "Optional", "Derived"

Type as defined on the Parameters tab of the tool's properties.

parameterDependencies

Read/write

List

A list of indexes of each dependent parameter.

value

Read/write

Value object

The value of the parameter.

defaultEnvironmentName

Read-only

String

The default environment setting as defined on the Parameters tab of the tool's properties.

enabled

Read/write

Boolean

False if the parameter is unavailable.

altered

Read-only

Boolean

True if the user modified the value.

hasBeenValidated

Read-only

Boolean

True if the internal validation routine has checked the parameter.

category

Read/write

String

The category of the parameter.

schema

Read-only

Schema object

The schema of the output dataset.

filter

Read/write

Filter object

The filter to apply to values in the parameter.

symbology

Read/write

String

The path to a layer file (.lyrx) used for drawing the output.

message

Read-only

String

The message to be displayed to the user. See setErrorMessage and setWarningMessage above.

Parameter object properties

Although many Parameter object properties are read/write, most of these properties can only be set or modified when you initially create or modify the object. Several properties, including name, displayName, datatype, direction, and parameterType, establish the characteristics of a tool and cannot be modified during validation methods (such as updateMessages and updateParameters).

Some code examples are shown below. For other coding examples, see Customizing script tool behavior.

ToolValidator properties versus script tool properties

You can set a parameter's default value, filter, symbology, and dependencies on the Parameters tab of the script tool's properties dialog box or in the ToolValidator class.

Properties that you set in the ToolValidator class override those set on the script tool properties dialog box and often provide additional customization options. For example, if you set the default value of a parameter to "BLUE" on the script tool properties dialog box, and reset it to "RED" in initializeParameters, the default value becomes "RED". Once initializeParameters has been called, the script tool properties dialog box will display "RED" as the default value. If you (or your users) get into the situation where changes you make to one of these four parameter properties on the script's properties dialog box are not saved, it may be because the property was overridden in the ToolValidator class.

parameterDependencies

Typically you'll set parameter dependencies for use by the Schema object. In the following two cases, the dependencies may already be set on the Parameters tab of the tool's properties dialog box:

  • For an output dataset parameter with a derived type, the dependency is the index of the parameter from which the output is derived.
  • For certain input data types, the dependency is the index of the parameter containing the information used by the control, as shown in the table below.

Parameter data typeDependent parameter data type

Area Unit

A geographic dataset used to determine the default units.

For example, the Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used.

Field

The table containing the fields.

For example, the Table View, Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used.

Field Mappings

A collection of fields in one or more input tables.

For example, the Table View, Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used.

Geostatistical Value Table

A table of datasets and fields to be used in Geostatistical Analyst tools.

Use the Geostatistical Layer data type.

Linear Unit

A geographic dataset used to determine the default units.

For example, the Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used.

Network Analyst Hierarchy Settings

The network dataset containing hierarchy information.

Use the Network Dataset data type.

Network Travel Mode

A list of travel modes.

Use the Network Data Source, Network Dataset, or Network Dataset Layer data type.

SQL Expression

The table containing the fields.

For example, the Table View, Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used.

Dependency data types

Dependencies are typically set in the initializeParameters method:


def initializeParameters(self):
    # Set the dependencies for the output and its schema properties
    self.params[2].parameterDependencies = [0, 1]

parameterType

The parameterType property can be required, optional, or derived.

  • Required—A value is required for the tool to run.
  • Optional—A value is not required for the tool to run.
  • Derived—An output value that is not provided as an input parameter. Derived parameters are always output parameters.

In validation, the parameterType value cannot be dynamically modified. However, it may be necessary for a parameter to behave as a required parameter or an optional parameter depending on other parameter settings. If this is the case, set the parameter as optional. Then, in the validation updateMessages method, use the Parameter setIDMessage method with message ID 530 or 735. Using message ID 530 or 735 will cause an optional parameter to behave as a required parameter.


# Force a parameter to be required using setIDMessage, if the preceding 
# parameter does not have a value.
if not self.params[4].valueAsText:
    self.params[5].setIDMessage('ERROR', 735)

value

This is the value of the parameter that the user entered or you set programmatically. You can set the value in initializeParameters in which case it serves as the initial default value for the parameter. You can also set values in updateParameters in response to user input as shown below.


def updateParameters(self):
    # Set the default distance threshold to 1/100 of the larger of the width
    #  or height of the extent of the input features.  Do not set if there is no 
    #  input dataset yet, or the user has set a specific distance (altered is true).
    if self.params[0].valueAsText:
        if not self.params[6].altered:
            extent = arcpy.Describe(self.params[0]).extent
        if extent.width > extent.height:
            self.params[6].value = extent.width / 100
        else:
            self.params[6].value = extent.height / 100

    return

A parameter's value property returns an object unless the parameter isn't populated in which case value returns None. To ensure that a parameter is populated, use an if check prior to using its value.

The code snippet below tests whether the value is equal to the string "Get Spatial Weights From File". This test works because the parameter data type is a string.


# If the option to use a weights file is selected, enable the 
#   parameter for specifying the file, otherwise disable it

if self.params[3].value:  # check that parameter has a value
    if self.params[3].value == "Get Spatial Weights From File":
        self.params[8].enabled = True
    else:
        self.params[8].enabled = False

Since a Value object does not support string manipulation, use the Value object's value property whenever a string is to be manipulated or parsed. The code sample below uses the os.path.dirname method to return the directory from a dataset.


if self.params[0].value:
    workspace = os.path.dirname(self.params[0].value.value)
Caution:

With the exception of Describe, don't use methods that take a catalog path—such as ListFields—in validation. The dataset may not exist when the tool is validated in ModelBuilder, and the method may fail or produce unexpected results.

Describe can be used on a Parameter object directly instead of using the parameter's value property. Using the value property is valid but is slower when working with layer inputs.

In the specific case of ListFields, the Describe object's fields property will provide the equivalent information.

Caution:

Don't set a parameter value in updateMessages since the value will not be validated by the internal validation routine.

altered

altered is true if the value of a parameter is changed—by entering an output path, for example. Once a parameter has been altered, it remains altered until the user empties (removes) the value in which case it returns to an unaltered state. Programmatically changing a value with validation code will change the altered state. That is, if you set a value for a parameter, the altered state of the parameter will be updated.

altered is used to determine whether you can change the value of a parameter. As an example, suppose a tool has a feature class parameter and a keyword parameter. If the feature class contains points or polygons, the keywords are RED, GREEN, and BLUE, and if lines, ORANGE, YELLOW, PURPLE, and WHITE.

Suppose the user enters a point feature class. If the keyword parameter is unaltered, you set the value to RED, since it's the default value.

If a line feature class is entered, you set the default value to ORANGE as long as the keyword parameter is unaltered.

However, if the keyword parameter has been altered by the user (that is, the keyword is set to GREEN), do not reset the keyword. The user has made their choice (GREEN) and you don't know their intention. They may change the feature class so that GREEN is valid or they may change the keyword (to PURPLE, for example). Since GREEN isn't a member of the set of keywords you created for lines, internal validation flags the parameter an error. Then the user has two options: change the input feature class or change the keyword.

if not self.params[2].altered:
    self.params[2].value = "POINT"

hasBeenValidated

hasBeenValidated is false if a parameter's value has been modified by the user since the last time updateParameters and internal validate were called. Once internal validate has been called, geoprocessing automatically sets hasBeenValidated to true for every parameter.

hasBeenValidated is used to determine whether the user has changed a value since the last call to updateParameters. You can use this information when deciding whether to check the parameter yourself.


# Set the default distance threshold to 1/100 of the larger of the width
#  or height of the extent of the input features. Do not set if there is no 
#  input dataset yet, or if the input features have already been validated,
#  or the user has set a specific distance (Altered is true).
if self.params[0].valueAsText and not self.params[0].hasBeenValidated:
    if not self.params[6].altered: 
        extent = arcpy.Describe(self.params[0]).extent
        width = extent.width
        height = extent.height
        if width > height:
            self.params[6].value = width / 100
        else:
            self.params[6].value = height / 100

category

Parameters can be grouped into categories in the Geoprocessing pane to minimize the size of the parameters or to group related parameters that will be infrequently used. Several ArcGIS Network Analyst extension tools use categories, as shown below.

Parameter categories

Since you can only set the category once, set it in initializeParameters. Setting categories in updateParameters has no effect. The code below shows putting parameters 4 and 5 into the Options category and parameters 6 and 7 into the Advanced category.

def initializeParameters(self):
    self.params[4].category = "Options"
    self.params[5].category = "Options"
    self.params[6].category = "Advanced"
    self.params[7].category = "Advanced"

Categories are always shown after noncategorized parameters. Do not put required parameters into categories, since the user may not see them in the Geoprocessing pane.

symbology

The symbology property associates a layer file (.lyrx) with an output parameter.

params[2].symbology = "E:/tools/extraction/ToolData/ClassByDist.lyrx"

Learn more about output symbology

schema object

Every output parameter of type feature class, table, raster, or workspace has a schema object. Only output feature classes, tables, rasters, and workspaces have a schema; other types do not. The schema object is created automatically through geoprocessing. You access this schema through the parameter object and set the rules for describing the output of the tool. After you set the schema rules, and on return from the ToolValidator class, the geoprocessing internal validation code examines the rules you set and updates the description of the output.

To review, the flow of control is as follows:

  1. When the tool is first opened in the Geoprocessing pane, initializeParameters is called. You set up the static rules (rules that don't change based on user input) for describing the output. No output description is created at this time, since the user hasn't specified values for any of the parameters (unless you've provided default values).
  2. Once the user interacts with the tool in the Geoprocessing pane, updateParameters is called.
  3. updateParameters can modify the schema object to account for dynamic behavior that can't be determined from the parameter dependencies (for example, adding a new field such as Add Field).
  4. After returning from updateParameters, the internal validation routines are called and the rules found in the schema object are applied to update the description of the output data.
  5. updateMessages is then called. You can examine the warning and error messages that internal validation may have created and modify them or add custom warning and error messages.

All schema properties are read and write except type, which is read-only.

Property nameValue

type

String: "Feature", "Table", "Raster" , "Container" (for workspaces and feature datasets)

clone

Boolean

featureTypeRule

String: "AsSpecified", "FirstDependency"

featureType

String: "Simple", "Annotation", "Dimension"

geometryTypeRule

String: "Unknown", "FirstDependency", "Min", "Max", "AsSpecified"

geometryType

String: "Point", "Multipoint", "Polyline", "Polygon"

extentRule

String: "AsSpecified", "FirstDependency", "Intersection", "Union", "Environment"

extent

Extent object

fieldsRule

String: "None", "FirstDependency", "FirstDependencyFIDs", "All", "AllNoFIDs", "AllFIDsOnly"

additionalFields

List of Field objects

cellSizeRule

String: "AsSpecified", "FirstDependency", "Min", "Max", "Environment"

cellSize

Double

rasterRule

String: "FirstDependency", "Min", "Max", "Integer", "Float"

rasterFormatRule

String: "Img", "Grid"

additionalChildren

List of datasets to add to a workspace schema

Schema object properties

Use FirstDependency

Several of the rules can be set to "FirstDependency", which means the value of the first parameter found in the parameter dependency array set will be used with parameter.parameterDependencies. In the code example below, parameter 2 has two dependent parameters, 0 and 1, and the first dependency is parameter 0.


# Set the dependencies for the output and its schema properties
self.params[2].parameterDependencies = [0, 1]

If any dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.

type

The type property is read-only and is set by geoprocessing.

clone

If true, the geoprocessing process will make an exact copy (clone) of the description in the first dependent parameter. The default value is false. Typically, you set clone to true in the initializeParameters method. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is cloned.

  • If parameter.parameterType is "Derived", an exact copy is made. This is the behavior of the Add Field tool.
  • If parameter.parameterType is "Required", an exact copy is made, but the catalog path to the dataset is changed. Catalog paths consist of two parts: the workspace and the base name, for example, E:/Data/TestData/netcity.gdb/infrastructure/roads.

    • Workspace = E:/Data/TestData/netcity.gdb/infrastructure
    • Base name = roads
    The rules used to construct new output names are as follows:
    • The base name is the same as the base name of the first input parameter containing a dataset (not the first dependency but the first parameter) appended with the name of the script tool (for example, roads_MyTool).
    • The workspace is set to the scratch workspace environment setting. If this is empty, the current workspace environment setting is used. If this is empty, the workspace of the first input parameter containing a dataset is used. If this workspace is read-only, the system temp directory is used.

After setting clone to true, all rule-based methods, such as featureTypeRule, geometryTypeRule, and extentRule, are set to "FirstDependency".

The two code examples below do equivalent work. Both examples are based on how the Clip tool creates the output schema.

Example 1: Explicitly set all rules

def initializeParameters(self):
    # Set the dependencies for the output and its schema properties
    #  The two input parameters are feature classes.
    self.params[2].parameterDependencies = [0, 1]

    # Feature type, geometry type, and fields all come from the first 
    #  dependency (parameter 0), the input features
    self.params[2].schema.featureTypeRule = "FirstDependency"
    self.params[2].schema.geometryTypeRule = "FirstDependency"
    self.params[2].schema.fieldsRule = "FirstDependency"

    # The extent of the output is the intersection of the input features 
    #  and the clip features (parameter 1)
    self.params[2].schema.extentRule = "Intersection"

    return
Example 2: Use clone to set rules to FirstDependency; then override the extent rule

def initializeParameters(self):
    # Set the dependencies for the output and its schema properties
    #  The two input parameters are feature classes.
    self.params[2].parameterDependencies = [0, 1]
    self.params[2].schema.clone = True
    return
    
def updateParameters(self):
    # The only property of the clone that changes is that the extent 
    #  of the output is the intersection of the input features 
    #  and the clip features (parameter 1)
    self.params[2].schema.extentRule = "Intersection"
    return

featureTypeRule

This setting determines the feature type of the output feature class. This rule has no effect on output rasters or tables.

ValueDescription

"AsSpecified"

The feature type will be determined by the featureType property.

"FirstDependency"

The feature type will be the same as the first parameter in the dependencies. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.

featureTypeRule values

featureType

When featureTypeRule is "AsSpecified", the value for featureType is used to specify the feature type of the output.

ValueDescription

"Simple"

The output will contain simple features. The geometry type of the features is specified with geometryTypeRule.

"Annotation"

The output will contain annotation features.

"Dimension"

The output will contain dimension features.

featureType values

geometryTypeRule

This setting determines the geometry type (such as point or polygon) of the output feature class.

ValueDescription

"Unknown"

This is the default setting. Typically, you should be able to determine the geometry type in updateParameters based on the values of other parameters. You only set the rule to "Unknown" if you don't have enough information to determine the geometry type.

"FirstDependency"

The geometry type is the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.

"Min", "Max"

The geometries of all dependent parameters are examined and the output geometry type is set to the minimum or maximum type found. "Min" and "Max" are defined as follows:

  • Point and Multipoint = 0
  • Polyline = 1
  • Polygon = 2
For example, if the dependent parameters are a point and polygon feature class, the minimum will be point, and the maximum will be polygon.

"AsSpecified"

The geometry type will be determined by the value of the geometryType property.

geometryTypeRule values

geometryType

Set this to the geometry type to use ("Point", "Multipoint", "Polyline", or "Polygon") when geometryTypeRule is "AsSpecified".

extentRule

ValueDescription

"AsSpecified"

The output extent will be specified in the extent property.

"FirstDependency"

The output extent is the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.

"Intersection"

The output extent will be the geometric intersection of all dependent parameters. (This is what the Clip tool uses, as shown below.)

"Union"

The output extent will be the geometric union of all dependent parameters.

"Environment"

The output extent will be calculated based on the Extent environment setting.

extentRule values

Example


# The extent of the output is the intersection of the input features 
#  and the clip features (the dependent parameters)
self.params[2].schema.extentRule = "Intersection"

extent

Set this to the extent to use when extentRule is "AsSpecified". You can set the extent with either a space-delimited string or a list with four values. The sequence is xmin, ymin, xmax, ymax.

Example

self.params[2].schema.extentRule = "AsSpecified"

self.params[2].schema.extent = "123.32 435.8 987.3 567.9"
# Alternatively use a list, as follows:
# self.params[2].schema.extent = [123.32, 435.8, 987.3, 567.9]

fieldsRule

fieldsRule determines the fields that will exist in the output feature class or table.

In the table below, FID stands for Feature ID but actually refers to the ObjectID field in every feature class or table.

ValueDescription

"None"

No fields will be output except ObjectID.

"FirstDependency"

Output fields will be the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.

"FirstDependencyFIDs"

Only the ObjectID of the first dependent input will be written to the output.

"All"

All fields in the list of dependent parameters will be output.

"AllNoFIDs"

All fields except ObjectIDs will be written to the output.

"AllFIDsOnly"

All ObjectID fields will be written to the output, but no other fields from the inputs will be written.

fieldsRule values

The following is an example of Clip using fieldsRule of "FirstDependency":


  def initializeParameters(self):
    # Set the dependencies for the output and its schema properties
    #  The two input parameters are feature classes.
    self.params[2].parameterDependencies = [0, 1]

    # Feature type, geometry type, and fields all come from the first 
    #  dependency (parameter 0), the input features
    self.params[2].schema.featureTypeRule = "FirstDependency"
    self.params[2].schema.geometryTypeRule = "FirstDependency"
    self.params[2].schema.fieldsRule = "FirstDependency"

    # The extent of the output is the intersection of the input features 
    #  and the clip features (parameter 1)
    self.params[2].schema.extentRule = "Intersection"

    return

additionalFields

Along with the fields that are added by the application of fieldsRule, you can add more fields to the output. additionalFields takes a list of field objects.

cellSizeRule

This determines the cell size of output rasters or grids.

ValueDescription

"AsSpecified"

The output cell size is specified in the cellSize property.

"FirstDependency"

The cell size is calculated from the first dependent parameter. If the dependent parameter is a raster, its cell size is used. For other types of dependent parameters, such as feature classes or feature datasets, the extent of the data is used to calculate a cell size. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.

"Min", "Max"

"Min" means the output cell size is the smallest cell size of the dependent parameters. "Max" means it is the largest cell size of the dependent parameters.

"Environment"

The output cell size is calculated based on the Cell Size environment setting.

cellSizeRule values

cellSize

Set this to the cell size to use when cellSizeRule is "AsSpecified".

rasterRule

This determines the data type—integer or float—contained in the output raster.

ValueDescription

"FirstDependency"

The data type (integer or float) is the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.

"Min", "Max"

Integer is considered smaller than float. For example, if there are two dependent parameters, one containing integers and the other containing floats, "Min" creates an integer output, and "Max" creates a float output.

"Integer"

The output raster contains integers (whole numbers).

"Float"

The output raster contains floats (fractional numbers).

rasterRule values

rasterFormatRule

This determines the output raster format, either "Grid" or "Img". The default is "Img", which is ERDAS IMAGINE format. "Grid" is an Esri format.

additionalChildren

A workspace is a container for datasets (features, tables, and rasters). These datasets are children of the workspace (think of the workspace as the parent). If the tool adds datasets to a new or existing workspace, you can update the description of the workspace by adding descriptions of the children. For example, you may have a tool that takes a list of feature classes (a multivalue), modifies them in some way, and writes the modified feature classes to an existing workspace. When the tool is used in ModelBuilder, the workspace is the derived output of the tool, and you can use this workspace as input to the Select Data tool. Select Data allows you to select a child dataset found in a container and use it as input to another tool.

The input to additionalChildren is one or more descriptions of the children. There are two forms of child descriptions:

FormDescription

value object

A feature class, table, raster, dimension, or annotation value as returned by the value property.

List object of the form [type, name, fields, extent, spatial reference]

A list containing a description of the child to be added. Only the first two entries in the list, type and name, are required. The remaining arguments are optional.

Member lists for additionalChildren

When adding more than one child, provide a list of child descriptions. If you're adding the children in list form, create a list of lists for additionalChildren.

The list form has five arguments, as described in the following table.

ArgumentTypeDescription

type

Required

One of the following: "Point", "Multipoint", "Polyline", "Polygon", "Table", "Raster", "Annotation", "Dimension"

name

Required

The name of the dataset. It can be the base name of the dataset (streets) or the full catalog path (E:\mydata\test.gdb\infrastructure\streets). When a full catalog path is provided, all but the base name (streets) is ignored.

fields

Optional

A list of field objects. This contains the fields appearing on the child, if known.

extent

Optional

A string or list containing the spatial extent of the child.

spatial reference

Optional

A spatial reference object.

Contents of the child list

These arguments must be supplied in the order shown. To skip an optional argument, use None or '#'.

Examples of setting a workspace schema are below. The examples are based on a script tool that has the following arguments:

Parameter indexParameter nameProperty

0

Input feature class

Feature class—input.

1

Input table

Table—input.

2

Input workspace

Workspace—input (an existing workspace that contains the results of the tool).

3

Derived workspace

Workspace—Derived output obtained from input workspace. The schema of this workspace is modified to contain additional children.

Example tool parameters

The tool takes the input feature class and table, copies both to the workspace, adds a new field to the feature class, and creates a polygon feature class in the workspace. (The actual work of the tool isn't important as it only serves to illustrate setting a workspace schema.) The code examples below build on one another, starting with simple usage of additionalChildren.

In initializeParameters, the output workspace is cloned from its dependent parameter (parameter 2). This dependency is set in the tool properties but can also be set in initializeParameters to prevent removal of the dependency in the tool's properties.

class ToolValidator:
    def __init__(self):
        self.params = arcpy.GetParameterInfo()

    def initializeParameters(self):
        self.params[3].parameterDependencies = [2]  # input workspace
        self.params[3].schema.clone = True  # Copy all existing contents to output
        return
Example: Copy the two inputs (no modifications) to the output workspace

def updateParameters(self):
    inFC = self.params[0].value  # input feature class
    inTable = self.params[1].value  # input table
    inWS = self.params[2].value  # input workspace
    if inFC and inTable and inWS:
        self.params[3].schema.additionalChildren = [inFC, inTable]
    return
Example: The tool creates a polygon feature class

The only properties known about this new feature class (when validating) are the name ("SummaryPolygon") and type ("polygon").


children = []  # New empty list
children.append(inFC)
children.append(inTable)
children.append(["polygon", "SummaryPolygon"])
self.params[3].schema.additionalChildren = children
Example: Add a field to the input feature class

# Create a field object with the name "Category" and type "Long".
newField = arcpy.Field()
newField.name = "Category"
newField.type = "Long"

# Describe the input feature class in order to get its list of fields. The 9.3
# version of the geoprocessing object returns fields in a list, unlike previous 
# versions, which returned fields in an enumerator.
desc = arcpy.Describe(inFC)
fieldList = desc.fields

# Add the new field to the list
fieldList.append(newField)

# Create a new child based on the input feature class, but with the 
# additional field added.
newChild = [desc.shapeType, desc.catalogPath, fieldList,
            desc.extent, desc.spatialReference]

# Now create our list of children and add to the schema.
children = []
children.append(newChild)
children.append(inTable)
children.append(["polygon", "SummaryPolygon"])
self.params[3].schema.additionalChildren = children

To create fields for SummaryPolygon (the new polygon feature class), create a list of field objects similar to the pattern shown in the above example.

Example: Multivalue input

In this example, the first parameter is a multivalue of feature classes. Each feature class in the multivalue is copied to the derived workspace. A new field, ProjectID, is added to each of the copied feature classes.


# 0 - input features (multivalue)
# 1 - input workspace
# 2 - derived workspace

import arcpy 

class ToolValidator:
    def __init__(self):
        self.params = arcpy.GetParameterInfo()

    def initializeParameters(self):
        self.params[2].parameterDependencies = [1]
        self.params[2].schema.clone = True
        return

    def updateParameters(self):
        inVT = self.params[0].value  # multivalue ValueTable
        inWS = self.params[1].value  # WorkSpace

        # Add each feature class to the output workspace. In addition,
        # add a new field "ProjectID" to each feature class.
        if inVT and inWS:
            rowCount = inVT.rowCount  # Number of rows in the MultiValue table
            children = []
            newField = arcpy.Field()
            newField.name = "ProjectID"
            newField.type = "Long"
            for row in range(0, rowCount):
                value = inVT.getValue(row, 0)
                if value:
                    d = arcpy.Describe(value)
                    fieldList = d.fields

                    # Note -- not checking if field already exists
                    fieldList.append(newField)

                    # Create new child with additional ProjectID field and
                    # add child to list of children.
                    child = [d.shapeType, d.catalogPath, fieldList]
                    children.append(child)            
                      
            self.params[2].schema.additionalChildren = children
        return

    def updateMessages(self):
        return

Filter object

The Filter object allows you to specify the choices available to the user for a parameter. For example, you can set up a field filter that limits choices to text fields. A filter does three jobs:

  • A filter only presents the user with valid choices when browsing for data. If you set a filter for point feature classes, only point feature classes are shown when the user browses for data. If you set a filter for text fields, the drop-down list of fields only shows text fields.
  • If a user types a parameter value (rather than choosing a value from the list or file browser), the value is compared to the filter. If the user enters an invalid value (a numeric field instead of a text field, for example), a warning or error occurs.
  • Because values are compared to their filter by internal validation, you don't have to program custom validation in the ToolValidator class.

There are two ways to specify filters:

  • On the Parameters tab of the tool's properties dialog box, click the parameter, click the cell next to Filter, and choose the filter type from the drop-down list. After choosing the filter type, a dialog box appears where you specify the values for the filter.
  • You can set the values programmatically in a ToolValidator class (examples are below). This provides some customization options that are not possible using the tool's properties dialog box, including defining dynamic filters based on other parameter values, filters for composite data types, and multiple filter types on the same parameter. Geoprocessing creates filters automatically for parameters of type string, long, double, feature class, file, field, and workspace. If you don't choose a filter on the tool's properties dialog box, a filter is still associated with the parameter—it's just empty. An empty filter is the same as no filter. By adding values to an empty filter, you activate the filter, and the user's choices are limited by the contents of the filter.

There are seven kinds of filters, as shown in the table below:

Filter typeValue

ValueList

A list of string or numeric values used with String, Long, Double, Boolean, Linear Unit, Areal Unit, and Time Unit data types.

For String or numeric filters, provide a list of values and only those values will be considered valid and shown in a drop-down list on the tool dialog box.

For Linear Unit, Areal Unit, and Time Unit ValueList filters, provide a list of unit keyword strings and only values using those units will be considered valid and shown in the unit drop-down list on the tool dialog box.

Range

A minimum and maximum value used with Long, Double, Linear Unit, Areal Unit, and Time Unit data types.

For Long and Double filters provide a list with two items: the minimum and maximum value. Only numbers specified between the minimum and maximum will be considered valid.

For Linear Unit, Areal Unit, and Time Unit Range filters, provide a list with two items: the minimum and maximum value including a unit. For example, ["1 Meters", "100 Meters"].

FeatureClass

A list of allowable feature class types specified by the values "Point", "Multipoint", "Polyline", "Polygon", "MultiPatch", "Annotation", and "Dimension". More than one value can be supplied to the filter.

File

A list of file suffixes, for example, ".txt" or ".xml".

Field

A list of allowable field types specified by the values "Short", "Long", "Single", "Double", "Text", "Date", "OID", "Geometry", "Blob", "Raster", "GUID", "GlobalID", and "XML". More than one value can be supplied to the filter.

Workspace

A list of allowable workspace types specified by the values "FileSystem", "LocalDatabase", and "RemoteDatabase". More than one value can be supplied.

Travel Mode Unit Type

A list of allowable travel mode's impedance attribute: "Time", "Distance", and "Other".

Filter type and values

Properties

PropertyDescription

type

The type of filter (ValueList, Range, FeatureClass, File, Field, and Workspace). You can set the type of filter when dealing with Long, Double, Linear Unit, Areal Unit, and Time Unit parameters (see the note below). For other types of parameters, there is only one valid type of filter, so setting the type on these parameters is ignored. If you do not want to filter values, set the list property to an empty list.

list

A list of values for the filter. If you do not want to filter values, set the list property to an empty list.

filter properties

ValueList

ValueList for String parameters

For a string parameter, the list can contain any number of strings. An example of setting the list of string values in initializeParameters is shown below. The parameter contains two choices: "NEW_FORMAT" and "OLD_FORMAT".


  def initializeParameters(self):
    # Set the fixed list of "file format type" parameter choices and its
    # default value.
    self.params[1].filter.list = ["OLD_FORMAT", "NEW_FORMAT"]
    self.params[1].value = "OLD_FORMAT"
    return

In the example above, you could set the list of values on the Parameter tab of the tool's properties dialog box instead. If you set the list of values to something else (such as "OLD" and "NEW") in the tool's properties, these values would be replaced by "OLD_FORMAT" and "NEW_FORMAT" when initializeParameters is called. The same is true for the default value—it can be set on the tool's properties dialog box, and reset in ToolValidator.

Note:

The list of values you provide in ToolValidator replaces the values set on the tool's properties dialog box. This allows you to update the values based on other parameters.

Continuing with this example, the following code shows updateParameters changing a list of values in another parameter based on whether the user chose "OLD_FORMAT" or "NEW_FORMAT":

def updateParameters(self):
    # Update the value list filter of the "feature type in file" parameter 
    # depending on the "file format type" parameter.
    if self.params[1].value.upper() == "OLD_FORMAT":
        self.params[2].filter.list = ["POINT", "LINE", "POLYGON"]
    elif self.params[1].value.upper() == "NEW_FORMAT":
        self.params[2].filter.list = ["POINT", "LINE", "POLYGON", 
                                      "POINT_WITH_ANNO", 
                                      "LINE_WITH_ANNO", 
                                      "POLYGON_WITH_ANNO"]

    # Provide default value for "feature type in file" parameter.
    if not self.params[2].altered:
        self.params[2].value = "POINT"

ValueList for Long and Double parameters

A Long or Double parameter can have a list of numeric values. The user can only choose or enter values that are in the list.

# Set filter for a Long parameter
self.params[7].filter.list = [10, 20, 30, 40, 50]

# Set filter for a Double parameter
self.params[8].filter.list = [10.0, 12.5, 15.0]

ValueList for Boolean parameters

There are two values for a Boolean parameter: true and false. The true value is always the first value in the list.

def initializeParameters(self):
    # Set the Boolean choice for including or excluding angles.
    self.params[6].filter.list = ["ANGLE", "NO_ANGLE"]

    # Set the default value to false (no angle).
    self.params[6].value = "NO_ANGLE"
    return

def updateParameters(self):
    # Enable angle format parameter if user wants angles.
    if self.params[6].value.upper() == "ANGLE":
        self.params[7].enabled = True

ValueList for Linear Unit, Areal Unit, and Time Unit parameters

A Linear Unit, Areal Unit, and Time Unit parameter can have a list of units. The user can only choose or enter units that are in the list

# Set filter for linear unit parameters
self.params[5].filter.type = "ValueList"
self.params[5].filter.list = ["Meters", "Kilometers"]

# Set filter for areal unit parameters
self.params[6].filter.type = "ValueList"
self.params[6].filter.list = ["Hectares", "SquareKilometers", "SquareMeters"]

# Set filter for time unit parameters
self.params[7].filter.type = "ValueList"
self.params[7].filter.list = ["Hours", "Days"]

Range

A Long, Double, Linear Unit, Areal Unit, or Time Unit parameter can have a Range filter. Range filters have two values: minimum and maximum. The first value in the list is the minimum. The range is inclusive, meaning the minimum and maximum are valid choices.

Range for Long and Double parameters

A Long or Double parameter can have a range of valid numeric values.

def initializeParameters(self):
    # Utility values must be between -10 and 10.
    self.params[7].filter.list = [-10, 10]

Range for Linear Unit, Areal Unit, and Time Unit parameters

A Linear Unit, Areal Unit, or Time Unit parameter can have a range of valid values. The user can specify any unit and it will be automatically converted for comparison to the unit of the minimum and maximum of the range filter.

# Set filter for linear unit parameters
self.params[5].filter.type = "Range"
self.params[5].filter.list = ["1 Meters", "10 Meters"]

# Set filter for areal unit parameters
self.params[6].filter.type = "Range"
self.params[6].filter.list = ["1 Acres", "10 Acres"]

# Set filter for time unit parameters
self.params[7].filter.type = "Range"
self.params[7].filter.list = ["1 Hours", "24 Hours"]

Set filter type on Long, Double, Linear Unit, Areal Unit, and Time Unit parameters

For Long, Double, Linear Unit, Areal Unit, and Time Unit parameters, the default filter type is ValueList. If you want it to be a Range filter, set the filter type in initializeParameters as follows:

def initializeParameters(self):
  # Set the 'score' value parameters to a range filter
  self.params[7].filter.type = "Range"
  self.params[7].filter.list = [-10, 10]
# Set both filter types for a single Linear Unit parameter
self.params[5].filter.type = "Range"
self.params[5].filter.list = ["0 Meters", "10000 Meters"]
self.params[5].filter.type = "ValueList"
self.params[5].filter.list = ["Meters", "Kilometers", "Feet", "Miles", "Yards"]

You can only set the filter type for Long, Double, Linear Unit, Areal Unit, and Time Unit parameters.

FeatureClass

The example below shows setting the feature type of one input parameter based on the feature type of another input parameter.

  def updateParameters(self):
    # Set the input feature type of the second parameter based
    # on the feature type of the first parameter.
    if self.params[0].valueAsText:
        desc = arcpy.Describe(self.params[0])
        feature_type = desc.shapeType.lower()

        if feature_type == "polygon":
            self.params[1].filter.list = ["point", "multipoint"]

        elif feature_type == "polyline":
            self.params[1].filter.list = ["polygon"]
      
        elif feature_type in ["point", "multipoint"]:
            self.params[1].filter.list = ["polyline"]

        else:
            self.params[1].filter.list = []
      
    return

File

The file filter contains a list of file suffixes that a file can have, such as .txt (simple text file) and .csv (comma-separated value). You can supply any text for a suffix—it doesn't have to be a suffix that ArcGIS recognizes. The suffix can be of any length and does not include the dot. The example below shows setting the filter for an input File parameter.

def initializeParameters(self):
    # Set the input file type to our recognized options file suffixes.
    self.params[0].filter.list = ["opt56", "opt57", "globalopt"]
    return

Field

The field filter defines the permissible field types. Values can be "Short", "Long", "Float", "Single", "Double", "Text", "Date", "OID", "Geometry", "Blob", "Raster", "GUID", "GlobalID", and "XML".

Display versus internal name

The four field types that have an internal name are shown in the following table:

Display nameInternal name

Short

SmallInteger

Long

Integer

Float

Single

Text

String

Field filter aliases

When specifying a field filter, you can use either the display or internal name; that is, the following two lines of code are equivalent:

self.params[1].filter.list = ["Short", "Long", "Float", "Text"]
self.params[1].filter.list = ["SmallInteger", "Integer", "Single", "String"]

If you supply the display name, such as "short", it is converted and stored in the filter as "SmallInteger". You may not need to access values in the field filter, but if you do, be aware that the internal name is stored. The code snippet below shows how to account for this:

self.params[1].filter.list = ["Short", "Long"]

if self.params[1].filter.list[0].lower() == "SmallInteger":
    # do something

Set a default field value

You can provide a default value for a field parameter by looping through the fields in the input table and choosing the first field that satisfies the filter.


def initializeParameters(self):
    self.params[1].filter.list = ["Short", "Long", "Float", "Double"]
    return

def updateParameters(self):
    if self.params[0].valueAsText and not self.params[1].altered:
        self.params[1].value = ""
        desc = arcpy.Describe(self.params[0])
        fields = desc.fields

        # Set default to the first field that matches your filter.
        for field in fields:
            fType = field.type.lower()
            if fType in ["SmallInteger", "Integer", "Single", "Double"]:
                self.params[1].value = field.name
                break
    return
Caution:

Do not use the ListFields function in ToolValidator. Instead, use the Describe function as shown above.

Workspace

The workspace filter specifies the types of input workspaces that are permissible. There are three values:

Workspace filterDescription

FileSystem

A system folder, used to store shapefiles, and grids

LocalDatabase

A file geodatabase

RemoteDatabase

An enterprise database connection

Related topics