-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Don't consider indirect dependencies when calculating SCCs #19903
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
Conversation
SCC construction should only consider import dependencies, since indirect dependencies are not available during non-incremental runs. I think otherwise SCCs can be different in non-incremental vs incremtal runs. Attempt to fix an issue with excessively large SCCs computed (sometimes) after #19798 when doing incremental runs. I haven't been able to create a self-contained test case that reproduces the issue, but this appears to fix this issue with an internal codebase.
|
||
def sorted_components( | ||
graph: Graph, vertices: AbstractSet[str] | None = None, pri_max: int = PRI_ALL | ||
graph: Graph, vertices: AbstractSet[str] | None = None, pri_max: int = PRI_INDIRECT |
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.
The name pri_max
is a bit confusing -- dependencies with a priority less than this are considered. I don't want to change this logic at this point, since it would require larger changes as this function is used in a few different places.
I don't think this is possible unless there is a bug somewhere. Indirect dependencies should never create a cycle (and vice versa). So although the PR is technically correct (we don't need indirect dependencies to identify SCCs), I think we should investigate this deeper, otherwise this will bite us later anyway. |
Diff from mypy_primer, showing the effect of this PR on open source code: AutoSplit (https://github.com/Toufool/AutoSplit)
- File "/tmp/mypy_primer/mypy_old/venv/bin/mypy", line 7, in <module>
+ File "/tmp/mypy_primer/mypy_new/venv/bin/mypy", line 7, in <module>
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/__main__.py", line 15, in console_entry
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/__main__.py", line 15, in console_entry
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/main.py", line 127, in main
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/main.py", line 127, in main
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/main.py", line 211, in run_build
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/main.py", line 211, in run_build
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/build.py", line 196, in build
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/build.py", line 196, in build
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/build.py", line 272, in _build
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/build.py", line 272, in _build
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/build.py", line 2946, in dispatch
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/build.py", line 2946, in dispatch
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/build.py", line 3346, in process_graph
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/build.py", line 3346, in process_graph
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/build.py", line 3475, in process_stale_scc
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/build.py", line 3475, in process_stale_scc
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/build.py", line 2493, in write_cache
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/build.py", line 2493, in write_cache
- File "/tmp/mypy_primer/mypy_old/venv/lib/python3.13/site-packages/mypy/cache.py", line 28, in __init__
+ File "/tmp/mypy_primer/mypy_new/venv/lib/python3.13/site-packages/mypy/cache.py", line 28, in __init__
|
FWIW I am suspecting this logic
in
there, similar to what we have in |
Yes, I agree the this only works around a deeper underlying issue. That code in |
I suspect that if there is a local variable that has the same name as a top-level module, mypy may generate a spurious indirect dependency to this module. I'll try to come up with a self-contained reproducer. Maybe references to local definitions should be filtered out in |
FWIW I think I see a potential way to make the logic there a bit more robust, it seems to me we should be able to simply:
I will try to make a PR later today. |
#19906 stops generating indirect deps for locals, and it also has a test case. |
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.
Let's merge both PRs, as this one also has its value (at least as a niche performance optimization).
Don't generate an indirect dependency to module `bar` if a local variable has name `bar`. This aims to fix the root cause of the issue #19903 tries to solve.
SCC construction should only consider import dependencies, since indirect dependencies are not available during non-incremental runs. I think otherwise SCCs can be different in non-incremental vs incremtal runs.
Attempt to fix an issue with excessively large SCCs computed (sometimes) after #19798 when doing incremental runs. I haven't been able to create a self-contained test case that reproduces the issue, but this appears to fix this issue with an internal codebase.