Skip to content

Commit 88a761e

Browse files
authored
Export DataclassInstance protocol from _typeshed (#9676)
1 parent b9270da commit 88a761e

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

stdlib/_typeshed/__init__.pyi

+9-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import mmap
88
import pickle
99
import sys
1010
from collections.abc import Awaitable, Callable, Iterable, Set as AbstractSet
11+
from dataclasses import Field
1112
from os import PathLike
1213
from types import FrameType, TracebackType
13-
from typing import Any, AnyStr, Generic, Protocol, TypeVar, Union
14+
from typing import Any, AnyStr, ClassVar, Generic, Protocol, TypeVar, Union
1415
from typing_extensions import Final, Literal, LiteralString, TypeAlias, final
1516

1617
_KT = TypeVar("_KT")
@@ -304,3 +305,10 @@ ProfileFunction: TypeAlias = Callable[[FrameType, str, Any], object]
304305

305306
# Objects suitable to be passed to sys.settrace, threading.settrace, and similar
306307
TraceFunction: TypeAlias = Callable[[FrameType, str, Any], TraceFunction | None]
308+
309+
# experimental
310+
# Might not work as expected for pyright, see
311+
# https://github.com/python/typeshed/pull/9362
312+
# https://github.com/microsoft/pyright/issues/4339
313+
class DataclassInstance(Protocol):
314+
__dataclass_fields__: ClassVar[dict[str, Field[Any]]]

stdlib/dataclasses.pyi

+11-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import enum
22
import sys
33
import types
4+
from _typeshed import DataclassInstance
45
from builtins import type as Type # alias to avoid name clashes with fields named "type"
56
from collections.abc import Callable, Iterable, Mapping
6-
from typing import Any, ClassVar, Generic, Protocol, TypeVar, overload
7+
from typing import Any, Generic, Protocol, TypeVar, overload
78
from typing_extensions import Literal, TypeAlias, TypeGuard
89

910
if sys.version_info >= (3, 9):
@@ -30,10 +31,7 @@ __all__ = [
3031
if sys.version_info >= (3, 10):
3132
__all__ += ["KW_ONLY"]
3233

33-
class _DataclassInstance(Protocol):
34-
__dataclass_fields__: ClassVar[dict[str, Field[Any]]]
35-
36-
_DataclassT = TypeVar("_DataclassT", bound=_DataclassInstance)
34+
_DataclassT = TypeVar("_DataclassT", bound=DataclassInstance)
3735

3836
# define _MISSING_TYPE as an enum within the type stubs,
3937
# even though that is not really its type at runtime
@@ -49,13 +47,13 @@ if sys.version_info >= (3, 10):
4947
class KW_ONLY: ...
5048

5149
@overload
52-
def asdict(obj: _DataclassInstance) -> dict[str, Any]: ...
50+
def asdict(obj: DataclassInstance) -> dict[str, Any]: ...
5351
@overload
54-
def asdict(obj: _DataclassInstance, *, dict_factory: Callable[[list[tuple[str, Any]]], _T]) -> _T: ...
52+
def asdict(obj: DataclassInstance, *, dict_factory: Callable[[list[tuple[str, Any]]], _T]) -> _T: ...
5553
@overload
56-
def astuple(obj: _DataclassInstance) -> tuple[Any, ...]: ...
54+
def astuple(obj: DataclassInstance) -> tuple[Any, ...]: ...
5755
@overload
58-
def astuple(obj: _DataclassInstance, *, tuple_factory: Callable[[list[Any]], _T]) -> _T: ...
56+
def astuple(obj: DataclassInstance, *, tuple_factory: Callable[[list[Any]], _T]) -> _T: ...
5957

6058
if sys.version_info >= (3, 8):
6159
# cls argument is now positional-only
@@ -223,13 +221,13 @@ else:
223221
metadata: Mapping[Any, Any] | None = None,
224222
) -> Any: ...
225223

226-
def fields(class_or_instance: _DataclassInstance | type[_DataclassInstance]) -> tuple[Field[Any], ...]: ...
224+
def fields(class_or_instance: DataclassInstance | type[DataclassInstance]) -> tuple[Field[Any], ...]: ...
227225
@overload
228-
def is_dataclass(obj: _DataclassInstance | type[_DataclassInstance]) -> Literal[True]: ...
226+
def is_dataclass(obj: DataclassInstance | type[DataclassInstance]) -> Literal[True]: ...
229227
@overload
230-
def is_dataclass(obj: type) -> TypeGuard[type[_DataclassInstance]]: ...
228+
def is_dataclass(obj: type) -> TypeGuard[type[DataclassInstance]]: ...
231229
@overload
232-
def is_dataclass(obj: object) -> TypeGuard[_DataclassInstance | type[_DataclassInstance]]: ...
230+
def is_dataclass(obj: object) -> TypeGuard[DataclassInstance | type[DataclassInstance]]: ...
233231

234232
class FrozenInstanceError(AttributeError): ...
235233

0 commit comments

Comments
 (0)