|
1 | 1 | import enum |
2 | 2 | import sys |
3 | | -from typing import Any, TypeVar, overload, type_check_only |
| 3 | +from typing import Any, Literal, TypeVar, overload, type_check_only |
4 | 4 |
|
5 | 5 | from _typeshed import ConvertibleToInt |
6 | 6 | from django.utils.functional import _StrOrPromise |
7 | 7 | from typing_extensions import deprecated |
8 | 8 |
|
9 | | -_Self = TypeVar("_Self") |
10 | | - |
11 | 9 | if sys.version_info >= (3, 11): |
12 | | - _enum_property = enum.property |
13 | | - EnumType = enum.EnumType |
14 | | - IntEnum = enum.IntEnum |
15 | | - StrEnum = enum.StrEnum |
| 10 | + from enum import EnumType, IntEnum, StrEnum |
| 11 | + from enum import property as enum_property |
16 | 12 | else: |
17 | | - _enum_property = property |
18 | | - EnumType = enum.EnumMeta |
| 13 | + from enum import EnumMeta as EnumType |
| 14 | + from types import DynamicClassAttribute as enum_property |
19 | 15 |
|
20 | 16 | class ReprEnum(enum.Enum): ... # type: ignore[misc] |
21 | 17 | class IntEnum(int, ReprEnum): ... # type: ignore[misc] |
22 | 18 | class StrEnum(str, ReprEnum): ... # type: ignore[misc] |
23 | 19 |
|
| 20 | +_Self = TypeVar("_Self", bound=ChoicesType) |
| 21 | + |
24 | 22 | class ChoicesType(EnumType): |
25 | | - # There's a contradiction between mypy and PYI019 regarding metaclasses. Where mypy |
26 | | - # disallows 'typing_extensions.Self' on metaclasses, while PYI019 try to enforce |
27 | | - # 'typing_extensions.Self' for '__new__' methods.. We've chosen to ignore the |
28 | | - # linter and trust mypy. |
29 | | - def __new__( # noqa: PYI019 |
| 23 | + __empty__: _StrOrPromise |
| 24 | + def __new__( |
30 | 25 | metacls: type[_Self], classname: str, bases: tuple[type, ...], classdict: enum._EnumDict, **kwds: Any |
31 | 26 | ) -> _Self: ... |
32 | | - def __contains__(self, member: Any) -> bool: ... |
33 | 27 | @property |
34 | 28 | def names(self) -> list[str]: ... |
35 | 29 | @property |
36 | | - def choices(self) -> list[tuple[Any, str]]: ... |
| 30 | + def choices(self) -> list[tuple[Any, _StrOrPromise]]: ... |
37 | 31 | @property |
38 | | - def labels(self) -> list[str]: ... |
| 32 | + def labels(self) -> list[_StrOrPromise]: ... |
39 | 33 | @property |
40 | 34 | def values(self) -> list[Any]: ... |
| 35 | + if sys.version_info < (3, 12): |
| 36 | + def __contains__(self, member: Any) -> bool: ... |
41 | 37 |
|
42 | 38 | @deprecated("ChoicesMeta is deprecated in favor of ChoicesType and will be removed in Django 6.0.") |
43 | 39 | class ChoicesMeta(ChoicesType): ... |
44 | 40 |
|
45 | 41 | class Choices(enum.Enum, metaclass=ChoicesType): # type: ignore[misc] |
46 | | - @property |
47 | | - def label(self) -> str: ... |
48 | | - @_enum_property |
| 42 | + _label_: _StrOrPromise |
| 43 | + do_not_call_in_templates: Literal[True] |
| 44 | + |
| 45 | + @enum_property |
| 46 | + def label(self) -> _StrOrPromise: ... |
| 47 | + @enum_property |
49 | 48 | def value(self) -> Any: ... |
50 | | - @property |
51 | | - def do_not_call_in_templates(self) -> bool: ... |
52 | 49 |
|
53 | 50 | # fake, to keep simulate class properties |
54 | 51 | @type_check_only |
55 | | -class _IntegerChoicesMeta(ChoicesType): |
| 52 | +class _IntegerChoicesType(ChoicesType): |
56 | 53 | @property |
57 | | - def choices(self) -> list[tuple[int, str]]: ... |
| 54 | + def choices(self) -> list[tuple[int, _StrOrPromise]]: ... |
58 | 55 | @property |
59 | 56 | def values(self) -> list[int]: ... |
60 | 57 |
|
61 | 58 | # In reality, the `__init__` overloads provided below should also support |
62 | 59 | # all the arguments of `int.__new__`/`str.__new__` (e.g. `base`, `encoding`). |
63 | 60 | # They are omitted on purpose to avoid having convoluted stubs for these enums: |
64 | | -class IntegerChoices(Choices, IntEnum, metaclass=_IntegerChoicesMeta): # type: ignore[misc] |
| 61 | +class IntegerChoices(Choices, IntEnum, metaclass=_IntegerChoicesType): # type: ignore[misc] |
65 | 62 | @overload |
66 | 63 | def __init__(self, x: ConvertibleToInt) -> None: ... |
67 | 64 | @overload |
68 | 65 | def __init__(self, x: ConvertibleToInt, label: _StrOrPromise) -> None: ... |
69 | | - @_enum_property |
| 66 | + @enum_property |
70 | 67 | def value(self) -> int: ... |
71 | 68 |
|
72 | 69 | # fake, to keep simulate class properties |
73 | 70 | @type_check_only |
74 | | -class _TextChoicesMeta(ChoicesType): |
| 71 | +class _TextChoicesType(ChoicesType): |
75 | 72 | @property |
76 | | - def choices(self) -> list[tuple[str, str]]: ... |
| 73 | + def choices(self) -> list[tuple[str, _StrOrPromise]]: ... |
77 | 74 | @property |
78 | 75 | def values(self) -> list[str]: ... |
79 | 76 |
|
80 | | -class TextChoices(Choices, StrEnum, metaclass=_TextChoicesMeta): # type: ignore[misc] |
| 77 | +class TextChoices(Choices, StrEnum, metaclass=_TextChoicesType): # type: ignore[misc] |
81 | 78 | @overload |
82 | 79 | def __init__(self, object: str) -> None: ... |
83 | 80 | @overload |
84 | 81 | def __init__(self, object: str, label: _StrOrPromise) -> None: ... |
85 | | - @_enum_property |
| 82 | + @enum_property |
86 | 83 | def value(self) -> str: ... |
0 commit comments