-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Examples gallery fails on case insensitive/case preserving systems when napari installed as editable #214
Comments
@aganders3 if you can fix Also we can open an issue over at Sphinx Gallery, and offer possible solutions, Eric will probably be a good judge of what changes would be appropriate in Sphinx Gallery. |
I don't have super strong feelings, but I'd still favor a small change in sphinx-gallery. The issue here comes from the case-insensitive imports (and that is probably more common), but consider this package structure:
To be clear this is pretty clearly bad practice, but please humor me. This is what importing from that package does:
I played around (probably too much) with the backreferences code in sphinx-gallery trying to clean up after these imports, but cleaning up Since the examples are run in the same process, I think my current best idea is to only import modules that are already imported when looking at backreferences. This is super simple and safer (I confirmed it prevents the issue that spawned this discussion) at the cost of being slightly less aggressive at finding shorter names for backreferences. A patch would look something like this: def _from_import(a, b):
+ if a not in sys.modules:
+ raise ImportError(f"not importing {a}, as it was not previously imported")
imp_line = f'from {a} import {b}'
scope = dict()
with warnings.catch_warnings(record=True): # swallow warnings I'd be happy to discuss this on an issue or PR at sphinx-gallery. |
I think we can definitely raise an issue in sphinx gallery - and I think Eric will be much better placed to judge. I am not sure we want to raise an error as this would cause a lot of existing users builds to fail. I also don't want to change behaviour (for existing builds), especially as I am not sure how common this problem is. We could add (yet another) config that will allow users to optionally only import if previously imported. I am always conscious of adding to our extensive config but Eric may feel differently! |
Ah yeah to be clear that fn is already called in a try/except that catches all errors so that change shouldn't actually break builds. The specific exception it raises doesn't really matter. I'm also typically anti new configs but will defer to the maintainers on that 😄. |
It's hard to know how much the behaviour change would affect users, but probably safer to be able to opt out... (But I think this is a very good solution!) |
Thanks! And yeah I'm not familiar enough with the actual use of the feature to have an instinct for it, haha. Maybe I'll find some example projects that use it and do a diff w/ and w/o this change. |
Feel free to just open an issue, most sphinx-gallery contributors are not half as thorough as you! |
This gives some background on why it looks for short modules: sphinx-gallery/sphinx-gallery#947 (comment) |
Now the fix in Sphinx Gallery and setuptools is in, I think we can close this. @aganders3 feel free to re-open if you wish. |
🐛 Bug
This problem has been discussed in #209 (comment) and #207 (comment) (and following comments).
@aganders3 has been doing all the investigation, just combining information so it's all in one place and so there is a place to discuss this issue.
On case-preserving but case-insensitive filesytem (e.g., macOS) when napari is installed in editable mode, examples gallery will fail.
With scraper added in #207, following error is seen:
Similar
napari.viewer
/napari.Viewer
(module/class) confusion has been noted before, notably when executing examplecustom_key_bindings.py
which uses the fixture:@napari.Viewer.bind_key('w')
(more details here).This is due to combination of:
_get_short_module_name
, for background on why it does this: Specify Target ofreference_url
sphinx-gallery/sphinx-gallery#947 (comment)), and this can leave new imports in sys.modules.Together these create our problem in the docs build. Here are the steps to failure:
custom_key_bindings.py
(maybe others) accessnapari.Viewer.bind_key()
from napari.Viewer import bind_key
napari.Viewer
is now insys.modules
and points tonapari/viewer.py
, this part of the import succeeds due to the setuptools issue with case-sensitivitynapari.Viewer
is accessed, it bypasses the getattr lazy-loading innapari/__init__.py
and instead gives back the module napari.viewer (with the wrong capitalized name). This can happen in the scraper where it accessesnapari.Viewer.close_all()
, or in the next example that usesnapari.Viewer()
.We could fix this in Sphinx-Gallery by avoiding importing - @aganders3 suggested to use
importlib.util
'sfind_spec
/module_from_spec
/exec_module
, but this only avoids one layer of side-effects asexec_module
will mean anything imported inside the module is still imported. I think this fix will at least our error though. Importing in a subprocess will be safest but is slow see: #209 (comment)Cleaning up
sys.modules
was also explored but there are potential problems if all references are not cleaned up and we have different module objects existing at the same time (details here).We could also fix this if
setuptools
avoids case-insensitive imports.Thanks to @aganders3 for all the work on this issue 🙏 If there are any inaccuracies, please let me know and I can amend it (as I don't think you can)!
The text was updated successfully, but these errors were encountered: