One of the major goals of param is to apply type validation and it does this well for Python literals. When it comes to callable objects, param is very lenient by assuming that the return value of the callable is of the right type. This is why you can use a imagen.PatternGenerator as the value of a param.Number for instance, even though the output of the PatternGenerator is incompatible.
For param.Number the line responsible for this hole in validation is here as self._check_value is skipped for callables. This situation could be improved by introducing support for a type annotation declaring the expected type of a method.
The API is still being decided, but perhaps we could have something like:
class Foo(param.Parameterized):
@param.output(np.ndarray)
def bar(...):
return baz # Expected to be an ndarray
Then you could query for the decorated types:
>>> Foo.param_output_types()
{'bar':np.ndarray}
API questions
- What arguments does
@param.output have? Setting the type as a mandatory first argument seems to make sense (every method has a single return value).
- Should the types be specified as classes/constructors (e.g
str,np.ndarray) or parameters param.String, param.Integer or both?
- Could this specify composite types? e.g a return value of
(int, str) or maybe multiple possible types? (int, str) | None?
- Should param have a flag to disallow unannotated callables from matching? This flag would be disabled by default for backwards compatibility.
- I think it might be worth being able to express the 'self type' somehow. This type matches that of the parameterized class itself...
These issues are worth thinking about even if the initial approach starts simple. It might also be worth looking at the type annotation syntax standardised in Python 3....
One of the major goals of param is to apply type validation and it does this well for Python literals. When it comes to callable objects, param is very lenient by assuming that the return value of the callable is of the right type. This is why you can use a
imagen.PatternGeneratoras the value of aparam.Numberfor instance, even though the output of thePatternGeneratoris incompatible.For
param.Numberthe line responsible for this hole in validation is here asself._check_valueis skipped for callables. This situation could be improved by introducing support for a type annotation declaring the expected type of a method.The API is still being decided, but perhaps we could have something like:
Then you could query for the decorated types:
API questions
@param.outputhave? Setting the type as a mandatory first argument seems to make sense (every method has a single return value).str,np.ndarray) or parametersparam.String, param.Integeror both?(int, str)or maybe multiple possible types?(int, str) | None?These issues are worth thinking about even if the initial approach starts simple. It might also be worth looking at the type annotation syntax standardised in Python 3....