@@ -3,8 +3,8 @@ import sys
33import types
44from builtins import type as Type # alias to avoid name clashes with fields named "type"
55from collections .abc import Callable , Iterable , Mapping
6- from typing import Any , Generic , Protocol , TypeVar , overload
7- from typing_extensions import Literal , TypeAlias
6+ from typing import Any , ClassVar , Generic , Protocol , TypeVar , overload
7+ from typing_extensions import Literal , TypeAlias , TypeGuard
88
99if sys .version_info >= (3 , 9 ):
1010 from types import GenericAlias
@@ -30,6 +30,11 @@ __all__ = [
3030if sys .version_info >= (3 , 10 ):
3131 __all__ += ["KW_ONLY" ]
3232
33+ class _DataclassInstance (Protocol ):
34+ __dataclass_fields__ : ClassVar [dict [str , Field [Any ]]]
35+
36+ _DataclassT = TypeVar ("_DataclassT" , bound = _DataclassInstance )
37+
3338# define _MISSING_TYPE as an enum within the type stubs,
3439# even though that is not really its type at runtime
3540# this allows us to use Literal[_MISSING_TYPE.MISSING]
@@ -44,13 +49,13 @@ if sys.version_info >= (3, 10):
4449 class KW_ONLY : ...
4550
4651@overload
47- def asdict (obj : Any ) -> dict [str , Any ]: ...
52+ def asdict (obj : _DataclassInstance ) -> dict [str , Any ]: ...
4853@overload
49- def asdict (obj : Any , * , dict_factory : Callable [[list [tuple [str , Any ]]], _T ]) -> _T : ...
54+ def asdict (obj : _DataclassInstance , * , dict_factory : Callable [[list [tuple [str , Any ]]], _T ]) -> _T : ...
5055@overload
51- def astuple (obj : Any ) -> tuple [Any , ...]: ...
56+ def astuple (obj : _DataclassInstance ) -> tuple [Any , ...]: ...
5257@overload
53- def astuple (obj : Any , * , tuple_factory : Callable [[list [Any ]], _T ]) -> _T : ...
58+ def astuple (obj : _DataclassInstance , * , tuple_factory : Callable [[list [Any ]], _T ]) -> _T : ...
5459
5560if sys .version_info >= (3 , 8 ):
5661 # cls argument is now positional-only
@@ -212,8 +217,13 @@ else:
212217 metadata : Mapping [Any , Any ] | None = ...,
213218 ) -> Any : ...
214219
215- def fields (class_or_instance : Any ) -> tuple [Field [Any ], ...]: ...
216- def is_dataclass (obj : Any ) -> bool : ...
220+ def fields (class_or_instance : _DataclassInstance | type [_DataclassInstance ]) -> tuple [Field [Any ], ...]: ...
221+ @overload
222+ def is_dataclass (obj : _DataclassInstance | type [_DataclassInstance ]) -> Literal [True ]: ...
223+ @overload
224+ def is_dataclass (obj : type ) -> TypeGuard [type [_DataclassInstance ]]: ...
225+ @overload
226+ def is_dataclass (obj : object ) -> TypeGuard [_DataclassInstance | type [_DataclassInstance ]]: ...
217227
218228class FrozenInstanceError (AttributeError ): ...
219229
@@ -285,4 +295,4 @@ else:
285295 frozen : bool = ...,
286296 ) -> type : ...
287297
288- def replace (__obj : _T , ** changes : Any ) -> _T : ...
298+ def replace (__obj : _DataclassT , ** changes : Any ) -> _DataclassT : ...
0 commit comments