In contrast to the python REPL, ipython, VS Code, Jupyter, etc. the napari-console doesn't allow local modules/functions to be imported.
The sys.path in the napari-console does not include "" in sys.path, which is what permits searching of imports from the current dir.
See: https://docs.python.org/3/library/sys.html#sys.path
As a result launching napari from a dir does not permit easy importing of local modules.
Because of the inconsistency with other python tools and the fact that the console so strongly mimics those tools, I consider this a bug. (After some growing pains with the napari-console now I'm a big fan, especially for easy single-window hacking, as well as for demos/screensharing.)
Have a folder, e.g. dev or python_stuffs and a subfolder napari_scripts (or any other such)
Launch napari from terminal in dev or whatever.
Open console and try to import from a script/module in napari_scripts: from napari_scripts.napari_measure import measure_shape
Result:
ModuleNotFoundError: No module named 'napari_scripts'
The broader import from napari_scripts import napari_measure results in the same error, also it doesn't matter if the sub-dir napari_scripts has __init__.py or not.
(FYI if napari is launched directly from the subdirectory with the scripts, they still cannot be imported.)
Edit: to make matters more confusing for the end user, pwd() works correctly and shows the dir. Also, to further blur the lines between ipython and napari-console: they share a history.
Expected behavior
Both of the above imports work in any of the above mentioned python consoles (regardless of __init__.py). As a result, I would expect the import to work in napari-console and my local functions to be available.
Additional Context
The issue with possible local imports, as @Czaki pointed out is that a user with a local file like tensorflow.py will prevent a napari plugin that uses tensorflow from working.
I tested this by making such a file with just a test function that prints a string.
In live napari, stardist-napari (the tensorflow test plugin) works just fine.
If one uses:
import sys; sys.path.insert(0, "") to add "" to the top of sys.path my local imports work, but launching the Stardist plugin an error results, fairly clearly identifying the issue:
ImportError: cannot import name '__version__' from 'tensorflow' (/Users/piotrsobolewski/Dev/python_stuffs/tensorflow.py)
If one uses instead: import sys; sys.path.append('')
then again the local imports work, just like in ipython, et al (which have "" in sys.path at the bottom).
Importantly, Stardist plugin still works despite the "malicious/ignorant" tensorflow.py
So the key is to put "" after all the other search dirs (e.g. conda env ones).
ipython uses a init_path function that does this on start setting sys.path[0]=""
PS: Not sure if this should be here or napari-console repo?
š Bug
In contrast to the python REPL,
ipython
, VS Code, Jupyter, etc. the napari-console doesn't allow local modules/functions to be imported. Thesys.path
in the napari-console does not include "" in sys.path, which is what permits searching of imports from the current dir. See: https://docs.python.org/3/library/sys.html#sys.pathAs a result launching napari from a dir does not permit easy importing of local modules. Because of the inconsistency with other python tools and the fact that the console so strongly mimics those tools, I consider this a bug. (After some growing pains with the napari-console now I'm a big fan, especially for easy single-window hacking, as well as for demos/screensharing.)
However, as the discussion here on zulip with @Czaki points out, it could be considered a feature: https://napari.zulipchat.com/#narrow/stream/212875-general/topic/napari.20console.20vs.20ipython.3A.20importing.20local.20modules By blocking local imports, the end user can't mask important "real" modules needed by plugins.
To Reproduce
Steps to reproduce the behavior:
dev
orpython_stuffs
and a subfoldernapari_scripts
(or any other such)dev
or whatever.napari_scripts
:from napari_scripts.napari_measure import measure_shape
Result:
The broader import
from napari_scripts import napari_measure
results in the same error, also it doesn't matter if the sub-dirnapari_scripts
has__init__.py
or not.(FYI if napari is launched directly from the subdirectory with the scripts, they still cannot be imported.)
Edit: to make matters more confusing for the end user,
pwd()
works correctly and shows the dir. Also, to further blur the lines between ipython and napari-console: they share a history.Expected behavior
Both of the above imports work in any of the above mentioned python consoles (regardless of
__init__.py
). As a result, I would expect the import to work in napari-console and my local functions to be available.Additional Context
The issue with possible local imports, as @Czaki pointed out is that a user with a local file like tensorflow.py will prevent a napari plugin that uses tensorflow from working.
I tested this by making such a file with just a test function that prints a string. In live napari, stardist-napari (the tensorflow test plugin) works just fine. If one uses:
import sys; sys.path.insert(0, "")
to add "" to the top of sys.path my local imports work, but launching the Stardist plugin an error results, fairly clearly identifying the issue:If one uses instead:
import sys; sys.path.append('')
then again the local imports work, just like in ipython, et al (which have "" in sys.path at the bottom). Importantly, Stardist plugin still works despite the "malicious/ignorant" tensorflow.pySo the key is to put "" after all the other search dirs (e.g. conda env ones). ipython uses a
init_path
function that does this on start settingsys.path[0]=""
PS: Not sure if this should be here or
napari-console
repo?Environment
napari: 0.4.16rc2.dev17+g0c148bb6 Platform: macOS-12.3.1-arm64-arm-64bit System: MacOS 12.3.1 Python: 3.9.12 | packaged by conda-forge | (main, Mar 24 2022, 23:25:14) [Clang 12.0.1 ] Qt: 5.15.2 PyQt5: 5.15.4 NumPy: 1.21.5 SciPy: 1.8.0 Dask: 2022.02.0 VisPy: 0.10.0
OpenGL:
Screens:
Plugins: