Repository: napari/napari

Issue:
running `napari` results in No module named 'napari' (pyenv, 3.8.6)
## 🐛 Bug

Calling `napari` after a fresh installation of napari (0.4.17) in a fresh environment yields the error `No module named 'napari'`.

## To Reproduce

Steps to reproduce the behavior:

1. Purge pip cache: `pip cache purge`
2. Set up new environment: `pyenv virtualenv 3.8.6 napari`
3. Activate environment: `pyenv activate napari`
4. Install napari: `pip install "napari[all]"`
5. Open napari: `napari`
6. Error occurs:
```
Traceback (most recent call last):
  File "/Users/schidani/.pyenv/versions/napari/bin/napari", line 5, in <module>
    from napari.__main__ import main
ModuleNotFoundError: No module named 'napari'
```

## Expected behavior

Napari starts up.

## Environment

 - OS: `macOS Monterey 12.6`
 - python: `3.8.6`
 - pyenv: `2.2.2`
 - pip: `22.3.1`
 - napari: `0.4.17`
 - napari-console: `0.0.7`
 - napari-plugin-engine: `0.2.0`
 - napari-svg: `0.1.6`

## Additional information

Following the same installation steps as above but exchanging Step 4 with `pip install "napari[all]==0.4.16"` installs a version of napari that I can open from console.

Let me know if you require further information.

Thank you,
Daniel



Discussion:
is there `napari` directory in your working directory?

Could you paste the output of `ls /Users/schidani/.pyenv/versions/napari/lib/python3.9/site-packages`?
there is no `napari` directory in my working directory (and the issue occurred in multiple CWDs).

