Repository: napari/napari

Issue:
Starting a plugin dock widget from the commandline no longer works
## 🐛 Bug

Since the last commit https://github.com/napari/napari/commit/9ea0159ad2b690556fe56ce480886d8f0b79ffae starting a dock widget from the command line with the `-w` option no longer works on npe2 packages, readers work as expected.
Once the GUI is started without the `-w` flag, the dock widget works as before.
Non-npe2 plugins seem to work.

Since there were changes within the last days in the npe2 package, so could it be that the proper dependencies are just not yet available?

## To Reproduce

Steps to reproduce the behavior:

1. Fresh napari main branch installation ".[all]"
2. pip install napari-matplotlib
3. napari -w napari-matplotlib

```
Traceback (most recent call last):
  File "/opt/user_software/miniconda3_envs/napari_fresh/bin/napari", line 8, in <module>
    sys.exit(main())
  File "/opt/user_software/miniconda3_envs/napari_fresh/lib/python3.10/site-packages/napari/__main__.py", line 449, in main
    _run()
  File "/opt/user_software/miniconda3_envs/napari_fresh/lib/python3.10/site-packages/napari/__main__.py", line 283, in _run
    ) or plugin_manager.get_widget(pname)
  File "/opt/user_software/miniconda3_envs/napari_fresh/lib/python3.10/site-packages/napari/plugins/_plugin_manager.py", line 610, in get_widget
    raise KeyError(msg)
KeyError: "Plugin 'napari-matplotlib' does not provide any dock widgets"
```

## Expected behavior

The GUI opens with the matplotlib Histogram window open

