[ty] Distribute type[] over unions#22115
Conversation
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
82bcc21 to
3bccb24
Compare
| let subclass_types: Option<Vec<_>> = union | ||
| .elements(db) | ||
| .iter() | ||
| .map(|element| Self::try_from_instance(db, *element)) | ||
| .collect(); | ||
| return subclass_types.map(|types| UnionType::from_elements(db, types)); |
There was a problem hiding this comment.
I think you can use UnionType::try_from_elements() to avoid having to .collect() into a Vec before you union the types together
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
type-assertion-failure |
2 | 0 | 147 |
invalid-argument-type |
51 | 2 | 2 |
invalid-return-type |
2 | 1 | 7 |
unsupported-operator |
0 | 4 | 5 |
unused-ignore-comment |
0 | 5 | 0 |
possibly-missing-attribute |
4 | 0 | 0 |
| Total | 59 | 12 | 161 |
|
Hah, all the
X = 3.14
assert_type(X.__class__, type[float])and we're complaining that our inferred type for So I think this would be another use case for astral-sh/ty#1762 (comment), but nothing needs to be done in this PR about those diagnostics. |
|
Here's a minimal repro of the new artigraph diagnostic. It looks like a tricky missing case we don't yet handle when iterating over intersections! Seems like an unrelated def f[T: tuple[int, ...] | int](x: T):
if isinstance(x, tuple):
reveal_type(x)
for item in x:
reveal_type(item) # `object`, but should be `int`
|
|
I can take a look at those artigraph diagnostics. |
|
All the new |
|
Here's a minimal repro of the new hydypy diagnostic, which is a false positive: class Replace: ...
class Multiply: ...
def get_rule[TypeRule2: Replace | Multiply](type_: type[TypeRule2]):
type_.__name__ # error: [unresolved-attribute] "Object of type `type[TypeRule2@get_rule]` has no attribute `__name__`"It only repros if the TypeVar is bound to a union. But all I think the same thing is going on with the new |
|
The first pydantic diagnostic is a true positive that they already have a |
|
Even if their root causes turn out to be pre-existing issues, we might need to fix the hydypy and artigraph issues before landing this -- seems like they cause a bunch of false positives otherwise :/ |
I think this is a different issue from astral-sh/ty#1762 (comment). |
3bccb24 to
f62be39
Compare
|
(Looking into these @AlexWaygood.) |
@jorenham no, that's exactly backwards. We infer the type of This seems very analogous to astral-sh/ty#1762, since In order for the from ty_extensions import JustFloat, TypeOf
from typing import assert_type
X = 3.14
assert_type(X.__class__, type[JustFloat])
assert_type(X.__class__, type[TypeOf[3.14]]) |
Ah yea I see, that makes more sense that way 🙃. Sorry about the noise!
Haha that sounds a lot like |
|
The hydypy false-positives are fixed in #22116. |
AlexWaygood
left a comment
There was a problem hiding this comment.
It's a bit hard to analyze the ecosystem report because there's a bunch of false-positives being introduced (all the "object of type type[T] has no __name__ attribute" ones) that you have a fix for, but the fix is in a PR stacked on top of this one (#22116). So I would be tempted to merge that PR into this one as a standalone commit, just so that we can double-check that it does really fix all the false positives of that genre that this PR is currently introducing.
But having said that, this definitely makes sense to me as the correct way to fix this!
I haven't reviewed #22117 yet but I don't think it "blocks" this PR in the same way as #22116, because we only see one false positive of that genre in the ecosystem report here.
I can do that! Hopefully they both show up in the changelog, I can't remember how that works. |
…22116) ## Summary For `type[T]` where `T: Replace | Multiply`, we now do the following: - `try_from_instance(Replace | Multiply)` becomes `type[Replace] | type[Multiply]` - `to_meta_type(type[Replace] | type[Multiply])` becomes `type[type] | type[type]` which becomes `type[type]` See: #22115 (comment)
…ain non-iterable types (#22117) ## Summary When iterating over an intersection like `T & tuple[object, ...]` where `T` is a `TypeVar` bounded by `tuple[int, ...] | int`, the iteration was returning `object` instead of `int`. Now, when a `TypeVar` fails to iterate normally, we check if it has a union bound, then extract the iterable parts and use those for the result. See: #22115 (comment)
Summary
Closes astral-sh/ty#2121.