The following code creates a package structure that demonstrates what I think is a bug in mypy's new semantic analyzer.
from os import makedirs
makedirs('src/core')
makedirs('src/stuff')
open('src/__init__.py', 'w').write("""
# nothing here
""")
open('src/core/__init__.py', 'w').write("""
from .run import config
""")
open('src/core/run.py', 'w').write("""
from ..stuff import somefunction
config = None
somefunction()
""")
open('src/stuff/__init__.py', 'w').write("""
from .somemore import more
from .somefunction import somefunction
""")
open('src/stuff/somefunction.py', 'w').write("""
def somefunction():
print("Hello, World!")
""")
open('src/stuff/somemore.py', 'w').write("""
def more():
from ..core import config
""")
When checking the created src package with mypy 0.720 and Python 3.7, I get the following error:
src/core/run.py:6: error: Module not callable
What mypy thinks is a module is actually a function. It just has the same name as its containing module.
When I check with --no-new-semantic-analyzer, I do not get this error.
I confirm this. Also I was able to find a much simpler repro. Here is a test case:
[case testSubModuleVsFunction]
# cmd: mypy -m test stuff stuff.somefunction
[file test.py]
from stuff import somefunction
somefunction()
[file stuff/__init__.py]
import test
from stuff.somefunction import somefunction
[file stuff/somefunction.py]
def somefunction(): ...
[builtins fixtures/module.pyi]
cc @JukkaL
Note there is a similar issue modulo function -> class, see #7172:
[case testCycleRenames]
# flags: --new-semantic-analyzer
import MyX
[file MyX.py]
from inner import MyBase
class MyX:
x: MyBase = None
[file inner/__init__.py]
from inner.MyBase import MyBase as MyBase
[file inner/MyBase.py]
from MyX import MyX
class MyBase:
pass
[file inner/MyDerived1.py]
from inner.MyBase import MyBase
class MyDerived1(MyBase):
pass
Hi, is there any known workaround for this issue?
A possible workaround is to move the definition of the function to __init__.py, instead of importing it from a submodule.
pkg/__init__.py:
def submodule() -> int:
return 4
pkg/submodule.py:
# no definition of submodule() here
Alternatively, maybe you can define the function in both pkg/__init__.py and pkg/submodule.py. To avoid code duplication, both of them can just wrap a call to another function such as _submodule().
Does this help? The underlying issue may be hard to fix.
I ended up importing as
from package.Object import Object
instead of
from package import Object
Note that my specific case was classes, not functions, but I guess it's the same issue.
Most helpful comment
I confirm this. Also I was able to find a much simpler repro. Here is a test case: