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