11from __future__ import annotations
22
33import dataclasses as dc
4- from typing import Any , Dict , Tuple , Type
4+ from typing import TYPE_CHECKING , Any , Dict , Tuple , Type , Union
55from typing_extensions import assert_type
66
7+ if TYPE_CHECKING :
8+ from _typeshed import DataclassInstance
9+
710
811@dc .dataclass
912class Foo :
@@ -21,10 +24,9 @@ class Foo:
2124# dc.astuple(Foo)
2225# dc.replace(Foo)
2326
24- if dc .is_dataclass (Foo ):
25- # The inferred type doesn't change
26- # if it's already known to be a subtype of type[_DataclassInstance]
27- assert_type (Foo , Type [Foo ])
27+ # See #9723 for why we can't make this assertion
28+ # if dc.is_dataclass(Foo):
29+ # assert_type(Foo, Type[Foo])
2830
2931f = Foo (attr = "attr" )
3032
@@ -39,7 +41,7 @@ class Foo:
3941 assert_type (f , Foo )
4042
4143
42- def test_other_isdataclass_overloads (x : type , y : object ) -> None :
44+ def check_other_isdataclass_overloads (x : type , y : object ) -> None :
4345 # TODO: pyright correctly emits an error on this, but mypy does not -- why?
4446 # dc.fields(x)
4547
@@ -55,17 +57,23 @@ def test_other_isdataclass_overloads(x: type, y: object) -> None:
5557 dc .replace (y ) # type: ignore
5658
5759 if dc .is_dataclass (x ):
60+ assert_type (x , Type ["DataclassInstance" ])
5861 assert_type (dc .fields (x ), Tuple [dc .Field [Any ], ...])
59- # These should cause type checkers to emit errors
60- # due to the fact it's a dataclass class, not an instance
61- dc .asdict (x ) # type: ignore
62- dc .astuple (x ) # type: ignore
63- dc .replace (x ) # type: ignore
62+
63+ # Mypy correctly emits an error on these due to the fact
64+ # that it's a dataclass class, not a dataclass instance.
65+ # Pyright, however, handles ClassVar members in protocols differently.
66+ # See https://github.com/microsoft/pyright/issues/4339
67+ #
68+ # dc.asdict(x)
69+ # dc.astuple(x)
70+ # dc.replace(x)
6471
6572 if dc .is_dataclass (y ):
73+ assert_type (y , Union ["DataclassInstance" , Type ["DataclassInstance" ]])
6674 assert_type (dc .fields (y ), Tuple [dc .Field [Any ], ...])
6775
68- # Mypy corrextly emits an error on these due to the fact we don't know
76+ # Mypy correctly emits an error on these due to the fact we don't know
6977 # whether it's a dataclass class or a dataclass instance.
7078 # Pyright, however, handles ClassVar members in protocols differently.
7179 # See https://github.com/microsoft/pyright/issues/4339
@@ -75,6 +83,7 @@ def test_other_isdataclass_overloads(x: type, y: object) -> None:
7583 # dc.replace(y)
7684
7785 if dc .is_dataclass (y ) and not isinstance (y , type ):
86+ assert_type (y , "DataclassInstance" )
7887 assert_type (dc .fields (y ), Tuple [dc .Field [Any ], ...])
7988 assert_type (dc .asdict (y ), Dict [str , Any ])
8089 assert_type (dc .astuple (y ), Tuple [Any , ...])
0 commit comments