-
Notifications
You must be signed in to change notification settings - Fork 192
/
Copy pathdecorators.py
91 lines (71 loc) · 2.8 KB
/
decorators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""
Utility decorators
The module variable is_diagnostics_mode can be set to a boolean or callable. It is used to determine
if an exception should be re-raised when the suppression decorator is requested to raise in
diagnostics mode.
"""
import hashlib
from functools import wraps
# module global variable
is_diagnostics_mode = False
# internal functions
def _should_raise(raise_in_diagnostics):
"""
This utitilty method is used in exception suppression decorator to determine if an exception
should be re-raised.
:param raise_in_diagnostics: The boolean value given to the suppression decorator to indicate if
exception should be re-raised in diagnostics mode.
"""
if not raise_in_diagnostics:
return False
if not is_diagnostics_mode:
return False
if isinstance(is_diagnostics_mode, bool) and is_diagnostics_mode:
return True
if hasattr(is_diagnostics_mode, '__call__') and \
is_diagnostics_mode(): # pylint: disable=not-callable
return True
return False
def call_once(factory_func):
""""
When a function is annotated by this decorator, it will be only executed once. The result will
be cached and return for following invocations.
"""
factory_func.executed = False
factory_func.cached_result = None
def _wrapped(*args, **kwargs):
if not factory_func.executed:
factory_func.cached_result = factory_func(*args, **kwargs)
return factory_func.cached_result
return _wrapped
def hash256_result(func):
"""Secure the return string of the annotated function with SHA256 algorithm. If the annotated
function doesn't return string or return None, raise ValueError."""
@wraps(func)
def _decorator(*args, **kwargs):
val = func(*args, **kwargs)
if not val:
raise ValueError('Return value is None')
if not isinstance(val, str):
raise ValueError('Return value is not string')
hash_object = hashlib.sha256(val.encode('utf-8'))
return str(hash_object.hexdigest())
return _decorator
def suppress_all_exceptions(raise_in_diagnostics=False, fallback_return=None):
def _decorator(func):
@wraps(func)
def _wrapped_func(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as ex: # nopa pylint: disable=broad-except
if _should_raise(raise_in_diagnostics):
raise ex
if fallback_return:
return fallback_return
return _wrapped_func
return _decorator
def transfer_doc(source_func):
def _decorator(func):
func.__doc__ = source_func.__doc__
return func
return _decorator