Skip to content

Commit 3796725

Browse files
make paramspecflavor an IntEnum and ParamSpecType generic in that type.
1 parent cb77a9b commit 3796725

File tree

1 file changed

+36
-14
lines changed

1 file changed

+36
-14
lines changed

mypy/types.py

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,20 @@
55
import sys
66
from abc import abstractmethod
77
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
1022

1123
import mypy.nodes
1224
from mypy.bogus_type import Bogus
@@ -694,16 +706,19 @@ def deserialize(cls, data: JsonDict) -> TypeVarType:
694706
)
695707

696708

697-
class ParamSpecFlavor:
709+
class ParamSpecFlavor(IntEnum):
698710
# Simple ParamSpec reference such as "P"
699-
BARE: Final = 0
711+
BARE = 0
700712
# P.args
701-
ARGS: Final = 1
713+
ARGS = 1
702714
# P.kwargs
703-
KWARGS: Final = 2
715+
KWARGS = 2
716+
717+
718+
Flavor = TypeVar("Flavor", bound=ParamSpecFlavor, default=Any)
704719

705720

706-
class ParamSpecType(TypeVarLikeType):
721+
class ParamSpecType(TypeVarLikeType, Generic[Flavor]):
707722
"""Type that refers to a ParamSpec.
708723
709724
A ParamSpec is a type variable that represents the parameter
@@ -721,17 +736,22 @@ class ParamSpecType(TypeVarLikeType):
721736
always just 'object').
722737
"""
723738

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+
724744
__slots__ = ("flavor", "prefix")
725745

726-
flavor: int
746+
flavor: Flavor
727747
prefix: Parameters
728748

729749
def __init__(
730750
self,
731751
name: str,
732752
fullname: str,
733753
id: TypeVarId,
734-
flavor: int,
754+
flavor: Flavor,
735755
upper_bound: Type,
736756
default: Type,
737757
*,
@@ -740,10 +760,12 @@ def __init__(
740760
prefix: Parameters | None = None,
741761
) -> None:
742762
super().__init__(name, fullname, id, upper_bound, default, line=line, column=column)
743-
self.flavor = flavor
763+
self.flavor = ParamSpecFlavor(flavor) # type: ignore[assignment]
744764
self.prefix = prefix or Parameters([], [], [])
745765

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]:
747769
return ParamSpecType(
748770
self.name,
749771
self.fullname,
@@ -758,16 +780,16 @@ def copy_modified(
758780
self,
759781
*,
760782
id: Bogus[TypeVarId] = _dummy,
761-
flavor: int = _dummy_int,
783+
flavor: _F = _dummy_int, # type: ignore[assignment]
762784
prefix: Bogus[Parameters] = _dummy,
763785
default: Bogus[Type] = _dummy,
764786
**kwargs: Any,
765-
) -> ParamSpecType:
787+
) -> ParamSpecType[_F]:
766788
return ParamSpecType(
767789
self.name,
768790
self.fullname,
769791
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]
771793
self.upper_bound,
772794
default=default if default is not _dummy else self.default,
773795
line=self.line,

0 commit comments

Comments
 (0)