1
1
from functools import wraps
2
2
import inspect
3
3
from textwrap import dedent
4
- from typing import Any , Callable , Dict , List , Optional , Tuple , Type , Union
4
+ from typing import (
5
+ Any ,
6
+ Callable ,
7
+ Dict ,
8
+ List ,
9
+ Optional ,
10
+ Tuple ,
11
+ Type ,
12
+ TypeVar ,
13
+ Union ,
14
+ cast ,
15
+ )
5
16
import warnings
6
17
7
18
from pandas ._libs .properties import cache_readonly # noqa
8
19
20
+ FuncType = Callable [..., Any ]
21
+ F = TypeVar ("F" , bound = FuncType )
22
+
9
23
10
24
def deprecate (
11
25
name : str ,
12
- alternative : Callable ,
26
+ alternative : Callable [..., Any ] ,
13
27
version : str ,
14
28
alt_name : Optional [str ] = None ,
15
29
klass : Optional [Type [Warning ]] = None ,
16
30
stacklevel : int = 2 ,
17
31
msg : Optional [str ] = None ,
18
- ) -> Callable :
32
+ ) -> Callable [..., Any ] :
19
33
"""
20
34
Return a new function that emits a deprecation warning on use.
21
35
@@ -47,7 +61,7 @@ def deprecate(
47
61
warning_msg = msg or "{} is deprecated, use {} instead" .format (name , alt_name )
48
62
49
63
@wraps (alternative )
50
- def wrapper (* args , ** kwargs ):
64
+ def wrapper (* args , ** kwargs ) -> Callable [..., Any ] :
51
65
warnings .warn (warning_msg , klass , stacklevel = stacklevel )
52
66
return alternative (* args , ** kwargs )
53
67
@@ -90,9 +104,9 @@ def wrapper(*args, **kwargs):
90
104
def deprecate_kwarg (
91
105
old_arg_name : str ,
92
106
new_arg_name : Optional [str ],
93
- mapping : Optional [Union [Dict , Callable [[Any ], Any ]]] = None ,
107
+ mapping : Optional [Union [Dict [ Any , Any ] , Callable [[Any ], Any ]]] = None ,
94
108
stacklevel : int = 2 ,
95
- ) -> Callable :
109
+ ) -> Callable [..., Any ] :
96
110
"""
97
111
Decorator to deprecate a keyword argument of a function.
98
112
@@ -160,27 +174,27 @@ def deprecate_kwarg(
160
174
"mapping from old to new argument values " "must be dict or callable!"
161
175
)
162
176
163
- def _deprecate_kwarg (func ) :
177
+ def _deprecate_kwarg (func : F ) -> F :
164
178
@wraps (func )
165
- def wrapper (* args , ** kwargs ):
179
+ def wrapper (* args , ** kwargs ) -> Callable [..., Any ] :
166
180
old_arg_value = kwargs .pop (old_arg_name , None )
167
181
168
- if new_arg_name is None and old_arg_value is not None :
169
- msg = (
170
- "the '{old_name}' keyword is deprecated and will be "
171
- "removed in a future version. "
172
- "Please take steps to stop the use of '{old_name}'"
173
- ).format (old_name = old_arg_name )
174
- warnings .warn (msg , FutureWarning , stacklevel = stacklevel )
175
- kwargs [old_arg_name ] = old_arg_value
176
- return func (* args , ** kwargs )
177
-
178
182
if old_arg_value is not None :
179
- if mapping is not None :
180
- if hasattr (mapping , "get" ):
181
- new_arg_value = mapping .get (old_arg_value , old_arg_value )
182
- else :
183
+ if new_arg_name is None :
184
+ msg = (
185
+ "the '{old_name}' keyword is deprecated and will be "
186
+ "removed in a future version. "
187
+ "Please take steps to stop the use of '{old_name}'"
188
+ ).format (old_name = old_arg_name )
189
+ warnings .warn (msg , FutureWarning , stacklevel = stacklevel )
190
+ kwargs [old_arg_name ] = old_arg_value
191
+ return func (* args , ** kwargs )
192
+
193
+ elif mapping is not None :
194
+ if callable (mapping ):
183
195
new_arg_value = mapping (old_arg_value )
196
+ else :
197
+ new_arg_value = mapping .get (old_arg_value , old_arg_value )
184
198
msg = (
185
199
"the {old_name}={old_val!r} keyword is deprecated, "
186
200
"use {new_name}={new_val!r} instead"
@@ -198,7 +212,7 @@ def wrapper(*args, **kwargs):
198
212
).format (old_name = old_arg_name , new_name = new_arg_name )
199
213
200
214
warnings .warn (msg , FutureWarning , stacklevel = stacklevel )
201
- if kwargs .get (new_arg_name , None ) is not None :
215
+ if kwargs .get (new_arg_name ) is not None :
202
216
msg = (
203
217
"Can only specify '{old_name}' or '{new_name}', " "not both"
204
218
).format (old_name = old_arg_name , new_name = new_arg_name )
@@ -207,17 +221,17 @@ def wrapper(*args, **kwargs):
207
221
kwargs [new_arg_name ] = new_arg_value
208
222
return func (* args , ** kwargs )
209
223
210
- return wrapper
224
+ return cast ( F , wrapper )
211
225
212
226
return _deprecate_kwarg
213
227
214
228
215
229
def rewrite_axis_style_signature (
216
230
name : str , extra_params : List [Tuple [str , Any ]]
217
- ) -> Callable :
218
- def decorate (func ) :
231
+ ) -> Callable [..., Any ] :
232
+ def decorate (func : F ) -> F :
219
233
@wraps (func )
220
- def wrapper (* args , ** kwargs ):
234
+ def wrapper (* args , ** kwargs ) -> Callable [..., Any ] :
221
235
return func (* args , ** kwargs )
222
236
223
237
kind = inspect .Parameter .POSITIONAL_OR_KEYWORD
@@ -234,8 +248,9 @@ def wrapper(*args, **kwargs):
234
248
235
249
sig = inspect .Signature (params )
236
250
237
- func .__signature__ = sig
238
- return wrapper
251
+ # https://github.com/python/typing/issues/598
252
+ func .__signature__ = sig # type: ignore
253
+ return cast (F , wrapper )
239
254
240
255
return decorate
241
256
@@ -279,18 +294,17 @@ def __init__(self, *args, **kwargs):
279
294
280
295
self .params = args or kwargs
281
296
282
- def __call__ (self , func : Callable ) -> Callable :
297
+ def __call__ (self , func : F ) -> F :
283
298
func .__doc__ = func .__doc__ and func .__doc__ % self .params
284
299
return func
285
300
286
301
def update (self , * args , ** kwargs ) -> None :
287
302
"""
288
303
Update self.params with supplied args.
289
-
290
- If called, we assume self.params is a dict.
291
304
"""
292
305
293
- self .params .update (* args , ** kwargs )
306
+ if isinstance (self .params , dict ):
307
+ self .params .update (* args , ** kwargs )
294
308
295
309
296
310
class Appender :
@@ -320,7 +334,7 @@ def __init__(self, addendum: Optional[str], join: str = "", indents: int = 0):
320
334
self .addendum = addendum
321
335
self .join = join
322
336
323
- def __call__ (self , func : Callable ) -> Callable :
337
+ def __call__ (self , func : F ) -> F :
324
338
func .__doc__ = func .__doc__ if func .__doc__ else ""
325
339
self .addendum = self .addendum if self .addendum else ""
326
340
docitems = [func .__doc__ , self .addendum ]
0 commit comments