You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Use union instead of join for unifying types #12056
I noticed that this was tried for the specific case of conditional expressions (type of x if y else z) in 532f3fb (issue #3487) but was partly reverted in 94309a1 because it "caused many problems in internal Dropbox repos that we aren't ready to fix yet.".
I agree that we should probably do this, but I also want to see the fallout first. Due to our backward compatibility policy, the change needs to be first introduced behind a feature flag, and we need a major mypy release when we switch the default (e.g. 2.0). This will let us iterate on the change and allow users to experiment with it easily before we make the switch.
Reacted by Jelle Zijlstra, Marc Mueller and buster-blue
Just to add my 50 cents here: I don't like the idea of completely switching to unions. The fact that this will fix 20 issues doesn't guarantee that we will not get 40 new issues caused by things like:
defbasket() ->set[Fruit]:
res= {Banana(), Apple(), Orange()}
# do something with res...returnres
I think a better (and probably safer) approach is: we should infer unions in "heterogeneous" contexts, while keeping joins in "homogeneous" contexts. By "heterogeneous" contexts I mean things like tuple types, ternary expressions, user declared unions, star arguments (which are also tuples under the hood), maybe there are some more. Note that a significant amount of issues mentioned above are about these cases. We can try switching these cases one by one, and see what is the fallout.
My prediction is that fallout from switching tuple fallback to union will be minimal (in particular since tuple instance is covariant), we can start with this.
Reacted by Sune Debel, Shantanu and Stanislav Terliakov
@ilevkivskyi In my experience, we haven't seen any issues with this functionality in basedmypy. You even get a very useful message in the example you provided:
classFruit: ...
classApple(Fruit): ...
classOrange(Fruit): ...
classBanana(Fruit): ...
deff() ->set[Fruit]:
result= {Apple(), Orange(), Banana()}
returnresult# test.py:26: error: Incompatible return value type (got "set[Apple | Orange | Banana]", expected "set[Fruit]") [return-value]# test.py:26: note: Perhaps you need a type annotation for "a"? Suggestion: "set[Fruit]"
Just some opinions from the basedmypy team is that TypeScript always performs a unionization here as well.
Reacted by Stanislav Terliakov
Reacted by Mike Perlov, Samuel de Framond, Matthew Hoffman, Sune Debel, Jack McIvor and Siddhartha Gandhi
because I'm curious -- is there any trick to adjust mypy's inference to resolve to the union that's shorter than enumerating all the types?
classBase: passclassA(Base): passclassB(Base): passclassC(Base): passx= [A, B, C] # implicitly `list[type[Base]]`y: list[type[A|B|C]] = [A, B, C] # works but is a little cumbersome as the number increases
@ilevkivskyi what's the best way to express support for the union behavior? Also, judging by your phrasing, may I assume that mypy may get the "union way" under as an opt-in sooner rather than later?
Activity
A5rocks commentedon Jan 24, 2022
How will this interact with TypeForm vs Type?Does this meanjoin(A,B)will still be accepted forType[T]?Union[A, B]is not.Nevermind: I was being confused. This doesn't matter I believe. (TypeForm is more about passing a type in, not about the type of an object)
bluetech commentedon Jan 25, 2022
I noticed that this was tried for the specific case of conditional expressions (type of
x if y else z) in 532f3fb (issue #3487) but was partly reverted in 94309a1 because it "caused many problems in internal Dropbox repos that we aren't ready to fix yet.".Always infer union types for ternaries
KotlinIsland commentedon May 9, 2023
Basedmypy uses union. We have seen great success with it. (we also form intersections at meets)
JukkaL commentedon May 10, 2023
I agree that we should probably do this, but I also want to see the fallout first. Due to our backward compatibility policy, the change needs to be first introduced behind a feature flag, and we need a major mypy release when we switch the default (e.g. 2.0). This will let us iterate on the change and allow users to experiment with it easily before we make the switch.
ilevkivskyi commentedon Aug 26, 2023
Just to add my 50 cents here: I don't like the idea of completely switching to unions. The fact that this will fix 20 issues doesn't guarantee that we will not get 40 new issues caused by things like:
I think a better (and probably safer) approach is: we should infer unions in "heterogeneous" contexts, while keeping joins in "homogeneous" contexts. By "heterogeneous" contexts I mean things like tuple types, ternary expressions, user declared unions, star arguments (which are also tuples under the hood), maybe there are some more. Note that a significant amount of issues mentioned above are about these cases. We can try switching these cases one by one, and see what is the fallout.
My prediction is that fallout from switching tuple fallback to union will be minimal (in particular since tuple instance is covariant), we can start with this.
KotlinIsland commentedon Aug 27, 2023
@ilevkivskyi In my experience, we haven't seen any issues with this functionality in basedmypy. You even get a very useful message in the example you provided:
Just some opinions from the basedmypy team is that TypeScript always performs a unionization here as well.
Mypy: add workaround for wrong type in ternary
Use (simplified) unions instead of joins for tuple fallbacks (#17408)
Infer unions for ternary expressions (#17427)
asottile-sentry commentedon Jul 3, 2024
because I'm curious -- is there any trick to adjust mypy's inference to resolve to the union that's shorter than enumerating all the types?
ilevkivskyi commentedon Jul 3, 2024
I am actually going to add a flag so that people can opt in if they want more unions (the default however is unlikely to change in next few years).
mishamsk commentedon Jul 3, 2024
@ilevkivskyi what's the best way to express support for the union behavior? Also, judging by your phrasing, may I assume that mypy may get the "union way" under as an opt-in sooner rather than later?