5
5
import sys
6
6
from abc import abstractmethod
7
7
from collections .abc import Iterable , Sequence
8
- from typing import TYPE_CHECKING , Any , ClassVar , Final , NewType , TypeVar , Union , cast , overload
9
- from typing_extensions import Self , TypeAlias as _TypeAlias , TypeGuard
8
+ from enum import IntEnum
9
+ from typing import (
10
+ TYPE_CHECKING ,
11
+ Any ,
12
+ ClassVar ,
13
+ Final ,
14
+ Generic ,
15
+ Literal ,
16
+ NewType ,
17
+ Union ,
18
+ cast ,
19
+ overload ,
20
+ )
21
+ from typing_extensions import Self , TypeAlias as _TypeAlias , TypeGuard , TypeVar
10
22
11
23
import mypy .nodes
12
24
from mypy .bogus_type import Bogus
@@ -694,16 +706,19 @@ def deserialize(cls, data: JsonDict) -> TypeVarType:
694
706
)
695
707
696
708
697
- class ParamSpecFlavor :
709
+ class ParamSpecFlavor ( IntEnum ) :
698
710
# Simple ParamSpec reference such as "P"
699
- BARE : Final = 0
711
+ BARE = 0
700
712
# P.args
701
- ARGS : Final = 1
713
+ ARGS = 1
702
714
# P.kwargs
703
- KWARGS : Final = 2
715
+ KWARGS = 2
716
+
717
+
718
+ Flavor = TypeVar ("Flavor" , bound = ParamSpecFlavor , default = Any )
704
719
705
720
706
- class ParamSpecType (TypeVarLikeType ):
721
+ class ParamSpecType (TypeVarLikeType , Generic [ Flavor ] ):
707
722
"""Type that refers to a ParamSpec.
708
723
709
724
A ParamSpec is a type variable that represents the parameter
@@ -721,17 +736,22 @@ class ParamSpecType(TypeVarLikeType):
721
736
always just 'object').
722
737
"""
723
738
739
+ # convenience type aliases
740
+ BARE : _TypeAlias = "ParamSpecType[Literal[ParamSpecFlavor.BARE]]"
741
+ ARGS : _TypeAlias = "ParamSpecType[Literal[ParamSpecFlavor.ARGS]]"
742
+ KWARGS : _TypeAlias = "ParamSpecType[Literal[ParamSpecFlavor.KWARGS]]"
743
+
724
744
__slots__ = ("flavor" , "prefix" )
725
745
726
- flavor : int
746
+ flavor : Flavor
727
747
prefix : Parameters
728
748
729
749
def __init__ (
730
750
self ,
731
751
name : str ,
732
752
fullname : str ,
733
753
id : TypeVarId ,
734
- flavor : int ,
754
+ flavor : Flavor ,
735
755
upper_bound : Type ,
736
756
default : Type ,
737
757
* ,
@@ -740,10 +760,12 @@ def __init__(
740
760
prefix : Parameters | None = None ,
741
761
) -> None :
742
762
super ().__init__ (name , fullname , id , upper_bound , default , line = line , column = column )
743
- self .flavor = flavor
763
+ self .flavor = ParamSpecFlavor ( flavor ) # type: ignore[assignment]
744
764
self .prefix = prefix or Parameters ([], [], [])
745
765
746
- def with_flavor (self , flavor : int ) -> ParamSpecType :
766
+ _F = TypeVar ("_F" , bound = ParamSpecFlavor , default = Flavor )
767
+
768
+ def with_flavor (self , flavor : _F ) -> ParamSpecType [_F ]:
747
769
return ParamSpecType (
748
770
self .name ,
749
771
self .fullname ,
@@ -758,16 +780,16 @@ def copy_modified(
758
780
self ,
759
781
* ,
760
782
id : Bogus [TypeVarId ] = _dummy ,
761
- flavor : int = _dummy_int ,
783
+ flavor : _F = _dummy_int , # type: ignore[assignment]
762
784
prefix : Bogus [Parameters ] = _dummy ,
763
785
default : Bogus [Type ] = _dummy ,
764
786
** kwargs : Any ,
765
- ) -> ParamSpecType :
787
+ ) -> ParamSpecType [ _F ] :
766
788
return ParamSpecType (
767
789
self .name ,
768
790
self .fullname ,
769
791
id if id is not _dummy else self .id ,
770
- flavor if flavor != _dummy_int else self .flavor ,
792
+ flavor if flavor != _dummy_int else self .flavor , # type: ignore[arg-type]
771
793
self .upper_bound ,
772
794
default = default if default is not _dummy else self .default ,
773
795
line = self .line ,
0 commit comments