Skip to content

Commit b642756

Browse files
[ty] Add support for functional Enum(...) syntax (#23602)
## Summary astral-sh/ty#876 https://typing.python.org/en/latest/spec/enums.html#enum-definition this pr implements the functional syntax for creating enums: `Enum('Color2', 'RED, GREEN, BLUE')` it mostly copies the `namedtuple` implementation it supports the `start=` and `type=` kwargs for `Enum` as well ([docs](https://docs.python.org/3/library/enum.html#enum.EnumType.__call__)) it also supports `Flag` and `IntFlag` the `ddtrace` diffs look to be correct - `IntEnum` call is now properly recognized ### for non-string-literal `name` arguments, it falls back to just returning `type[Enum]` - this came up by way of a psycopg regression on this [line](https://github.com/psycopg/psycopg/blob/eb87f0eb58ee05b7202b7d8835b925b084d32b5c/psycopg/psycopg/types/enum.py#L173) - wasn't sure if this was better or worse than returning a `DynamicEnumLiteral` with an unknown name and members. this now looks correct for psycopg: `+ psycopg/psycopg/types/enum.py:173:12 [error] [invalid-return-type] Return type does not match returned value: expected `Enum`, found `type[Enum]`` however, it appears mypy does not correctly support the functional API (i am wondering if this is why the psycopg typing is the way it is), or maybe when just returning the result of the `Enum` call (without assigning it to a name), it always assumes its looking up a member: ```python from enum import Enum, EnumType from typing import reveal_type def make_color_1() -> EnumType: return Enum("Color1", names="RED GREEN") def make_color_2() -> EnumType: return Enum("Color2", names=("RED", "GREEN")) reveal_type(make_color_1()) reveal_type(make_color_2()) ``` ```bash # mypy output main.py:6: error: Incompatible return value type (got "Enum", expected "EnumMeta") [return-value] main.py:10: error: Incompatible return value type (got "Enum", expected "EnumMeta") [return-value] main.py:13: note: Revealed type is "enum.EnumMeta" main.py:14: note: Revealed type is "enum.EnumMeta" Found 2 errors in 1 file (checked 1 source file) # runtime output Runtime type is 'EnumType' Runtime type is 'EnumType' ``` ## Test Plan mdtests --------- Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
1 parent 9e3bd44 commit b642756

16 files changed

Lines changed: 2038 additions & 110 deletions

File tree

crates/ty_python_semantic/resources/mdtest/annotations/literal.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ def f():
3939
reveal_type(a7) # revealed: None
4040
reveal_type(a8) # revealed: Literal[1]
4141
reveal_type(b1) # revealed: Literal[Color.RED]
42-
# TODO should be `Literal[MissingT.MISSING]`
43-
reveal_type(b2) # revealed: @Todo(functional `Enum` syntax)
42+
reveal_type(b2) # revealed: MissingT
4443

4544
# error: [invalid-type-form]
4645
invalid1: Literal[3 + 4]

crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,16 +1936,16 @@ from enum import Enum
19361936

19371937
E = Enum("E", "A B C")
19381938

1939-
# TODO: should emit `invalid-dataclass`
1939+
# error: [invalid-dataclass] "Cannot use `dataclass()` on an enum class"
19401940
dataclass(E)
19411941

1942-
# TODO: should emit `invalid-dataclass`
1942+
# error: [invalid-dataclass] "Cannot use `dataclass()` on an enum class"
19431943
dataclass()(E)
19441944

1945-
# TODO: should emit `invalid-dataclass`
1945+
# error: [invalid-dataclass] "Cannot use `dataclass()` on an enum class"
19461946
dataclass(Enum("Inline1", "X Y"))
19471947

1948-
# TODO: should emit `invalid-dataclass`
1948+
# error: [invalid-dataclass] "Cannot use `dataclass()` on an enum class"
19491949
dataclass()(Enum("Inline2", "X Y"))
19501950
```
19511951

0 commit comments

Comments
 (0)