Third excruciating attempt to understand the sparsely document difference between hasBeenValidated and altered when creating a Python Toolbox in Pro.
Please help me understand:
1) Use cases of the two
2) WHEN does validation occur and WHEN does checking altered status occur?
From the oft referenced, and seemingly sole, Official ESRI documentation page on the topic, Customizing Tool Behavior ,I understand the intent of altered.
I do NOT understand WHEN is the updateParameters method called, other than the altered property is immediately updated after changing a parameter value BUT internal validation does not occur.
I'm utterly confused.
TLDR: altered checks for None, hasBeenValidated checks for errors, and both are decided during updateParameters()
Long explanation below:
Ok, here's how I understand it.
I have a tool with 3 parameters: param0, param1, param2.
param0 is going to act as a switch for the filter in param0: if it's "Y", give me one list, if it's "N" give me another list, and then I'm being lazy so I'm not going to set behaviour for anything else.
param1 is just a pick-one list, and param2 is just there for me to add a message to it.
def getParameterInfo(self):
"""Define parameter definitions"""
param0 = arcpy.Parameter(
displayName="Param0",
name="param0",
datatype="GPString",
parameterType="Required",
direction="Input")
# param0.value = "N"
param1 = arcpy.Parameter(
displayName="Param1",
name="param1",
datatype="GPString",
parameterType="Required",
direction="Input")
param2 = arcpy.Parameter(
displayName="Param2",
name="param2",
datatype="GPString",
parameterType="Required",
direction="Input")
params = [param0, param1, param2]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
param0 = parameters[0]
param1 = parameters[1]
param2 = parameters[2]
if param0.value == "Y":
param1.filter.list = ["apple", "pear"]
elif param0.value == "N":
param1.filter.list = ["strawberry", "pineapple"]
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
param0 = parameters[0]
param1 = parameters[1]
param2 = parameters[2]
if param0.altered:
param0.setWarningMessage("param0 is altered")
else:
param0.setWarningMessage("param0 is not altered")
if param1.hasBeenValidated:
param2.setWarningMessage("param1 is validated, yeah")
else:
param2.setWarningMessage("param1 is not validated yet")
return
What I've found by experimenting this morning is that I could only really get something useable for altered and hasBeenValidated in updateMessages(), so that's what this example is going to use.
I'm not sure if that's always true, but it does stand to reason that hasBeenValidated is only helpful after updateParameters(), since that's when validation happens.
It goes: getParameterInfo()-->updateParameters()-->updateMessages(), in that order. updateParameters() gets called when you make any chance, and updateMessages() is called immediately after.
In any case, here's what I think the difference is.
altered: Is the parameter's current value different from None? This includes setting the default value, which is kind of dumb but whatever.
def getParameterInfo(self):
"""Define parameter definitions"""
param0 = arcpy.Parameter(
displayName="Param0",
name="param0",
datatype="GPString",
parameterType="Required",
direction="Input")
# param0.value = "N" # Set the default, if you want.
params =[param0]
return params
def updateMessages(self, parameters):
param0 = parameters[0]
if param0.altered:
param0.setWarningMessage("param0 is altered")
else:
param0.setWarningMessage("param0 is not altered")
If I've set the default:
hasBeenValidated: Is there are error on the parameter?
def updateParameters(self, parameters):
param0 = parameters[0]
if param0.value == "Y":
param1.filter.list = ["apple", "pear"]
elif param0.value == "N":
param1.filter.list = ["strawberry", "pineapple"]
return
def updateMessages(self, parameters):
param1 = parameters[1]
param2 = parameters[2]
if param1.hasBeenValidated:
param2.setWarningMessage("param1 is validated, yeah")
else:
param2.setWarningMessage("param1 is not validated yet")