Correctly infer x: SomeEnum; x.name as union of literal names#18797
Correctly infer x: SomeEnum; x.name as union of literal names#18797
x: SomeEnum; x.name as union of literal names#18797Conversation
for more information, see https://pre-commit.ci
This comment has been minimized.
This comment has been minimized.
Hi! I am working on mypy in python/mypy#18797 And I've noticed a small thing in your code. Ideally, `SomeEnum.Item.name` should be inferenced as `Literal[NAME_ONE, NAME_TWO, ...]` But, since you later modify `status` (which is the name of a enum item), it should be explicitly annotated as `str`, not `Literal`.
|
I opened psycopg/psycopg#1023 to fix a "problem" is psycopg. |
This comment has been minimized.
This comment has been minimized.
|
Should this also handle unions of literals? I notice if you narrow with |
|
@TeamSpen210 please, share your examples, I would be happy to support them as well :) |
|
Here's an example of both: class SomeEnum(Enum):
A = 0
B = 1
C = 2
class AnotherEnum(Enum):
ONE = 1
TWO = 2
THREE = 3
def func(value: SomeEnum, combo: SomeEnum | Literal[AnotherEnum.ONE, AnotherEnum.THREE]):
reveal_type(value.name) # Literal["A", "B", "C"]
assert value is not SomeEnum.A
reveal_type(value.name) # Just str, but should be Literal["B", "C"]?
# also str, but could be Literal["A", "B", "C", "ONE", "THREE"]
reveal_type(combo.name)Second is a bit less likely, but seems reasonable to support? |
|
Ok, I see, supporting |
Currently enum names are strings, but this is being changed to become Literal. When this will happen, the type inferred will not be valid anymore, as we mutate it and manipulate it as string in the function. See python/mypy#18797
for more information, see https://pre-commit.ci
|
Done! |
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
Currently enum names are strings, but this is being changed to become Literal. When this will happen, the type inferred will not be valid anymore, as we mutate it and manipulate it as string in the function. See python/mypy#18797
|
@JukkaL friendly ping :) |
ilevkivskyi
left a comment
There was a problem hiding this comment.
LG, hopefully this will not cause any performance regressions, as this may create more large unions.
| ) | ||
| if enum_names: | ||
| str_type = ctx.api.named_generic_type("builtins.str", []) | ||
| return make_simplified_union( |
There was a problem hiding this comment.
I don't think we need to call make_simplified_union() here. Instead, make sure that _extract_enum_names_from_literal_union() deduplicates the strings, it should be much faster.
Closes #18786