![image](https://user-images.githubusercontent.com/18047816/184878237-fa26679b-89e5-4329-981d-55c0039ce7c1.png)


## Environment

Working:
```
napari: 0.4.16rc2.dev218+gb5413925
Platform: Linux-5.15.0-46-generic-x86_64-with-glibc2.31
System: Ubuntu 20.04.4 LTS
Python: 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:06:46) [GCC 10.3.0]
Qt: 5.15.2
PyQt5: 5.15.7
NumPy: 1.23.2
SciPy: 1.9.0
Dask: 2022.8.0
VisPy: 0.11.0

OpenGL:
- GL version: 4.6.0 NVIDIA 470.141.03
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 3840x2160, scale 1.0
- screen 2: resolution 1200x1920, scale 1.0
- screen 3: resolution 1920x1200, scale 1.0
```

Failing:

```
napari: 0.4.16rc2.dev219+g9ea0159a
Platform: Linux-5.15.0-46-generic-x86_64-with-glibc2.31
System: Ubuntu 20.04.4 LTS
Python: 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:06:46) [GCC 10.3.0]
Qt: 5.15.2
PyQt5: 5.15.7
NumPy: 1.23.2
SciPy: 1.9.0
Dask: 2022.8.0
VisPy: 0.11.0

OpenGL:
- GL version: 4.6.0 NVIDIA 470.141.03
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 3840x2160, scale 1.0
- screen 2: resolution 1200x1920, scale 1.0
- screen 3: resolution 1920x1200, scale 1.0
```

```
pip freeze | grep -e 'napari' -e npe
napari-console==0.0.4
napari-plugin-engine==0.2.0
napari-svg==0.1.6
npe2==0.6.1
```

Starting a plugin dock widget from the commandline no longer works
## 🐛 Bug

Since the last commit https://github.com/napari/napari/commit/9ea0159ad2b690556fe56ce480886d8f0b79ffae starting a dock widget from the command line with the `-w` option no longer works on npe2 packages, readers work as expected.
Once the GUI is started without the `-w` flag, the dock widget works as before.
Non-npe2 plugins seem to work.

Since there were changes within the last days in the npe2 package, so could it be that the proper dependencies are just not yet available?

## To Reproduce

Steps to reproduce the behavior:

1. Fresh napari main branch installation ".[all]"
2. pip install napari-matplotlib
3. napari -w napari-matplotlib

```
Traceback (most recent call last):
  File "/opt/user_software/miniconda3_envs/napari_fresh/bin/napari", line 8, in <module>
    sys.exit(main())
  File "/opt/user_software/miniconda3_envs/napari_fresh/lib/python3.10/site-packages/napari/__main__.py", line 449, in main
    _run()
  File "/opt/user_software/miniconda3_envs/napari_fresh/lib/python3.10/site-packages/napari/__main__.py", line 283, in _run
    ) or plugin_manager.get_widget(pname)
  File "/opt/user_software/miniconda3_envs/napari_fresh/lib/python3.10/site-packages/napari/plugins/_plugin_manager.py", line 610, in get_widget
    raise KeyError(msg)
KeyError: "Plugin 'napari-matplotlib' does not provide any dock widgets"
```

## Expected behavior

The GUI opens with the matplotlib Histogram window open

![image](https://user-images.githubusercontent.com/18047816/184878237-fa26679b-89e5-4329-981d-55c0039ce7c1.png)


## Environment

Working:
```
napari: 0.4.16rc2.dev218+gb5413925
Platform: Linux-5.15.0-46-generic-x86_64-with-glibc2.31
System: Ubuntu 20.04.4 LTS
Python: 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:06:46) [GCC 10.3.0]
Qt: 5.15.2
PyQt5: 5.15.7
NumPy: 1.23.2
SciPy: 1.9.0
Dask: 2022.8.0
VisPy: 0.11.0

OpenGL:
- GL version: 4.6.0 NVIDIA 470.141.03
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 3840x2160, scale 1.0
- screen 2: resolution 1200x1920, scale 1.0
- screen 3: resolution 1920x1200, scale 1.0
```

Failing:

```
napari: 0.4.16rc2.dev219+g9ea0159a
Platform: Linux-5.15.0-46-generic-x86_64-with-glibc2.31
System: Ubuntu 20.04.4 LTS
Python: 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:06:46) [GCC 10.3.0]
Qt: 5.15.2
PyQt5: 5.15.7
NumPy: 1.23.2
SciPy: 1.9.0
Dask: 2022.8.0
VisPy: 0.11.0

OpenGL:
- GL version: 4.6.0 NVIDIA 470.141.03
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 3840x2160, scale 1.0
- screen 2: resolution 1200x1920, scale 1.0
- screen 3: resolution 1920x1200, scale 1.0
```

```
pip freeze | grep -e 'napari' -e npe
napari-console==0.0.4
napari-plugin-engine==0.2.0
napari-svg==0.1.6
npe2==0.6.1
```



Discussion:
@mstabrin thanks for the report - will have a look into this today.
Ok so the reason this is happening is very helpfully documented [on the line that's causing it](https://github.com/napari/napari/pull/4847/files#diff-d5c7eaa497f40561af9dc89131f265676417b726c6eb454b11281e0cbe25c3f2R57-R58). 

As per that comment, in #4847 we decided to delay the entire plugin discovery until the creation of a `Viewer`, so there are no plugins discovered when we check whether the given plugin name provides widgets [here](https://github.com/napari/napari/blob/bf74cbc1266d6e04045f084c4c19a0991f7e362b/napari/__main__.py#L299).

@tlambert03 @nclack thoughts? I understand the general idea behind delaying the discovery, but if we want to maintain this sanity check for valid widgets, we need to initialize here. Alternatively we should just go back to initializing on module import. 
yep @DragaDoncila nailed it.  we need to add this to line ~268 in `__main__.py`:

```python
        if args.with_:
            from .plugins import _npe2, plugin_manager, _initialize_plugins

            _initialize_plugins()
```


**edit**

> Alternatively we should just go back to initializing on module import.

I think initializing here in main is best (initializing in the module itself was troublesome) ... alternatively, we could just move the whole `if args.with_:` below  `Viewer()` instantiation on line ~296 (since that will _also_ initialize plugins)
@mstabrin thanks for the report - will have a look into this today.
Ok so the reason this is happening is very helpfully documented [on the line that's causing it](https://github.com/napari/napari/pull/4847/files#diff-d5c7eaa497f40561af9dc89131f265676417b726c6eb454b11281e0cbe25c3f2R57-R58). 

As per that comment, in #4847 we decided to delay the entire plugin discovery until the creation of a `Viewer`, so there are no plugins discovered when we check whether the given plugin name provides widgets [here](https://github.com/napari/napari/blob/bf74cbc1266d6e04045f084c4c19a0991f7e362b/napari/__main__.py#L299).

@tlambert03 @nclack thoughts? I understand the general idea behind delaying the discovery, but if we want to maintain this sanity check for valid widgets, we need to initialize here. Alternatively we should just go back to initializing on module import. 
yep @DragaDoncila nailed it.  we need to add this to line ~268 in `__main__.py`:

```python
        if args.with_:
            from .plugins import _npe2, plugin_manager, _initialize_plugins

            _initialize_plugins()
```


**edit**

> Alternatively we should just go back to initializing on module import.

I think initializing here in main is best (initializing in the module itself was troublesome) ... alternatively, we could just move the whole `if args.with_:` below  `Viewer()` instantiation on line ~296 (since that will _also_ initialize plugins)

Resolving patch:
diff --git a/napari/__main__.py b/napari/__main__.py
--- a/napari/__main__.py
+++ b/napari/__main__.py
@@ -266,10 +266,11 @@ def _run():
 
     else:
         if args.with_:
-            from .plugins import _npe2, plugin_manager
+            from .plugins import _initialize_plugins, _npe2, plugin_manager
 
             # if a plugin widget has been requested, this will fail immediately
             # if the requested plugin/widget is not available.
+            _initialize_plugins()
             plugin_manager.discover_widgets()
             pname, *wnames = args.with_
             if wnames:


Test patch: