File tree Expand file tree Collapse file tree 3 files changed +51
-5
lines changed
crates/ty_python_semantic Expand file tree Collapse file tree 3 files changed +51
-5
lines changed Original file line number Diff line number Diff line change @@ -285,6 +285,11 @@ reveal_type(enum_members(Answer))
285285
286286reveal_type(Answer.YES .value) # revealed: Literal[1]
287287reveal_type(Answer.NO .value) # revealed: Literal[2]
288+
289+ class SingleMember (Enum ):
290+ SINGLE = auto()
291+
292+ reveal_type(SingleMember.SINGLE .value) # revealed: Literal[1]
288293```
289294
290295Usages of ` auto() ` can be combined with manual value assignments:
@@ -313,6 +318,11 @@ class Answer(StrEnum):
313318
314319reveal_type(Answer.YES .value) # revealed: Literal["yes"]
315320reveal_type(Answer.NO .value) # revealed: Literal["no"]
321+
322+ class SingleMember (StrEnum ):
323+ SINGLE = auto()
324+
325+ reveal_type(SingleMember.SINGLE .value) # revealed: Literal["single"]
316326```
317327
318328Using ` auto() ` with ` IntEnum ` also works as expected:
@@ -328,6 +338,24 @@ reveal_type(Answer.YES.value) # revealed: Literal[1]
328338reveal_type(Answer.NO .value) # revealed: Literal[2]
329339```
330340
341+ Using ` auto() ` with non-integer mixins:
342+
343+ ``` python
344+ from enum import Enum, auto
345+
346+ class A (str , Enum ):
347+ X = auto()
348+ Y = auto()
349+
350+ reveal_type(A.X.value) # revealed: str
351+
352+ class B (bytes , Enum ):
353+ X = auto()
354+ Y = auto()
355+
356+ reveal_type(B.X.value) # revealed: bytes
357+ ```
358+
331359Combining aliases with ` auto() ` :
332360
333361``` py
Original file line number Diff line number Diff line change @@ -3592,6 +3592,16 @@ impl<'db> Type<'db> {
35923592 . into ( )
35933593 }
35943594
3595+ Type :: NominalInstance ( instance)
3596+ if matches ! ( name_str, "value" | "_value_" )
3597+ && is_single_member_enum ( db, instance. class ( db) . class_literal ( db) . 0 ) =>
3598+ {
3599+ enum_metadata ( db, instance. class ( db) . class_literal ( db) . 0 )
3600+ . and_then ( |metadata| metadata. members . get_index ( 0 ) . map ( |( _, v) | * v) )
3601+ . map_or ( Place :: Unbound , Place :: bound)
3602+ . into ( )
3603+ }
3604+
35953605 Type :: NominalInstance ( ..)
35963606 | Type :: ProtocolInstance ( ..)
35973607 | Type :: BooleanLiteral ( ..)
Original file line number Diff line number Diff line change @@ -77,9 +77,6 @@ pub(crate) fn enum_metadata<'db>(
7777 return None ;
7878 }
7979
80- let is_str_enum =
81- Type :: ClassLiteral ( class) . is_subtype_of ( db, KnownClass :: StrEnum . to_subclass_of ( db) ) ;
82-
8380 let scope_id = class. body_scope ( db) ;
8481 let use_def_map = use_def_map ( db, scope_id) ;
8582 let table = place_table ( db, scope_id) ;
@@ -150,14 +147,25 @@ pub(crate) fn enum_metadata<'db>(
150147 // enum.auto
151148 Some ( KnownClass :: Auto ) => {
152149 auto_counter += 1 ;
153- Some ( if is_str_enum {
150+ let auto_value_ty = if ( Type :: ClassLiteral ( class)
151+ . is_subtype_of ( db, KnownClass :: StrEnum . to_subclass_of ( db) ) )
152+ {
154153 Type :: StringLiteral ( StringLiteralType :: new (
155154 db,
156155 name. to_lowercase ( ) . as_str ( ) ,
157156 ) )
157+ } else if ( Type :: ClassLiteral ( class)
158+ . is_subtype_of ( db, KnownClass :: Str . to_subclass_of ( db) ) )
159+ {
160+ KnownClass :: Str . to_instance ( db)
161+ } else if ( Type :: ClassLiteral ( class)
162+ . is_subtype_of ( db, KnownClass :: Bytes . to_subclass_of ( db) ) )
163+ {
164+ KnownClass :: Bytes . to_instance ( db)
158165 } else {
159166 Type :: IntLiteral ( auto_counter)
160- } )
167+ } ;
168+ Some ( auto_value_ty)
161169 }
162170
163171 _ => None ,
You can’t perform that action at this time.
0 commit comments