I have this file structure:
- package
- sub_package_1
- __init__.py
- sub_module_1.py
- sub_package_2
- __init__.py
- sub_module_2.py
In sub_module_1.py we have this code:
class A:
def __init__(self):
self.b = B()
def method_a(self, var: int):
pass
class B:
def __init__(self):
pass
def method_b(self, var: int):
pass
class C: # This class always located in different module, but for example lets place it here
def __init__(self):
self.a = A()
def method_c(self, var: int):
pass
a = A()
a.b.method_b() # here we have an argument warning (method_b is waiting for an argument)
c = C()
c.a.b.method_b() # and also here, the same warning
And in sub_module_2.py we have this code:
from package.sub_package_1.sub_module_1 import A
class C:
def __init__(self):
self.a = A()
def method_c(self, var: int):
pass
c = C()
c.a.b.method_b() # but here we don't have a warning
I've leaved some comments in code to show the problem.
When I work in the same module (or even in the same package), I can see all warnings, caused by methods' arguments. But if I move one of the classes outside the package (like I did with C class) I loose all warnings. I still can autocomplete lines, has typehinting etc, but I have no warnings in case I do not pass any argument in c.a.b.method_b().
I feel like this is an import issue, but I can't find the solution.
What is the reason of this behaviour and how can I fix it?
As written, the inferred type of
c.aisAny, which means you can do anything with it, andmypy(and likely other tools) will be happy. This includes assumingc.ahas an attributebwith a 0-argument methodmethod_b.This is because you haven't provided any annotations for various
__init__functions, which makesmypyessentially ignore them and anything they produce.Provide explicit return types of
Nonefor the__init__methods, and you should get the expected error even across import boundaries.