1
1
from functools import partial
2
2
import inspect
3
+ import sys
3
4
4
5
from typing import (
5
- Any ,
6
6
Callable ,
7
7
Iterable ,
8
8
List ,
9
9
Optional ,
10
- overload ,
11
- Union ,
12
10
Tuple ,
13
11
Type ,
14
12
TypeVar ,
13
+ Union ,
14
+ cast ,
15
+ overload ,
15
16
)
16
17
18
+ if sys .version_info >= (3 , 8 ):
19
+ from typing import Protocol
20
+ else :
21
+ from typing_extensions import Protocol # pragma: no cover
22
+
17
23
18
24
T = TypeVar ("T" )
19
25
20
26
21
- Result = Iterable [Union [Any , Tuple [Any ], Tuple [str , Any ], Tuple [str , Any , Any ]]]
27
+ Result = Iterable [
28
+ Union [object , Tuple [object ], Tuple [str , object ], Tuple [str , object , object ]]
29
+ ]
22
30
RichReprResult = Result
23
31
24
32
25
33
class ReprError (Exception ):
26
34
"""An error occurred when attempting to build a repr."""
27
35
28
36
37
+ class SupportsRichRepr (Protocol ):
38
+ def __rich_repr__ (self ) -> Result : # pragma: no cover
39
+ ...
40
+
41
+
29
42
@overload
30
- def auto (cls : Optional [T ] ) -> T :
43
+ def auto (cls : Optional [Type [ T ]] ) -> Type [ T ] :
31
44
...
32
45
33
46
34
47
@overload
35
- def auto (* , angular : bool = False ) -> Callable [[T ], T ]:
48
+ def auto (* , angular : bool ) -> Callable [[Type [ T ]], Type [ T ] ]:
36
49
...
37
50
38
51
39
52
def auto (
40
- cls : Optional [T ] = None , * , angular : Optional [bool ] = None
41
- ) -> Union [T , Callable [[T ], T ]]:
53
+ cls : Optional [Type [ T ] ] = None , * , angular : Optional [bool ] = None
54
+ ) -> Union [Type [ T ] , Callable [[Type [ T ]], Type [ T ] ]]:
42
55
"""Class decorator to create __repr__ from __rich_repr__"""
43
56
44
57
def do_replace (cls : Type [T ], angular : Optional [bool ] = None ) -> Type [T ]:
45
- def auto_repr (self : Type [ T ] ) -> str :
58
+ def auto_repr (self : SupportsRichRepr ) -> str :
46
59
"""Create repr string from __rich_repr__"""
47
60
repr_str : List [str ] = []
48
61
append = repr_str .append
49
62
50
- angular = getattr (self .__rich_repr__ , "angular" , False ) # type: ignore
51
- for arg in self .__rich_repr__ (): # type: ignore
63
+ angular = getattr (self .__rich_repr__ , "angular" , False )
64
+ for arg in self .__rich_repr__ ():
52
65
if isinstance (arg , tuple ):
53
66
if len (arg ) == 1 :
54
67
append (repr (arg [0 ]))
55
68
else :
56
- key , value , * default = arg
69
+ key , value , * default = cast (
70
+ Union [
71
+ Tuple [object , ...],
72
+ Tuple [str , object ],
73
+ Tuple [str , object , object ],
74
+ ],
75
+ arg ,
76
+ )
57
77
if key is None :
58
78
append (repr (value ))
59
79
else :
@@ -67,10 +87,10 @@ def auto_repr(self: Type[T]) -> str:
67
87
else :
68
88
return f"{ self .__class__ .__name__ } ({ ', ' .join (repr_str )} )"
69
89
70
- def auto_rich_repr (self : Type [ T ] ) -> Result :
71
- """Auto generate __rich_rep__ from signature of __init__"""
90
+ def auto_rich_repr (self : T ) -> Result :
91
+ """Auto generate __rich_repr__ from signature of __init__"""
72
92
try :
73
- signature = inspect .signature (self .__init__ ) ## type: ignore
93
+ signature = inspect .signature (self .__init__ ) # type: ignore[misc]
74
94
for name , param in signature .parameters .items ():
75
95
if param .kind == param .POSITIONAL_ONLY :
76
96
yield getattr (self , name )
@@ -89,33 +109,33 @@ def auto_rich_repr(self: Type[T]) -> Result:
89
109
90
110
if not hasattr (cls , "__rich_repr__" ):
91
111
auto_rich_repr .__doc__ = "Build a rich repr"
92
- cls . __rich_repr__ = auto_rich_repr # type: ignore
112
+ setattr ( cls , " __rich_repr__" , auto_rich_repr )
93
113
94
114
auto_repr .__doc__ = "Return repr(self)"
95
- cls . __repr__ = auto_repr # type: ignore
115
+ setattr ( cls , " __repr__" , auto_repr )
96
116
if angular is not None :
97
- cls .__rich_repr__ . angular = angular # type: ignore
117
+ setattr ( cast ( SupportsRichRepr , cls ) .__rich_repr__ , " angular" , angular )
98
118
return cls
99
119
100
120
if cls is None :
101
- return partial (do_replace , angular = angular ) # type: ignore
121
+ return partial (do_replace , angular = angular )
102
122
else :
103
- return do_replace (cls , angular = angular ) # type: ignore
123
+ return do_replace (cls , angular = angular )
104
124
105
125
106
126
@overload
107
- def rich_repr (cls : Optional [T ] ) -> T :
127
+ def rich_repr (cls : Optional [Type [ T ]] ) -> Type [ T ] :
108
128
...
109
129
110
130
111
131
@overload
112
- def rich_repr (* , angular : bool = False ) -> Callable [[T ], T ]:
132
+ def rich_repr (* , angular : bool = False ) -> Callable [[Type [ T ]], Type [ T ] ]:
113
133
...
114
134
115
135
116
136
def rich_repr (
117
- cls : Optional [T ] = None , * , angular : bool = False
118
- ) -> Union [T , Callable [[T ], T ]]:
137
+ cls : Optional [Type [ T ] ] = None , * , angular : bool = False
138
+ ) -> Union [Type [ T ] , Callable [[Type [ T ]], Type [ T ] ]]:
119
139
if cls is None :
120
140
return auto (angular = angular )
121
141
else :
@@ -143,7 +163,7 @@ def __rich_repr__(self) -> Result:
143
163
console .print (foo , width = 30 )
144
164
145
165
console .rule ("Angular repr" )
146
- Foo .__rich_repr__ . angular = True # type: ignore
166
+ setattr ( Foo .__rich_repr__ , " angular" , True )
147
167
148
168
console .print (foo )
149
169
0 commit comments