spaCy icon indicating copy to clipboard operation
spaCy copied to clipboard

[mypy] Module "spacy" does not explicitly export attribute "prefer_gpu" when using --no-implicit-reexport

Open sliedes opened this issue 5 months ago • 2 comments

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

  1. Install mypy 1.8.0
  2. Create a file bug.py with the contents
import spacy

spacy.prefer_gpu()
  1. 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

sliedes avatar Jan 18 '24 15:01 sliedes

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)

svlandeg avatar Jan 18 '24 16:01 svlandeg

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']

sliedes avatar Jan 18 '24 17:01 sliedes