peng-lab / napari-basicpy

BSD 3-Clause "New" or "Revised" License
2 stars 3 forks source link

Fields with `typing.Any` causes ValueError #6

Open yfukai opened 1 year ago

yfukai commented 1 year ago

The following happened when initializing napari plugin. Maybe we need to exclude fields with Any annotation.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)     
File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/napari/_qt/menus/plugins_menu.py:105, in PluginsMenu._add_plugin_actions.<locals>._add_toggle_widget(key=('napari-basicpy', 'BaSiC Shadow Correction'), hook_type='dock')                                                                     
    102     return                                                              
    104 if hook_type == 'dock':                                                 
--> 105     self._win.add_plugin_dock_widget(*key)                              
        key = ('napari-basicpy', 'BaSiC Shadow Correction')                     
        self._win = <napari._qt.qt_main_window.Window object at 0x19407c8b0>    
        self = <napari._qt.menus.plugins_menu.PluginsMenu object at 0x197353640>
    106 else:                                                                   
    107     self._win._add_plugin_function_widget(*key)

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/napari/_qt/qt_main_window.py:811, in Window.add_plugin_dock_widget(self=<napari._qt.qt_main_window.Window object>, plugin_name='napari-basicpy', widget_name='BaSiC Shadow Correction', tabify=False)
    808         wdg = wdg._magic_widget
    809     return dock_widget, wdg
