Revision a25d0a5e
b/commissioning/highlevel/util.py | ||
---|---|---|
1 |
import sys |
|
1 | 2 |
from commissioning.clients.http import HTTP_API_Client |
2 | 3 |
from commissioning import QuotaholderAPI |
3 | 4 |
|
... | ... | |
10 | 11 |
|
11 | 12 |
return QuotaholderHTTP(QH_URL) |
12 | 13 |
|
14 |
def method_accepts(*types): |
|
15 |
'''Method decorator. Checks decorated function's arguments are |
|
16 |
of the expected types. The self argument is ignored. This is |
|
17 |
based on the ``accepts`` decorator. |
|
18 |
|
|
19 |
Parameters: |
|
20 |
types -- The expected types of the inputs to the decorated function. |
|
21 |
Must specify type for each parameter. |
|
22 |
''' |
|
23 |
try: |
|
24 |
def decorator(f): |
|
25 |
def newf(*args): |
|
26 |
args_to_check = args[1:] # Throw away self (or cls) |
|
27 |
assert len(args_to_check) == len(types) |
|
28 |
argtypes = tuple(map(type, args_to_check)) |
|
29 |
if argtypes != types: |
|
30 |
msg = info(f.__name__, types, argtypes, 0) |
|
31 |
raise TypeError, msg |
|
32 |
return f(*args) |
|
33 |
newf.__name__ = f.__name__ |
|
34 |
return newf |
|
35 |
return decorator |
|
36 |
except KeyError, key: |
|
37 |
raise KeyError, key + "is not a valid keyword argument" |
|
38 |
except TypeError, msg: |
|
39 |
raise TypeError, msg |
|
40 |
|
|
41 |
# http://wiki.python.org/moin/PythonDecoratorLibrary#Type_Enforcement_.28accepts.2Freturns.29 |
|
42 |
# Slightly modified to always raise an error |
|
43 |
def accepts(*types): |
|
44 |
'''Function decorator. Checks decorated function's arguments are |
|
45 |
of the expected types. |
|
46 |
|
|
47 |
Parameters: |
|
48 |
types -- The expected types of the inputs to the decorated function. |
|
49 |
Must specify type for each parameter. |
|
50 |
''' |
|
51 |
try: |
|
52 |
def decorator(f): |
|
53 |
def newf(*args): |
|
54 |
assert len(args) == len(types) |
|
55 |
argtypes = tuple(map(type, args)) |
|
56 |
if argtypes != types: |
|
57 |
msg = info(f.__name__, types, argtypes, 0) |
|
58 |
raise TypeError, msg |
|
59 |
return f(*args) |
|
60 |
newf.__name__ = f.__name__ |
|
61 |
return newf |
|
62 |
return decorator |
|
63 |
except KeyError, key: |
|
64 |
raise KeyError, key + "is not a valid keyword argument" |
|
65 |
except TypeError, msg: |
|
66 |
raise TypeError, msg |
|
67 |
|
|
68 |
# http://wiki.python.org/moin/PythonDecoratorLibrary#Type_Enforcement_.28accepts.2Freturns.29 |
|
69 |
# Slightly modified to always raise an error |
|
70 |
def returns(ret_type): |
|
71 |
'''Function decorator. Checks decorated function's return value |
|
72 |
is of the expected type. |
|
73 |
|
|
74 |
Parameters: |
|
75 |
ret_type -- The expected type of the decorated function's return value. |
|
76 |
Must specify type for each parameter. |
|
77 |
''' |
|
78 |
try: |
|
79 |
def decorator(f): |
|
80 |
def newf(*args): |
|
81 |
result = f(*args) |
|
82 |
res_type = type(result) |
|
83 |
if res_type != ret_type: |
|
84 |
msg = info(f.__name__, (ret_type,), (res_type,), 1) |
|
85 |
raise TypeError, msg |
|
86 |
return result |
|
87 |
newf.__name__ = f.__name__ |
|
88 |
return newf |
|
89 |
return decorator |
|
90 |
except KeyError, key: |
|
91 |
raise KeyError, key + "is not a valid keyword argument" |
|
92 |
except TypeError, msg: |
|
93 |
raise TypeError, msg |
|
94 |
|
|
95 |
# http://wiki.python.org/moin/PythonDecoratorLibrary#Type_Enforcement_.28accepts.2Freturns.29 |
|
96 |
def info(fname, expected, actual, flag): |
|
97 |
'''Convenience function returns nicely formatted error/warning msg.''' |
|
98 |
format = lambda types: ', '.join([str(t).split("'")[1] for t in types]) |
|
99 |
expected, actual = format(expected), format(actual) |
|
100 |
msg = "'{}' method ".format( fname )\ |
|
101 |
+ ("accepts", "returns")[flag] + " ({}), but ".format(expected)\ |
|
102 |
+ ("was given", "result is")[flag] + " ({})".format(actual) |
|
103 |
return msg |
|
104 |
|
|
13 | 105 |
def check_string(name, value): |
14 | 106 |
assert isinstance(value, str), "%s is not a string, but a %s" % (name, type(value)) |
15 | 107 |
return value |
Also available in: Unified diff