Open
Description
EDIT: MWE
from typing import Literal
foo = 0
bar: tuple[Literal[1], ...] = (1,)[foo:] # error: Incompatible types in assignment (expression has type "tuple[int, ...]", variable has type "tuple[Literal[1], ...]") [assignment]
baz: tuple[Literal[1], ...] = (1,)[0:] # OK
bar_fix: tuple[Literal[1], ...] = (1,) # In two steps...
bar_fix = bar_fix[foo:] # ...works fine
Original message
Hi there,
As always, I'm not sure whether I should post on mypy
or python typing
page. The problem I encounter is the following.
aligns: tuple[Literal["center", "right"], ...] = ("center", "right", "center")[no_extra:]
error: Incompatible types in assignment (expression has type "tuple[str, ...]", variable has type "tuple[Literal['center', 'right'], ...]") [assignment]
aligns: tuple[Literal["center", "right"], ...] = ("center", "right", "center")[no_extra:]
where no_extra
is a bool
. Essentially, I either keep or not the first element with my_tuple[no_extra:]
, and this makes it into a tuple[str, ...]
.
Is it normal? If so, is there a recommended practice around it, or should this be a new feature?
Thanks in advance!
All the best.
Élie
Metadata
Metadata
Assignees
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
ego-thales commentedon May 26, 2025
Just for info, I circumvent this by proceeding in two steps:
It would still be nice to have the possibility to proceed directly.
A5rocks commentedon May 26, 2025
I don't see why this isn't possible, unless we are using a heuristic on whether to use type context here (in which case this is just a sad consequence of that).
ego-thales commentedon May 27, 2025
I don't understand what you mean. I'm not sure whether you are saying that it's a possible feature to implement or saying that this should not raise the error. Just to be sure, I provide this MWE:
sterliakov commentedon May 28, 2025
This is trivially fixable, but I suspect this was intentionally not supported to prevent horror like this:
...which is exactly what happens if we decide to retain literal values in tuples, and is bad enough IMO to not fix this corner case.
If anyone has better ideas that retain literals only to some extent, here's what I did to receive that giant union:
A5rocks commentedon May 28, 2025
Maybe return the type context (
self.type_context[-1]
) ifleft_type
is a subtype? (or ifunion
is a subtype?)ego-thales commentedon May 28, 2025
Thanks for the details, it's interesting for me as
mypy
noob. I'm not sure this makes sense, but couldn't the behaviour be different between typed and nontyped statements?What I mean is that your example indeed provides ugly revealed type, but maybe it should not unless the assignment explicitly types with Literals? Again, I'm not sure I'm making sense here.