spaCy
spaCy copied to clipboard
[mypy] Module "spacy" does not explicitly export attribute "prefer_gpu" when using --no-implicit-reexport
First of all, thank you for maintaining a well type annotated library. It's a joy to use!
This bug is a minor issue when using spacy with mypy --no-implicit-reexport
. I do not know if you care about --no-implicit-reexport
, so feel free to ignore if you don't.
Brief explanation of the switch (in case): mypy's --no-implicit-reexport allows modules to be more specific about what in its namespace is part of the public API. Using it, by default, a module doing from foo import X
does not, for type checking purposes, export the symbol X
to importing modules, i.e. the import is assumed to be private by default. I believe the canonical way to explicitly reexport an imported symbol is the slightly funny looking from thinc.api import prefer_gpu as prefer_gpu
.
How to reproduce the behaviour
- Install mypy 1.8.0
- Create a file
bug.py
with the contents
import spacy
spacy.prefer_gpu()
- run
mypy --strict --no-implicit-reexport bug.py
Expected outcome:
There are no errors from mypy.
Actual outcome:
mypy reports
bug.py:3: error: Module "spacy" does not explicitly export attribute "prefer_gpu" [attr-defined]
Info about spaCy
- spaCy version: 3.7.2
- Platform: Linux-6.2.0-1018-lowlatency-x86_64-with-glibc2.37
- Python version: 3.11.4
- mypy version: 1.8.0
Thanks for the detailed report and the kind words! 😊
So but if I understand correctly, basically to make this work with --no-implicit-reexport
there would be a bunch of these imports that we'd have to rewrite to the more verbose version? (not just prefer_gpu
)
Hmm, that's probably true, although so far I haven't really run into many such errors, for reasons that I do not 100% understand. Maybe there's not that many of these reexports in spacy, or maybe I always have imported directly the module where it's defined?
Here's the mypy documentation:
--no-implicit-reexport
By default, imported values to a module are treated as exported and mypy allows other modules to import them. This flag changes the behavior to not re-export unless the item is imported using from-as or is included in all. Note this is always treated as enabled for stub files. For example:
# This won't re-export the value
from foo import bar
# Neither will this
from foo import bar as bang
# This will re-export it as bar and allow other modules to import it
from foo import bar as bar
# This will also re-export bar
from foo import bar
__all__ = ['bar']