ipywidgets
ipywidgets copied to clipboard
Proposal: allow `interact` to use type hint annotations for abbreviations
Problem
Type hint annotations are rapidly approaching maturity in the Python world, to the point where it is common for functions to provide these for the arguments.
Currently if you have a function with type annotations like:
def f(x: int) -> int:
return x**2
the interact function and related infrastructure can't infer anything from the annotation of the argument types, so
interact(f)
fails: the user must supply additional information. It seems like it would be reasonable in this situation to use basic type hints (eg. int, float, etc.) to provide a basic Widget for the argument (although maybe not a slider: something like IntText might be better), ie. to have behaviour which is equivalent to
interact(f, x=IntText())
Since interact is fairly basic, it probably only makes sense to support str, int, float, bool, and Enum - anything more complex should be ignored.
Proposed Solution
I think this can be achieved in a fairly straightforward way without changing current working behaviour as follows:
- in
_yield_abbreviations_for_parameteradd an additional branch to this block https://github.com/jupyter-widgets/ipywidgets/blob/b78de43e12ff26e4aa16e6e4c6844a7c82a8ee1c/python/ipywidgets/ipywidgets/widgets/interaction.py#L123-L130 which looks something like:
at line 128.elif param.annotation: value = param.annotation - add a new method
interactive.widget_from_annotationwhich branches on the type to create appropriate widgets for each supported type. Since there is no value or default supplied, this will use the default value of the widget type (eg. empty string forText, 0 forIntText, etc.). This might look something like this:@staticmethod def widget_from_annotation(t): """Make widgets from type annotation and optional default value.""" if t is str: return Text() elif t is bool: return Checkbox() elif t in {int, Integral}: return IntText() elif t in {float, Real}: return FloatText() elif isinstance(t, EnumType): return Dropdown(options={option.name: option for option in t}) else: return None - call this new method from
interactive.widget_from_abbrevin this section https://github.com/jupyter-widgets/ipywidgets/blob/b78de43e12ff26e4aa16e6e4c6844a7c82a8ee1c/python/ipywidgets/ipywidgets/widgets/interaction.py#L298-L311 around line 307
Because the annotations are only considered as abbreviations after all other possibilites have failed, existing working code will continue to produce the same results.
Additional context
I have a basic implemention along these lines working in this branch: https://github.com/corranwebster/ipywidgets/tree/feat/interact-type-hints