Skip to content

Commit 5b40295

Browse files
committed
[ty] Enums: allow multiple aliases to point to the same member
1 parent 963bc8c commit 5b40295

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

crates/ty_python_semantic/resources/mdtest/enums.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,41 @@ reveal_type(enum_members(Color))
265265
reveal_type(Color.red)
266266
```
267267

268+
Multiple aliases to the same member are also supported. This is a regression test for
269+
<https://github.com/astral-sh/ty/issues/1293>:
270+
271+
```py
272+
from ty_extensions import enum_members
273+
274+
class ManyAliases(Enum):
275+
real_member = "real_member"
276+
alias1 = "real_member"
277+
alias2 = "real_member"
278+
alias3 = "real_member"
279+
280+
other_member = "other_real_member"
281+
282+
# revealed: tuple[Literal["real_member"], Literal["other_member"]]
283+
reveal_type(enum_members(ManyAliases))
284+
285+
reveal_type(ManyAliases.real_member) # revealed: Literal[ManyAliases.real_member]
286+
reveal_type(ManyAliases.alias1) # revealed: Literal[ManyAliases.real_member]
287+
reveal_type(ManyAliases.alias2) # revealed: Literal[ManyAliases.real_member]
288+
reveal_type(ManyAliases.alias3) # revealed: Literal[ManyAliases.real_member]
289+
290+
reveal_type(ManyAliases.real_member.value) # revealed: Literal["real_member"]
291+
reveal_type(ManyAliases.real_member.name) # revealed: Literal["real_member"]
292+
293+
reveal_type(ManyAliases.alias1.value) # revealed: Literal["real_member"]
294+
reveal_type(ManyAliases.alias1.name) # revealed: Literal["real_member"]
295+
296+
reveal_type(ManyAliases.alias2.value) # revealed: Literal["real_member"]
297+
reveal_type(ManyAliases.alias2.name) # revealed: Literal["real_member"]
298+
299+
reveal_type(ManyAliases.alias3.value) # revealed: Literal["real_member"]
300+
reveal_type(ManyAliases.alias3.name) # revealed: Literal["real_member"]
301+
```
302+
268303
### Using `auto()`
269304

270305
```toml

crates/ty_python_semantic/src/types/enums.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,14 @@ pub(crate) fn enum_metadata<'db>(
196196
value_ty,
197197
Type::IntLiteral(_) | Type::StringLiteral(_) | Type::BytesLiteral(_)
198198
) {
199-
if let Some(previous) = enum_values.insert(value_ty, name.clone()) {
200-
aliases.insert(name.clone(), previous);
199+
if let Some(canonical) = enum_values.get(&value_ty) {
200+
// This is a duplicate value, create an alias to the canonical (first) member
201+
aliases.insert(name.clone(), canonical.clone());
201202
return None;
202203
}
204+
205+
// This is the first occurrence of this value, track it as the canonical member
206+
enum_values.insert(value_ty, name.clone());
203207
}
204208

205209
let declarations = use_def_map.end_of_scope_symbol_declarations(symbol_id);

0 commit comments

Comments
 (0)