Imprecise error messages in Python API for `SetParameters`
When we pass data of the wrong type or even None
to otb.Application.SetParams()
, we have no way to know what we did wrong.
In the stack trace we see messages like:
File "/path/to/OTB-7.2.0-Linux64/lib/python/otbApplication.py", line 2920, in SetParameterString
val = _otbApplication.Application_SetParameterString(self, parameter, value, hasUserValueFlag)
TypeError: in method 'Application_SetParameterString', argument 3 of type 'std::string'
But, which parameter is it? What is its value?
Instead, we could have
File "/home/luc/dev/tests/OTB-7.2.0-Linux64/lib/python/otbApplication.py", line 3239, in SetParameterValue
raise TypeError('Expected a string for %s, got %s for %s' % (paramKey, type(value), value))
TypeError: Expected a string for elev.geoid, got <class 'NoneType'> for None
thanks to something like
def SetParameterValue(self, paramKey, value):
paramType = self.GetParameterType(paramKey)
if paramType in [ParameterType_RAM,
ParameterType_String, ParameterType_InputFilename,
ParameterType_OutputImage, ParameterType_OutputVectorData,
ParameterType_OutputFilename,
ParameterType_Directory, ParameterType_InputImage,
ParameterType_InputVectorData]:
if not isinstance(value, str):
raise TypeError('Expected a string for %s, got %s for %s' % (paramKey, type(value), value))
return self.SetParameterString(paramKey, value)
elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList,
ParameterType_InputFilenameList, ParameterType_StringList,
ParameterType_ListView]:
if not isinstance(value, list):
raise TypeError('Expected a list for %s, got %s for %s' % (paramKey, type(value), value))
return self.SetParameterStringList(paramKey, value)
elif paramType in [ParameterType_Int, ParameterType_Radius]:
if not isinstance(value, int):
raise TypeError('Expected an int for %s, got %s for %s' % (paramKey, type(value), value))
return self.SetParameterInt(paramKey, value)
elif paramType in [ParameterType_Float]:
if not isinstance(value, float):
raise TypeError('Expected a float for %s, got %s for %s' % (paramKey, type(value), value))
return self.SetParameterFloat(paramKey, value)
elif paramType in [ParameterType_Double]:
if not isinstance(value, float):
raise TypeError('Expected a float for %s, got %s for %s' % (paramKey, type(value), value))
return self.SetParameterDouble(paramKey, value)
elif paramType in [ParameterType_Bool]:
if not isinstance(value, bool):
raise TypeError('Expected a bool for %s, got %s for %s' % (paramKey, type(value), value))
return self.SetParameterString(paramKey, str(value) )
elif paramType in [ParameterType_Group]:
return ApplicationProxy(self, paramKey)
elif paramType in [ParameterType_Choice]:
return ApplicationProxy(self, paramKey, value)
else:
print ("Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey))
return
All I've added are tests + raise
. It seems that some implicit conversions work like string
to bool
though. A more precise analysis shall be done in order to ignore the implicit conversions which are already supported.
Edited by Luc Hermitte