--> 811 wdg = _instantiate_dock_widget(
        Widget = <class 'napari_basicpy._widget.BasicWidget'>
        self = <napari._qt.qt_main_window.Window object at 0x19407c8b0>
    812     Widget, cast('Viewer', self._qt_viewer.viewer)
    813 )
    815 # Add dock widget
    816 dock_kwargs.pop('name', None)

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/napari/_qt/qt_main_window.py:1465, in _instantiate_dock_widget(wdg_cls=<class 'napari_basicpy._widget.BasicWidget'>, viewer=Viewer(camera=Camera(center=(0.0, 0.0, 0.0), zoo...ouse_drag_gen={}, _mouse_wheel_gen={}, keymap={}))
   1460             break
   1461         # cannot look for param.kind == param.VAR_KEYWORD because
   1462         # QWidget allows **kwargs but errs on unknown keyword arguments
   1463 
   1464 # instantiate the widget
-> 1465 return wdg_cls(**kwargs)
        kwargs = {'viewer': Viewer(camera=Camera(center=(0.0, 0.0, 0.0), zoom=1.0, angles=(0.0, 0.0, 90.0), perspective=0.0, mouse_pan=True, mouse_zoom=True), cursor=Cursor(position=(1.0, 1.0), scaled=True, size=1, style=<CursorStyle.STANDARD: 'standard'>), dims=Dims(ndim=2, ndisplay=2, last_used=0, range=((0, 2, 1), (0, 2, 1)), current_step=(0, 0), order=(0, 1), axis_labels=('0', '1')), grid=GridCanvas(stride=1, shape=(-1, -1), enabled=False), layers=[], help='', status='', tooltip=Tooltip(visible=False, text=''), theme='dark', title='napari', mouse_over_canvas=False, mouse_move_callbacks=[], mouse_drag_callbacks=[], mouse_double_click_callbacks=[], mouse_wheel_callbacks=[<function dims_scroll at 0x18d9203a0>], _persisted_mouse_event={}, _mouse_drag_gen={}, _mouse_wheel_gen={}, keymap={})}
        wdg_cls = <class 'napari_basicpy._widget.BasicWidget'>

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/napari_basicpy/_widget.py:48, in BasicWidget.__init__(self=<napari_basicpy._widget.BasicWidget object>, viewer=Viewer(camera=Camera(center=(0.0, 0.0, 0.0), zoo...ouse_drag_gen={}, _mouse_wheel_gen={}, keymap={}))
     45 layer_select_container = QWidget()
     46 layer_select_container.setLayout(layer_select_layout)
---> 48 simple_settings, advanced_settings = self._build_settings_containers()
        self = <napari_basicpy._widget.BasicWidget object at 0x1973cc0d0>
     49 self.advanced_settings = advanced_settings
     51 self.run_btn = QPushButton("Run")

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/napari_basicpy/_widget.py:127, in BasicWidget._build_settings_containers(self=<napari_basicpy._widget.BasicWidget object>)
    120     return create_widget(
    121         value=default,
    122         annotation=type_,
    123         options={"tooltip": description},
    124     )
    126 # all settings here will be used to initialize BaSiC
--> 127 self._settings = {k: build_widget(k) for k in BaSiC().settings.keys()}
        self = <napari_basicpy._widget.BasicWidget object at 0x1973cc0d0>
        BaSiC = <class 'basicpy.basicpy.BaSiC'>
    129 self._extrasettings = dict()
    130 # settings to display correction profiles
    131 # options to show flatfield/darkfield profiles

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/napari_basicpy/_widget.py:127, in <dictcomp>(.0=<dict_keyiterator object>)
    120     return create_widget(
    121         value=default,
    122         annotation=type_,
    123         options={"tooltip": description},
    124     )
    126 # all settings here will be used to initialize BaSiC
--> 127 self._settings = {k: build_widget(k) for k in BaSiC().settings.keys()}
        k = 'resize_params'
        BaSiC = <class 'basicpy.basicpy.BaSiC'>
    129 self._extrasettings = dict()
    130 # settings to display correction profiles
    131 # options to show flatfield/darkfield profiles

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/napari_basicpy/_widget.py:120, in BasicWidget._build_settings_containers.<locals>.build_widget(k='resize_params')
    118     pass
    119 # name = field.name
--> 120 return create_widget(
        default = {}
        type_ = typing.Any
        description = 'Parameters for the resize function when downsampling images.'
        {"tooltip": description} = {'tooltip': 'Parameters for the resize function when downsampling images.'}
    121     value=default,
    122     annotation=type_,
    123     options={"tooltip": description},
    124 )

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/magicgui/widgets/bases/_create_widget.py:119, in create_widget(value={}, annotation=typing.Any, name='', param_kind='POSITIONAL_OR_KEYWORD', label=None, gui_only=False, app=None, widget_type=None, options={'tooltip': 'Parameters for the resize function when downsampling images.'}, is_result=False, raise_on_unknown=True)
    112 if (
    113     not _options.get("widget_type")
    114     and (name or "").lower() == "password"
    115     and annotation is str
    116 ):
    117     _options["widget_type"] = "Password"
--> 119 wdg_class, opts = get_widget_class(
        _options = {'tooltip': 'Parameters for the resize function when downsampling images.'}
        value = {}
        annotation = typing.Any
        is_result = False
        raise_on_unknown = True
    120     value, annotation, _options, is_result, raise_on_unknown
    121 )
    123 if issubclass(wdg_class, Widget):
    124     widget = wdg_class(**{**kwargs, **opts, **_options})

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/magicgui/type_map/_type_map.py:314, in get_widget_class(value={}, annotation=typing.Any, options={'tooltip': 'Parameters for the resize function when downsampling images.'}, is_result=False, raise_on_unknown=True)
    284 def get_widget_class(
    285     value: Any = Undefined,
    286     annotation: Any = Undefined,
   (...)
    289     raise_on_unknown: bool = True,
    290 ) -> tuple[WidgetClass, dict]:
    291     """Return a [magicgui.widgets.Widget][] subclass for the given `value`/`annotation`.
    292 
    293     Parameters
   (...)
    312         may be different than the options passed in.
    313     """
--> 314     widget_type, _options = _pick_widget_type(
        value = {}
        annotation = typing.Any
        options = {'tooltip': 'Parameters for the resize function when downsampling images.'}
        is_result = False
        raise_on_unknown = True
    315         value, annotation, options, is_result, raise_on_unknown
    316     )
    318     if isinstance(widget_type, str):
    319         widget_class = _import_wdg_class(widget_type)

File ~/.pyenv/versions/miniforge3-4.14.0-2/envs/napari-basicpy/lib/python3.10/site-packages/magicgui/type_map/_type_map.py:262, in _pick_widget_type(value={}, annotation=typing.Any, options={'nullable': False, 'tooltip': 'Parameters for the resize function when downsampling images.'}, is_result=False, raise_on_unknown=True)
    259     return _cls, {**options, **opts}
    261 if raise_on_unknown:
--> 262     raise ValueError(
        annotation = typing.Any
        _type = typing.Any
    263         f"No widget found for type {_type} and annotation {annotation!r}"
    264     )
    266 return widgets.EmptyWidget, {"visible": False}

ValueError: No widget found for type typing.Any and annotation typing.Any
yfukai commented 1 year ago

The problem was because of Callable annotation in the autosegment field. Should be solved once https://github.com/peng-lab/BaSiCPy/pull/130 is merged and released.