11from functools import wraps
22import inspect
33from 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+ )
516import warnings
617
718from pandas ._libs .properties import cache_readonly # noqa
819
20+ FuncType = Callable [..., Any ]
21+ F = TypeVar ("F" , bound = FuncType )
22+
923
1024def deprecate (
1125 name : str ,
12- alternative : Callable ,
26+ alternative : Callable [..., Any ] ,
1327 version : str ,
1428 alt_name : Optional [str ] = None ,
1529 klass : Optional [Type [Warning ]] = None ,
1630 stacklevel : int = 2 ,
1731 msg : Optional [str ] = None ,
18- ) -> Callable :
32+ ) -> Callable [..., Any ] :
1933 """
2034 Return a new function that emits a deprecation warning on use.
2135
@@ -47,7 +61,7 @@ def deprecate(
4761 warning_msg = msg or "{} is deprecated, use {} instead" .format (name , alt_name )
4862
4963 @wraps (alternative )
50- def wrapper (* args , ** kwargs ):
64+ def wrapper (* args , ** kwargs ) -> Callable [..., Any ] :
5165 warnings .warn (warning_msg , klass , stacklevel = stacklevel )
5266 return alternative (* args , ** kwargs )
5367
@@ -90,9 +104,9 @@ def wrapper(*args, **kwargs):
90104def deprecate_kwarg (
91105 old_arg_name : str ,
92106 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 ,
94108 stacklevel : int = 2 ,
95- ) -> Callable :
109+ ) -> Callable [..., Any ] :
96110 """
97111 Decorator to deprecate a keyword argument of a function.
98112
@@ -160,27 +174,27 @@ def deprecate_kwarg(
160174 "mapping from old to new argument values " "must be dict or callable!"
161175 )
162176
163- def _deprecate_kwarg (func ) :
177+ def _deprecate_kwarg (func : F ) -> F :
164178 @wraps (func )
165- def wrapper (* args , ** kwargs ):
179+ def wrapper (* args , ** kwargs ) -> Callable [..., Any ] :
166180 old_arg_value = kwargs .pop (old_arg_name , None )
167181
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-
178182 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 ):
183195 new_arg_value = mapping (old_arg_value )
196+ else :
197+ new_arg_value = mapping .get (old_arg_value , old_arg_value )
184198 msg = (
185199 "the {old_name}={old_val!r} keyword is deprecated, "
186200 "use {new_name}={new_val!r} instead"
@@ -198,7 +212,7 @@ def wrapper(*args, **kwargs):
198212 ).format (old_name = old_arg_name , new_name = new_arg_name )
199213
200214 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 :
202216 msg = (
203217 "Can only specify '{old_name}' or '{new_name}', " "not both"
204218 ).format (old_name = old_arg_name , new_name = new_arg_name )
@@ -207,17 +221,17 @@ def wrapper(*args, **kwargs):
207221 kwargs [new_arg_name ] = new_arg_value
208222 return func (* args , ** kwargs )
209223
210- return wrapper
224+ return cast ( F , wrapper )
211225
212226 return _deprecate_kwarg
213227
214228
215229def rewrite_axis_style_signature (
216230 name : str , extra_params : List [Tuple [str , Any ]]
217- ) -> Callable :
218- def decorate (func ) :
231+ ) -> Callable [..., Any ] :
232+ def decorate (func : F ) -> F :
219233 @wraps (func )
220- def wrapper (* args , ** kwargs ):
234+ def wrapper (* args , ** kwargs ) -> Callable [..., Any ] :
221235 return func (* args , ** kwargs )
222236
223237 kind = inspect .Parameter .POSITIONAL_OR_KEYWORD
@@ -234,8 +248,9 @@ def wrapper(*args, **kwargs):
234248
235249 sig = inspect .Signature (params )
236250
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 )
239254
240255 return decorate
241256
@@ -279,18 +294,17 @@ def __init__(self, *args, **kwargs):
279294
280295 self .params = args or kwargs
281296
282- def __call__ (self , func : Callable ) -> Callable :
297+ def __call__ (self , func : F ) -> F :
283298 func .__doc__ = func .__doc__ and func .__doc__ % self .params
284299 return func
285300
286301 def update (self , * args , ** kwargs ) -> None :
287302 """
288303 Update self.params with supplied args.
289-
290- If called, we assume self.params is a dict.
291304 """
292305
293- self .params .update (* args , ** kwargs )
306+ if isinstance (self .params , dict ):
307+ self .params .update (* args , ** kwargs )
294308
295309
296310class Appender :
@@ -320,7 +334,7 @@ def __init__(self, addendum: Optional[str], join: str = "", indents: int = 0):
320334 self .addendum = addendum
321335 self .join = join
322336
323- def __call__ (self , func : Callable ) -> Callable :
337+ def __call__ (self , func : F ) -> F :
324338 func .__doc__ = func .__doc__ if func .__doc__ else ""
325339 self .addendum = self .addendum if self .addendum else ""
326340 docitems = [func .__doc__ , self .addendum ]
0 commit comments