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