Open Dakkaron opened 7 years ago
This is not a bug. In stub files, the names that are imported for re-export (i.e. actually imported in runtime .py
file, not just to annotate functions and variables in stub) must use the import name as name
pattern. Please read the corresponding section https://www.python.org/dev/peps/pep-0484/#stub-files
This was not caught by previous versions of mypy, but now it conforms to PEP 484 in this aspect. If you are curious about the motivation, then consider this:
# file lib.pyi
from typing import List
from lib.inner import SomeClass
def func(arg: List[SomeClass]) -> None: ...
# file main.py
from lib import List # this will obviously fail at runtime, but was not caught by mypy previously
from lib import SomeClass # this will also fail if SomeClass is not actually imported in mod.py
# in this case the stub should use from lib.inner import SomeClass as SomeClass
I understand the reasoning and the new way of doing things is good. But I think the error message is still misleading. Especially when migrating from mypy 0.520 or older to mypy 0.530 it can be very confusing that stuff that worked fine before does not work anymore. There should be a special error message to handle this case.
Fair enough, the error message could be better. Reopening (with a new title).
By the way, how to deal with stuff like that when using *-imports?
from X import *
I guess, it is not possible to write from X import * as *
. Is it now mandatory to convert all that into explicit imports? I know, *-imports are often not seen as good practice, but a lot of libraries still use them.
from x import *
is implicitly exported in a stub, so no * as *
is needed. Actually, you should only use from x import *
in a stub if you want to export everything in x
; otherwise you must use explicit imports.
From https://www.python.org/dev/peps/pep-0484/#stub-files:
Additional notes on stub files:
- Modules and variables imported into the stub are not considered exported from the stub unless the import uses the
import ... as ...
form or the equivalentfrom ... import ... as ...
form.- *However, as an exception to the previous bullet, all objects imported into a stub using `from ... import ` are considered exported. (This makes it easier to re-export all objects from a given module that may vary by Python version.)**
(Highlight by me)
That's good to know, thank you!
Indirect imports in stubs don't seem to work. I tested the following case against mypy 0.520, where everything worked (no error detected), mypy 0.530 (where the error occurred) and the current git version, which also had the same error as mypy 0.530.
I attached a zip file with the test case: testcase.zip
The mypy call line is just
mypy --config-file=mypy.ini -p testcase
.The error I get is the following:
The main problem is the first line. Module
'b'
imports'TestClass'
fromb.stubB
inb.__init__.pyi
, but mypy for some reason does not know that.