You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Circular import + reexport = "error: Module '...' has no attribute '..."? #4049
This is a minimal test case replicating what I'm experiencing in a larger project:
% tree
.
└── asd
├── __init__.py
├── one.py
└── two.py
2 directories, 6 files
% cat asd/__init__.py
from asd.one import One
from asd.two import Two
% cat asd/one.py
class One:
pass
% cat asd/two.py
from asd import One
class Two:
pass
I see the same error on master. There are few other issues related to import cycles. Maybe we can process situation like this or #3277 in the third pass (similar to forward references). @JukkaL what do you think?
Yes, creating some sort of forward references for imported names seems like a potential way to fix this. Another thing that might work is improving the processing order of modules within cycles.
We should also make sure that any fix will also work in fine-grained incremental checking.
tests/test_database_service.py:22: error: Module has no attribute "db"
for code like:
defsetUp(self) ->None:
# ...frombrowse.servicesimportdatabaseself.database_service=database#self.database_service.db.init_app(mock_app) #accessing db here causes the error
Edit: I found the discussion on forward references ... so I should look into that next.
@JukkaL After looking into it more, I now realize you probably meant that forward references might provide a fix internally to mypy - I couldn't see how to use them myself to avoid the error I mentioned above. Is there currently a workaround?
@bbarker Yes, I was talking how we could fix this in mypy internally. Your workaround should work, if you access the attribute directly and not through a "module alias":
from browse.services.database import db
db.init_app(...)
You seem to be assigning a module to an instance attribute, which isn't supported right now (#4291).
We're running into this problem at Instagram, too. It's a high priority for us since it's causing type errors we can't easily work around, so I'm looking into it. It seems like we already have a sort of internal "forward reference" for imported names, in the form of node.kind == UNBOUND_IMPORTED. In the problematic cases, we are visiting an import in semantic analysis pass 2 where the name we are importing is still of kind UNBOUND_IMPORTED in the module we are importing it from. Looking into whether we can just let UNBOUND_IMPORTED propagate in pass 2 (instead of immediately erroring) and then resolve it in pass 3.
(It's hard to workaround in our case because the error is raised in generated code, and the code generator has no way to tell whether this particular module will be involved in an import cycle, so it doesn't know whether to generate a # type: ignore comment on the import line; and we consider unused # type: ignore to be an error, too.)
Activity
ilevkivskyi commentedon Oct 3, 2017
I see the same error on master. There are few other issues related to import cycles. Maybe we can process situation like this or #3277 in the third pass (similar to forward references). @JukkaL what do you think?
JukkaL commentedon Oct 3, 2017
Yes, creating some sort of forward references for imported names seems like a potential way to fix this. Another thing that might work is improving the processing order of modules within cycles.
We should also make sure that any fix will also work in fine-grained incremental checking.
bbarker commentedon Nov 20, 2017
Is there a workaround? I tried doing something like the following in
database/__init__.py:However, in my test code I still get errors like:
for code like:
Edit: I found the discussion on forward references ... so I should look into that next.
bbarker commentedon Nov 28, 2017
@JukkaL After looking into it more, I now realize you probably meant that forward references might provide a fix internally to mypy - I couldn't see how to use them myself to avoid the error I mentioned above. Is there currently a workaround?
JukkaL commentedon Nov 29, 2017
@bbarker Yes, I was talking how we could fix this in mypy internally. Your workaround should work, if you access the attribute directly and not through a "module alias":
You seem to be assigning a module to an instance attribute, which isn't supported right now (#4291).
Drop types for this for now
carljm commentedon Jan 20, 2018
We're running into this problem at Instagram, too. It's a high priority for us since it's causing type errors we can't easily work around, so I'm looking into it. It seems like we already have a sort of internal "forward reference" for imported names, in the form of
node.kind == UNBOUND_IMPORTED. In the problematic cases, we are visiting an import in semantic analysis pass 2 where the name we are importing is still of kindUNBOUND_IMPORTEDin the module we are importing it from. Looking into whether we can just letUNBOUND_IMPORTEDpropagate in pass 2 (instead of immediately erroring) and then resolve it in pass 3.(It's hard to workaround in our case because the error is raised in generated code, and the code generator has no way to tell whether this particular module will be involved in an import cycle, so it doesn't know whether to generate a
# type: ignorecomment on the import line; and we consider unused# type: ignoreto be an error, too.)Don't error on re-exported imports in cycles. Fixes python#4049.
Fix issues related to indirect imports in import cycles (#4695)
Fix issues related to indirect imports in import cycles (python#4695)
initiating work on strict typing, need sqlalchemy-stubs
initiating work on strict typing, need sqlalchemy-stubs