4 Some useful decorators.
7 from typing
import Any, Callable
13 log = logging.getLogger(__name__)
15 TFunc = Callable[..., Any]
19 exc_info = sys.exc_info()
20 _exc_class, _exc, tb = exc_info
21 raise new_exc.__class__ (new_exc, tb)
26 This decorator implements the forking patterns, i.e. it runs the function
29 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/511474
31 @functools.wraps(func)
32 def wrapper(*args, **kwargs):
37 pread, pwrite = os.pipe()
45 with os.fdopen(pread,
'rb')
as f:
46 status, result = pickle.load(f)
51 remote_exc = result[0]
58 result = func(*args, **kwargs)
60 except (Exception, KeyboardInterrupt)
as exc:
62 exc_string = traceback.format_exc(limit=10)
63 for l
in exc_string.splitlines():
64 print (
"[%d]"%os.getpid(),l.rstrip())
66 result = exc, exc_string
68 with os.fdopen(pwrite,
'wb')
as f:
70 pickle.dump((status,result), f, pickle.HIGHEST_PROTOCOL)
71 except pickle.PicklingError
as exc:
72 pickle.dump((2,exc), f, pickle.HIGHEST_PROTOCOL)
80 reason: str, *, warn_once_per_call: bool =
True, print_context: bool =
False
81 ) -> Callable[[TFunc], TFunc]:
82 """Decorator to indicate that a function should not be used
87 A string explaining why the function should not be used
88 warn_once_per_call : bool
89 If True, only warn once per call location, default True
91 If True, print the calling context as part of the warning, default False
95 warncache: set[tuple[int, str, int]] =
set()
97 def deprecate_decorator(f):
99 def call_deprecated(*args, **kwargs):
100 """Call a deprecated function"""
104 frame_info = inspect.stack()[1]
105 cache_value =
id(f), frame_info.filename, frame_info.lineno
106 if not warn_once_per_call
or cache_value
not in warncache:
107 if warn_once_per_call:
108 warncache.add(cache_value)
109 log.warning(f
"Calling deprecated function '{f.__qualname__}'")
111 f
"in function {frame_info.function}, file {frame_info.filename}, line {frame_info.lineno}"
114 for idx, line
in enumerate(frame_info.code_context):
115 log.warning(f
"{frame_info.lineno + idx - frame_info.index}\t{line}")
117 return f(*args, **kwargs)
118 return call_deprecated
119 return deprecate_decorator