-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ty] Filter overloads based on Any / Unknown
#18607
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
|
e2b0c19 to
7693df9
Compare
7693df9 to
e77e099
Compare
## Summary This is to support #18607. This PR adds support for generating the top materialization (or upper bound materialization) and the bottom materialization (or lower bound materialization) of a type. This is the most general and the most specific form of the type which is fully static, respectively. More concretely, `T'`, the top materialization of `T`, is the type `T` with all occurrences of dynamic type (`Any`, `Unknown`, `@Todo`) replaced as follows: - In covariant position, it's replaced with `object` - In contravariant position, it's replaced with `Never` - In invariant position, it's replaced with an unresolved type variable (For an invariant position, it should actually be replaced with an existential type, but this is not currently representable in our type system, so we use an unresolved type variable for now instead.) The bottom materialization is implemented in the same way, except we start out in "contravariant" position. ## Test Plan Add test cases for various types.
ba64697 to
c5e01dc
Compare
47bd939 to
689ca40
Compare
Any / UnknownAny / Unknown
|
Fixed this. |
689ca40 to
06b2e88
Compare
carljm
left a comment
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.
Nice!
|
|
||
| # `Any` matches both overloads, but the return types are not equivalent. | ||
| # Pyright and mypy both reveals `str` here. | ||
| reveal_type(f(any)) # revealed: Any |
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.
To be honest, I think we should reveal str here also, even though that's not what the spec says. Perhaps the spec should be changed. It feels like str is just a strictly superior result here.
If the return types don't have a subtype relation, then unioning will create lots of false positives (and break the gradual guarantee), since callers would be forced to handle both possibilities (a OneOf connective would be ideal here.) But when the possible return types do have a subtype relation, there are no false positives created by just returning the wider type.
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.
I'll create a new tracking issue for this, I think it is a reasonable change but would be also useful to get it into the spec as well.
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.
Opened: astral-sh/ty#665
| from overloaded import f | ||
|
|
||
| def _(list_int: list[int], list_any: list[Any], any: Any): | ||
| reveal_type(f(list_int)) # revealed: A |
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.
Can we also show that passing e.g. list[str] returns str, just to clarify the handling of the generic second overload?
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.
Huh, it's actually giving me Any instead, let me look at it.
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.
This is giving me false:
from ty_extensions import static_assert, is_assignable_to
from typing import TypeVar
T = TypeVar("T")
# False
static_assert(is_assignable_to(list[str], list[T]))Shouldn't this be assignable?
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.
Opened astral-sh/ty#669 for now.
|
Ecosystem analysis: Accessing a member of the dictionary when the default is def _(d: dict[str, str], default):
# revealed: Unknown (should be str | None)
reveal_type(d.get("hello", default))I think most of the overloaded function calls are now returning There are multiple instances where it's due to missing features so the argument type would be |
Summary
Closes: astral-sh/ty#552
This PR adds support for step 5 of the overload call evaluation algorithm which specifies:
The algorithm works in two parts:
For step 1, the participating parameter indexes are computed by just comparing whether all the parameter types at the corresponding index for all the overloads are gradual equivalent.
The step 2 of the algorithm used is described in this comment.
Test Plan
Update the overload call tests.