1
1
from __future__ import annotations
2
2
3
3
import dataclasses as dc
4
- from typing import Any , Dict , Tuple , Type
4
+ from typing import TYPE_CHECKING , Any , Dict , Tuple , Type , Union
5
5
from typing_extensions import assert_type
6
6
7
+ if TYPE_CHECKING :
8
+ from _typeshed import DataclassInstance
9
+
7
10
8
11
@dc .dataclass
9
12
class Foo :
@@ -21,10 +24,9 @@ class Foo:
21
24
# dc.astuple(Foo)
22
25
# dc.replace(Foo)
23
26
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])
28
30
29
31
f = Foo (attr = "attr" )
30
32
@@ -39,7 +41,7 @@ class Foo:
39
41
assert_type (f , Foo )
40
42
41
43
42
- def test_other_isdataclass_overloads (x : type , y : object ) -> None :
44
+ def check_other_isdataclass_overloads (x : type , y : object ) -> None :
43
45
# TODO: pyright correctly emits an error on this, but mypy does not -- why?
44
46
# dc.fields(x)
45
47
@@ -55,17 +57,23 @@ def test_other_isdataclass_overloads(x: type, y: object) -> None:
55
57
dc .replace (y ) # type: ignore
56
58
57
59
if dc .is_dataclass (x ):
60
+ assert_type (x , Type ["DataclassInstance" ])
58
61
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)
64
71
65
72
if dc .is_dataclass (y ):
73
+ assert_type (y , Union ["DataclassInstance" , Type ["DataclassInstance" ]])
66
74
assert_type (dc .fields (y ), Tuple [dc .Field [Any ], ...])
67
75
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
69
77
# whether it's a dataclass class or a dataclass instance.
70
78
# Pyright, however, handles ClassVar members in protocols differently.
71
79
# See https://github.com/microsoft/pyright/issues/4339
@@ -75,6 +83,7 @@ def test_other_isdataclass_overloads(x: type, y: object) -> None:
75
83
# dc.replace(y)
76
84
77
85
if dc .is_dataclass (y ) and not isinstance (y , type ):
86
+ assert_type (y , "DataclassInstance" )
78
87
assert_type (dc .fields (y ), Tuple [dc .Field [Any ], ...])
79
88
assert_type (dc .asdict (y ), Dict [str , Any ])
80
89
assert_type (dc .astuple (y ), Tuple [Any , ...])
0 commit comments