1
+ from __future__ import annotations
1
2
import gc
2
- from typing import MutableMapping , Any , AbstractSet , Type , Callable , Dict , Tuple , Mapping , Optional , Iterable , Set
3
+ from typing import MutableMapping , Any , AbstractSet , Type , Callable , Dict , Tuple , Mapping , Optional , Set , cast
3
4
4
5
5
6
class _Missing :
@@ -38,10 +39,17 @@ def set_attr(t: Any, name: str, value: Any) -> Any:
38
39
39
40
class PatchMeta (type ):
40
41
__enabled__ : bool
41
- __run_on_class__ : Callable [[ Type [ Any ]], None ]
42
- __run_on_instance__ : Callable [[ Any ], None ]
42
+ __run_on_class__ : classmethod
43
+ __run_on_instance__ : classmethod
43
44
44
- def __prepare__ (cls , * args : Any , ** kwargs : Any ) -> Mapping [str , Any ]:
45
+ __target__ : Type [Any ]
46
+ __to_update__ : dict [str , Any ]
47
+ __to_delete__ : AbstractSet [str ]
48
+ __original_attrs__ : dict [Any , Any ]
49
+ __extra__ : AbstractSet [str ]
50
+ __redefined_on_subclasses__ : dict [str , Any ]
51
+
52
+ def __prepare__ (cls , * args : Any , ** kwargs : Any ) -> Mapping [str , Any ]: # type: ignore
45
53
return type .__prepare__ (* args , ** kwargs )
46
54
47
55
def __new__ (
@@ -52,19 +60,19 @@ def __new__(
52
60
target : Any = None ,
53
61
delete : AbstractSet [str ] = None ,
54
62
update : AbstractSet [str ] = None
55
- ) -> " PatchMeta" :
63
+ ) -> PatchMeta :
56
64
target = target or namespace .pop ('__target__' , None )
57
65
if target is None :
58
66
return type .__new__ (mcs , name , bases , namespace )
59
67
60
- to_delete = delete or namespace .pop ('__to_delete__' , set ())
61
- to_update = update or namespace .pop ('__to_update__' , set ())
68
+ to_delete = cast ( set , delete or namespace .pop ('__to_delete__' , set () ))
69
+ to_update = cast ( set , update or namespace .pop ('__to_update__' , set () ))
62
70
63
71
patched_attrs = {
64
72
attr : namespace [attr ]
65
73
for attr in to_update
66
-
67
74
}
75
+
68
76
original_attrs = {
69
77
attr : target .__dict__ [attr ]
70
78
for attr in to_update | to_delete
@@ -164,15 +172,10 @@ def _get_all_subclasses(cls, target: Type[Any]) -> Set[Type[Any]]:
164
172
165
173
class Patch (metaclass = PatchMeta ):
166
174
"""Class to declare attributes to patch other classes"""
167
-
168
- __target__ : Type [Any ]
169
- __to_update__ : AbstractSet [str ]
170
- __to_delete__ : AbstractSet [str ]
171
-
172
175
__enabled__ : bool = False
173
176
174
- __run_on_class__ : Callable [[Type [Any ]], None ] = None
175
- __run_on_instance__ : Callable [[Any ], None ] = None
177
+ __run_on_class__ : Callable [[Type [Any ]], None ] | None = None
178
+ __run_on_instance__ : Callable [[Any ], None ] | None = None
176
179
177
180
178
181
class InstancePatchMeta (PatchMeta ):
@@ -181,18 +184,18 @@ def _get_all_subclasses(cls, target: Any) -> Set[Type[Any]]:
181
184
182
185
def new (
183
186
cls , target : Any , delete : AbstractSet [str ] = None , update : Dict [str , Any ] = None
184
- ) -> " InstancePatchMeta" :
185
- return cls .__class__ .__new__ (
186
- cls .__class__ ,
187
- getattr (target , '__name__' , target .__class__ .__name__ ) + 'Patch' ,
188
- (cls ,),
189
- update ,
187
+ ) -> InstancePatchMeta :
188
+ return cast ( InstancePatchMeta , cls .__class__ .__new__ (
189
+ mcs = cls .__class__ ,
190
+ name = getattr (target , '__name__' , target .__class__ .__name__ ) + 'Patch' ,
191
+ bases = (cls ,),
192
+ namespace = update or {} ,
190
193
target = target ,
191
194
delete = delete ,
192
- update = update .keys (),
193
- )
195
+ update = update .keys () if update else None ,
196
+ ))
194
197
195
198
196
199
class InstancePatch (metaclass = InstancePatchMeta ):
197
- __run_on_class__ : Callable [[ Type [ Any ]], None ] = None
198
- __run_on_instance__ : Callable [[ Any ], None ] = None
200
+ __run_on_class__ = None
201
+ __run_on_instance__ = None
0 commit comments