-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Traverse module ancestors when traversing reachable graph nodes during dmypy update #18906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Traverse module ancestors when traversing reachable graph nodes during dmypy update #18906
Conversation
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is a right thing to do. Few comments:
- This design is quite counter-intuitive, it took me a while to scroll down to the very bottom of
fine_grained_increment_follow_imports()
where problem happens. Could you please add a comment at the point whereseen
set is first created there, explaining that it will be updated by various method calls to mark modules that are still reachable by following imports (and after all delete the rest). Also please update the docstrings of two methods that do modifyseen
(right now those docstrings are actively misleading, it looks like the only point of modifyingseen
is to avoid infinite loops during traversal). - To help you create a self-contained test, this assert is usually hit when the same file is processed twice under different module ids. For example after kicking out an
a/__init__.py
, a filea/b.py
can be assigned a module idb
, while before it appeared asa.b
. But please don't spend more than few hours on this. It is OK to merge without a test, if it is too hard to write. - I am quite sure this will fix dmypy: INTERNAL ERROR: AssertionError in _add_error_info() #15486 as well (that also appears on unmodified re-run with
--follow-imports=normal
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sterliakov for your debugging and for the fix!
This seems correct to me as well. Only one other thing I would check is if new_files
is correct as well. (though I would guess it is correct from your testing)
If writing a unit test is hard, maybe an integration test is easier. Those are in test-data/unit/daemon.test. See the other tests in there for the format. testDaemonQuickstart is an example of a test that changes files and runs dmypy multiple times.
Okay, I think the test is possible to write, thank you for suggestions! So far I know that the following is enough to repro:
(consistently crashes on the third run) Now I only need to figure out what's so special about |
Oh, awesome that you narrowed it down to just 1 import! While it might be good to have a test, since that makes it clear how the bug happened, I also think we can merge this as is without a test, and the test in a separate PR, if it's taking you a lot of time. I don't believe this change would make things worse. |
Okay, may I write an awkward, slow test depending on stdlib stub? The following crashes on master and passes with my patch:
If yes, I'll be back in ~4 h and submit all these changes:) |
@sterliakov I think this is fine. |
… xml.etree.ElementTree is so special
Looks like it is, I think this should be ready for another review round! |
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
heroes |
@sterliakov is the hero, he found and fixed the bug! :) Thanks again! |
Fixes #18396. Fixes #17652. Hopefully fixes #15486 (but not enough info to reproduce the original problem).
See discussion in #18396. This PR forces collecting all ancestors of all modules during dep graph traversal in incremental update.
Ancestors are included in
load_graph
, which means not traversing them during update results in some modules being erroneously treated as deleted:mypy/mypy/build.py
Lines 3141 to 3146 in a4e79ea