Here the requested output (I changed the environment name to "test"):
```
(test) schidani@bs-mbpr396:~$ ls /Users/schidani/.pyenv/versions/test/lib/python3.8/site-packages/
Babel-2.11.0.dist-info/                              certifi/                                             imagesize.py                                         napari_svg-0.1.6.dist-info/                          ptyprocess-0.7.0.dist-info/                          sphinxcontrib_jsmath-1.0.1.dist-info/
HeapDict-1.0.1.dist-info/                            certifi-2022.12.7.dist-info/                         importlib_metadata/                                  nest_asyncio-1.5.6.dist-info/                        pure_eval/                                           sphinxcontrib_qthelp-1.0.3-py3.8-nspkg.pth
IPython/                                             charset_normalizer/                                  importlib_metadata-6.0.0.dist-info/                  nest_asyncio.py                                      pure_eval-0.2.2.dist-info/                           sphinxcontrib_qthelp-1.0.3.dist-info/
Jinja2-3.1.2.dist-info/                              charset_normalizer-2.1.1.dist-info/                  importlib_resources/                                 networkx/                                            pvectorc.cpython-38-darwin.so*                       sphinxcontrib_serializinghtml-1.1.5-py3.9-nspkg.pth
MarkupSafe-2.1.1.dist-info/                          click/                                               importlib_resources-5.10.2.dist-info/                networkx-2.8.8.dist-info/                            pydantic/                                            sphinxcontrib_serializinghtml-1.1.5.dist-info/
OpenGL/                                              click-8.1.3.dist-info/                               in_n_out/                                            npe2/                                                pydantic-1.10.4.dist-info/                           stack_data/
PIL/                                                 cloudpickle/                                         in_n_out-0.1.6.dist-info/                            npe2-0.6.1.dist-info/                                pygments/                                            stack_data-0.6.2.dist-info/
Pillow-9.4.0.dist-info/                              cloudpickle-2.2.0.dist-info/                         ipykernel/                                           numpy/                                               pyrsistent/                                          superqt/
Pint-0.20.1.dist-info/                               comm/                                                ipykernel-6.19.4.dist-info/                          numpy-1.24.1.dist-info/                              pyrsistent-0.19.3.dist-info/                         superqt-0.4.1.dist-info/
PyOpenGL-3.1.6.dist-info/                            comm-0.1.2.dist-info/                                ipykernel_launcher.py                                numpydoc/                                            python_dateutil-2.8.2.dist-info/                     tifffile/
PyQt5/                                               commonmark/                                          ipython-8.8.0.dist-info/                             numpydoc-1.5.0.dist-info/                            pytomlpp/                                            tifffile-2022.10.10.dist-info/
PyQt5-5.15.7.dist-info/                              commonmark-0.9.1.dist-info/                          ipython_genutils/                                    packaging/                                           pytomlpp-1.0.11.dist-info/                           tlz/
PyQt5_Qt5-5.15.2.dist-info/                          dask/                                                ipython_genutils-0.2.0.dist-info/                    packaging-22.0.dist-info/                            pytz/                                                tomli/
PyQt5_sip-12.11.0.dist-info/                         dask-2022.12.1.dist-info/                            jedi/                                                pandas/                                              pytz-2022.7.dist-info/                               tomli-2.0.1.dist-info/
PyWavelets-1.4.1.dist-info/                          dateutil/                                            jedi-0.18.2.dist-info/                               pandas-1.5.2.dist-info/                              pywt/                                                toolz/
PyYAML-6.0.dist-info/                                debugpy/                                             jinja2/                                              parso/                                               pyzmq-24.0.1.dist-info/                              toolz-0.12.0.dist-info/
Pygments-2.14.0.dist-info/                           debugpy-1.6.4.dist-info/                             jsonschema/                                          parso-0.8.3.dist-info/                               qtconsole/                                           tornado/
QtPy-2.3.0.dist-info/                                decorator-5.1.1.dist-info/                           jsonschema-4.17.3.dist-info/                         partd/                                               qtconsole-5.4.0.dist-info/                           tornado-6.2.dist-info/
Sphinx-4.5.0.dist-info/                              decorator.py                                         jupyter.py                                           partd-1.3.0.dist-info/                               qtpy/                                                tqdm/
__pycache__/                                         doc/                                                 jupyter_client/                                      pep517/                                              requests/                                            tqdm-4.64.1.dist-info/
_pyrsistent_version.py                               docstring_parser/                                    jupyter_client-7.4.8.dist-info/                      pep517-0.13.0.dist-info/                             requests-2.28.1.dist-info/                           traitlets/
_yaml/                                               docstring_parser-0.15.dist-info/                     jupyter_core/                                        pexpect/                                             rich/                                                traitlets-5.8.0.dist-info/
alabaster/                                           docutils/                                            jupyter_core-5.1.2.dist-info/                        pexpect-4.8.0.dist-info/                             rich-13.0.0.dist-info/                               typer/
alabaster-0.7.12.dist-info/                          docutils-0.17.1.dist-info/                           kiwisolver/                                          pickleshare-0.7.5.dist-info/                         scikit_image-0.19.3.dist-info/                       typer-0.7.0.dist-info/
app_model/                                           easy_install.py                                      kiwisolver-1.4.4.dist-info/                          pickleshare.py                                       scipy/                                               typing_extensions-4.4.0.dist-info/
app_model-0.1.1.dist-info/                           entrypoints-0.4.dist-info/                           locket/                                              pint/                                                scipy-1.10.0.dist-info/                              typing_extensions.py
appdirs-1.4.4.dist-info/                             entrypoints.py                                       locket-1.0.0.dist-info/                              pip/                                                 setuptools/                                          urllib3/
appdirs.py                                           executing/                                           magicgui/                                            pip-22.3.1.dist-info/                                setuptools-49.2.1.dist-info/                         urllib3-1.26.13.dist-info/
appnope/                                             executing-1.2.0.dist-info/                           magicgui-0.6.1.dist-info/                            pkg_resources/                                       six-1.16.0.dist-info/                                vispy/
appnope-0.1.3.dist-info/                             freetype/                                            markupsafe/                                          pkgutil_resolve_name-1.3.10.dist-info/               six.py                                               vispy-0.11.0.dist-info/
asttokens/                                           freetype_py-2.3.0.dist-info/                         matplotlib_inline/                                   pkgutil_resolve_name.py                              skimage/                                             wcwidth/
asttokens-2.2.1.dist-info/                           fsspec/                                              matplotlib_inline-0.1.6.dist-info/                   platformdirs/                                        snowballstemmer/                                     wcwidth-0.2.5.dist-info/
attr/                                                fsspec-2022.11.0.dist-info/                          mypy_extensions-0.4.3.dist-info/                     platformdirs-2.6.2.dist-info/                        snowballstemmer-2.2.0.dist-info/                     wrapt/
attrs/                                               heapdict.py                                          mypy_extensions.py                                   pooch/                                               sphinx/                                              wrapt-1.14.1.dist-info/
attrs-22.2.0.dist-info/                              hsluv-5.0.3.dist-info/                               napari/                                              pooch-1.6.0.dist-info/                               sphinxcontrib/                                       yaml/
babel/                                               hsluv.py                                             napari-0.4.17.dist-info/                             prompt_toolkit/                                      sphinxcontrib_applehelp-1.0.2-py3.8-nspkg.pth        zipp/
backcall/                                            idna/                                                napari_builtins/                                     prompt_toolkit-3.0.36.dist-info/                     sphinxcontrib_applehelp-1.0.2.dist-info/             zipp-3.11.0.dist-info/
backcall-0.2.0.dist-info/                            idna-3.4.dist-info/                                  napari_console/                                      psutil/                                              sphinxcontrib_devhelp-1.0.2-py3.8-nspkg.pth          zmq/
build/                                               imageio/                                             napari_console-0.0.7.dist-info/                      psutil-5.9.4.dist-info/                              sphinxcontrib_devhelp-1.0.2.dist-info/
build-0.9.0.dist-info/                               imageio-2.23.0.dist-info/                            napari_plugin_engine/                                psygnal/                                             sphinxcontrib_htmlhelp-2.0.0-py3.9-nspkg.pth
cachey/                                              imagesize/                                           napari_plugin_engine-0.2.0.dist-info/                psygnal-0.7.0.dist-info/                             sphinxcontrib_htmlhelp-2.0.0.dist-info/
cachey-0.2.1.dist-info/                              imagesize-1.4.1.dist-info/                           napari_svg/                                          ptyprocess/                                          sphinxcontrib_jsmath-1.0.1-py3.7-nspkg.pth
```


