2
2
import types as python_types
3
3
import typing
4
4
from typing import Any
5
+ from typing import ClassVar
5
6
from typing import Dict
6
7
from typing import FrozenSet
7
8
from typing import Iterable
@@ -68,19 +69,20 @@ def get_attr_fields_dict(cls: type) -> Dict[str, dataclasses.Field]: # type: ig
68
69
MISSING = frozenset ({DATACLASSES_MISSING })
69
70
70
71
if TYPE_CHECKING : # pragma: no cover
71
- from _typeshed import DataclassInstance as DataclassesProtocol
72
+ from _typeshed import DataclassInstance
72
73
else :
73
-
74
- class DataclassesProtocol (Protocol ):
75
- __dataclasses_fields__ : Dict [str , dataclasses .Field ]
74
+ # https://github.com/python/typeshed/blob/727f3c4320d2af3af2f16695e24dd78e79b7c070/stdlib/_typeshed/__init__.pyi#L348
75
+ # TODO: update the hint to `Field[Any]` when we drop support for 3.8
76
+ class DataclassInstance (Protocol ):
77
+ __dataclasses_fields__ : ClassVar [Dict [str , dataclasses .Field ]]
76
78
77
79
78
80
if TYPE_CHECKING and _use_attr : # pragma: no cover
79
81
from attr import AttrsInstance
80
82
else :
81
-
83
+ # https://github.com/python-attrs/attrs/blob/f7f317ae4c3790f23ae027db626593d50e8a4e88/src/attr/_typing_compat.pyi#L9
82
84
class AttrsInstance (Protocol ): # type: ignore[no-redef]
83
- __attrs_attrs__ : Dict [ str , Any ]
85
+ __attrs_attrs__ : ClassVar [ Any ]
84
86
85
87
86
88
def is_attr_class (cls : type ) -> bool : # type: ignore[arg-type]
@@ -90,7 +92,7 @@ def is_attr_class(cls: type) -> bool: # type: ignore[arg-type]
90
92
91
93
_MISSING_OR_NONE : FrozenSet [Any ] = frozenset ({* MISSING , None })
92
94
"""Set of values that are considered missing or None for dataclasses or attr classes"""
93
- _DataclassesOrAttrClass : TypeAlias = Union [DataclassesProtocol , AttrsInstance ]
95
+ _DataclassesOrAttrClass : TypeAlias = Union [DataclassInstance , AttrsInstance ]
94
96
"""
95
97
TypeAlias for dataclasses or attr classes. Mostly nonsense because they are not true types, they
96
98
are traits, but there is no python trait-tester.
@@ -103,7 +105,7 @@ def is_attr_class(cls: type) -> bool: # type: ignore[arg-type]
103
105
104
106
105
107
def _get_dataclasses_fields_dict (
106
- class_or_instance : Union [DataclassesProtocol , Type [DataclassesProtocol ]],
108
+ class_or_instance : Union [DataclassInstance , Type [DataclassInstance ]],
107
109
) -> Dict [str , dataclasses .Field ]:
108
110
"""Get a dict from field name to Field for a dataclass class or instance."""
109
111
return {field .name : field for field in get_dataclasses_fields (class_or_instance )}
0 commit comments