[ty] Delay computation of 'unbound' visibility for implicit instance attributes#18669
Merged
[ty] Delay computation of 'unbound' visibility for implicit instance attributes#18669
Conversation
Contributor
Author
|
We should probably also add a regression test/benchmark. I can look into that next week, in a follow-up, in case we want to merge this sooner. |
Contributor
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Consider the following example, which leads to a excessively large runtime on
main. The reason for this is the following. When inferring types forself.a, we look up theaattribute onC. While looking for implicit instance attributes, we go through every method and check forself.a = …assignments. There are no such assignments here, but we always have an implicitself.a = <unbound>binding at the beginning over every method. This binding accumulates a complex visibility constraint inC.f, due to theisinstancechecks. While evaluating that constraint, we need to infer the type ofself.b. There's no binding forself.beither, but there's also an implicitself.b = <unbound>binding with the same complex visibility constraint (involvingself.brecursively). This leads to a combinatorial explosion:(note that the
selfparameter here is annotated explicitly because we currently still inferUnknownforselfotherwise)The fix proposed here is rather simple: when there are no
self.name = …attribute assignments in a given method, we skip evaluating the visibility constraint of the implicitself.name = <unbound>binding. This should also generally help with performance, because that's a very common case.This is not a fix for cases where there are actual bindings in the method. When we add
self.a = 1; self.b = 1to that example above, we still see that combinatorial explosion of runtime. I still think it's worth to make this optimization, as it fixes the problems withpandasandsqlalchemyreported by users. I will open a ticket to track that separately.closes astral-sh/ty#627
closes astral-sh/ty#641
Test Plan
tyfinishes quickly on the MREs in Freeze when checking project ty#627tyfinishes quickly onpandastyfinishes quickly onsqlalchemy