Hmm, 3.8.6 is pretty old—do you need this specific version?
I can't reproduce with 3.8.15 and can't get everything installed on 3.8.6 because of pyqt (I'm on arm64 though).

BTW, does it work if you try to first launch `ipython` and then:
```
import napari
viewer = napari.Viewer()
```
For compatibility reasons I would like to stick to 3.8.6 for now.

> BTW, does it work if you try to first launch ipython and then:
>
>```
>import napari
>viewer = napari.Viewer()
>```

yes, this works.
I have installed python 3.8.6 (from pyenv) and cannot reproduce the behavior. 

What shows?
`ls /Users/schidani/.pyenv/versions/napari/lib/python3.9/site-packages/napari`

You have outdated pyenv. May you update it? 
I upgraded to `pyenv==2.3.9` and the issue persists. I also tested a fresh environment with `python==3.8.15` and have the same issue (call from `ipython` still works).

This is the requested output:
```
(basic) schidani@bs-mbpr396:~$ ls /Users/schidani/.pyenv/versions/test/lib/python3.8/site-packages/napari
__init__.py      __main__.py      _app_model/      _lazy.py         _tests/          _version.py      components/      errors/          layers/          qt/              settings/        utils/           view_layers.pyi  window.py
__init__.pyi     __pycache__/     _event_loop.py   _qt/             _vendor/         _vispy/          conftest.py      experimental/    plugins/         resources/       types.py         view_layers.py   viewer.py
```
This smells similar to: https://github.com/napari/napari/pull/5007
Can you try: `python -m napari`

```
(test) schidani@bs-mbpr396:~/Desktop/PhD$ python -m napari
/var/folders/55/7bw8sfdn7y77cpmy24mqx5jr0000gr/T/symlink-to-fix-macos-menu-name-vatzpapg/napari: No module named napari
```
Here's something to try, also paging @jaimergp who may have some more insight based on his work with #5007 
>Export _NAPARI_RERUN_WITH_FIXES=1 and then run napari
>Same but try python -m napari
I'd like to see:

1. The shebang in `/Users/schidani/.pyenv/versions/napari/bin/napari`
2. The output of `env | sort | grep PYTHON`
3. The output of `echo $PATH` (redact if needed)
> Here's something to try, also paging @jaimergp who may have some more insight based on his work with https://github.com/napari/napari/pull/5007
>```
>Export _NAPARI_RERUN_WITH_FIXES=1 and then run napari
>Same but try python -m napari
>```

If I use `export _NAPARI_RERUN_WITH_FIXES=1` running `napari` and `python -m napari` both work!


> 1. The shebang in `/Users/schidani/.pyenv/versions/napari/bin/napari`

`#!/Users/schidani/.pyenv/versions/3.8.6/envs/test/bin/python3.8`

> 2. The output of `env | sort | grep PYTHON`

there is no environment variable that contains `PYTHON`

> 3. The output of `echo $PATH` (redact if needed)

```
(test) schidani@bs-mbpr396:~/Desktop/PhD$ echo $PATH
/usr/local/Cellar/pyenv-virtualenv/1.1.5/shims:/Users/schidani/.pyenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Users/schidani/nvim-osx64/bin/:/Users/schidani/.local/bin
```
It might be finding a `python` under `/usr/local/Cellar/pyenv-virtualenv/1.1.5/shims`? What do you get for `where python`?
`where python` does not work on my system, but `which python`/`whereis python` work:

```
(test) schidani@bs-mbpr396:~/Desktop$ which python
/Users/schidani/.pyenv/shims/python
(test) schidani@bs-mbpr396:~/Desktop$ whereis python
python: /Users/schidani/.pyenv/shims/python
```
Can you resolve that path? It might be a symlink to somewhere else. I think the command is `realpath`? 
for pyenv use `pyenv which python` to show where currently `/Users/schidani/.pyenv/shims/python` leads. 
This is the output:
```
(test) schidani@bs-mbpr396:~/Desktop/PhD$ pyenv which python
/Users/schidani/.pyenv/versions/test/bin/python
```
Is that the same one as in the shebang of `napari`? It does say `test` but not the `3.8.6` parts.
The shebang links to:
```
/Users/schidani/.pyenv/versions/3.8.6/envs/test/bin/python3.8
```

`/Users/schidani/.pyenv/versions/test` is a link to:
```
/Users/schidani/.pyenv/versions/test@ -> /Users/schidani/.pyenv/versions/3.8.6/envs/test
```
so `/Users/schidani/.pyenv/versions/test/bin/python` is equivalent to `/Users/schidani/.pyenv/versions/3.8.6/envs/test/bin/python`

so regarding the question if `python` and `python3.8` link to the same version:
```
schidani@bs-mbpr396:~/.pyenv/versions/3.8.6/envs/test/bin$ ls -l python*
lrwxr-xr-x  1 schidani  staff     9B Jan  5 13:31 python@ -> python3.8
lrwxr-xr-x  1 schidani  staff     9B Jan  5 13:31 python3@ -> python3.8
lrwxr-xr-x  1 schidani  staff    51B Jan  5 13:31 python3.8@ -> /Users/schidani/.pyenv/versions/3.8.6/bin/python3.8
```
Yea that sounds correct. What I don't get is why a different executable is being chosen, but I am getting an idea.

Can you run this line for the `python` you are mentioning above?

```
python -c "import sys; print(f'{sys.executable=:}', f'{sys.prefix=:}', f'{sys.exec_prefix=:}', f'{sys.base_prefix=:}', sep='\n')"
```

I suspect the value for `exec_prefix` is different than what we would expect (same "root" as the pyenv `python`), and that it ships a `pythonw` binary that points to a different Python installation. 

The problematic logic lies in this function, if you want to try adding some `print`s here and there:
 https://github.com/napari/napari/blob/ada5d1c88b3ecfa1500c0c77ecaff5d32ed35a3e/napari/__main__.py#L428
> Can you run this line for the python you are mentioning above?

```
(test) schidani@bs-mbpr396:~/Desktop/PhD$ python -c "import sys; print(f'{sys.executable=:}', f'{sys.prefix=:}', f'{sys.exec_prefix=:}', f'{sys.base_prefix=:}', sep='\n')"
sys.executable=/Users/schidani/.pyenv/versions/test/bin/python
sys.prefix=/Users/schidani/.pyenv/versions/test
sys.exec_prefix=/Users/schidani/.pyenv/versions/test
sys.base_prefix=/Users/schidani/.pyenv/versions/3.8.6
```

Ill have a look at https://github.com/napari/napari/blob/ada5d1c88b3ecfa1500c0c77ecaff5d32ed35a3e/napari/__main__.py#L428

and get back at you later. Thank you.
I just ran into this as well and think I have a fix. @dsethz can you try this patch? If it works for you too I will make a PR:

```patch
diff --git a/napari/__main__.py b/napari/__main__.py
index 334628123..110002fbd 100644
--- a/napari/__main__.py
+++ b/napari/__main__.py
@@ -537,6 +537,10 @@ def _maybe_rerun_with_macos_fixes():
         else:  # we assume it must have been launched via '-m' syntax
             cmd = [executable, "-m", "napari"]
 
+        # this fixes issues running from a venv/virtualenv based virtual
+        # environment with certain python distributions (e.g. pyenv)
+        env["PYTHONEXECUTABLE"] = sys.executable
+
         # Append original command line arguments.
         if len(sys.argv) > 1:
             cmd.extend(sys.argv[1:])
```
Sorry for the late reply... 

I tested @aganders3 fix and it works 👍 
I will close the issue and thanks for all your help!
Good to hear @dsethz ! 
But I'm going to re-open this until we have a merged PR that solves this for everyone!

Resolving patch:
diff --git a/napari/__main__.py b/napari/__main__.py
--- a/napari/__main__.py
+++ b/napari/__main__.py
@@ -537,6 +537,10 @@ def _maybe_rerun_with_macos_fixes():
         else:  # we assume it must have been launched via '-m' syntax
             cmd = [executable, "-m", "napari"]
 
+        # this fixes issues running from a venv/virtualenv based virtual
+        # environment with certain python distributions (e.g. pyenv, asdf)
+        env["PYTHONEXECUTABLE"] = sys.executable
+
         # Append original command line arguments.
         if len(sys.argv) > 1:
             cmd.extend(sys.argv[1:])


Test patch: