18
18
__all__ = ['needs_read_lock',
19
19
'needs_write_lock',
20
'use_fast_decorators',
21
'use_pretty_decorators',
22
def needs_read_lock(unbound):
25
def _get_parameters(func):
26
"""Recreate the parameters for a function using introspection.
28
:return: (function_params, calling_params)
29
function_params: is a string representing the parameters of the
30
function. (such as "a, b, c=None, d=1")
31
This is used in the function declaration.
32
calling_params: is another string representing how you would call the
33
function with the correct parameters. (such as "a, b, c=c, d=d")
34
Assuming you sued function_params in the function declaration, this
35
is the parameters to put in the function call.
39
def wrapper(%(function_params)s):
40
return original(%(calling_params)s)
42
# "import inspect" should stay in local scope. 'inspect' takes a long time
43
# to import the first time. And since we don't always need it, don't import
46
args, varargs, varkw, defaults = inspect.getargspec(func)
47
formatted = inspect.formatargspec(args, varargs=varargs,
53
first_default = len(args) - len(defaults)
54
args_passed = args[:first_default]
55
for arg in args[first_default:]:
56
args_passed.append("%s=%s" % (arg, arg))
57
if varargs is not None:
58
args_passed.append('*' + varargs)
60
args_passed.append('**' + varkw)
61
args_passed = ', '.join(args_passed)
63
return formatted[1:-1], args_passed
66
def _pretty_needs_read_lock(unbound):
67
"""Decorate unbound to take out and release a read lock.
69
This decorator can be applied to methods of any class with lock_read() and
76
def branch_method(self, ...):
79
# This compiles a function with a similar name, but wrapped with
80
# lock_read/unlock calls. We use dynamic creation, because we need the
81
# internal name of the function to be modified so that --lsprof will see
83
# TODO: jam 20070111 Modify this template so that the generated function
84
# has the same argument signature as the original function, which
85
# will help commands like epydoc.
86
# This seems possible by introspecting foo.func_defaults, and
87
# foo.func_code.co_argcount and foo.func_code.co_varnames
89
def %(name)s_read_locked(%(params)s):
92
return unbound(%(passed_params)s)
95
read_locked = %(name)s_read_locked
97
params, passed_params = _get_parameters(unbound)
98
variables = {'name':unbound.__name__,
100
'passed_params':passed_params,
102
func_def = template % variables
104
exec func_def in locals()
106
read_locked.__doc__ = unbound.__doc__
107
read_locked.__name__ = unbound.__name__
111
def _fast_needs_read_lock(unbound):
23
112
"""Decorate unbound to take out and release a read lock.
25
114
This decorator can be applied to methods of any class with lock_read() and
43
132
return read_locked
46
def needs_write_lock(unbound):
135
def _pretty_needs_write_lock(unbound):
136
"""Decorate unbound to take out and release a write lock."""
138
def %(name)s_write_locked(%(params)s):
141
return unbound(%(passed_params)s)
144
write_locked = %(name)s_write_locked
146
params, passed_params = _get_parameters(unbound)
147
variables = {'name':unbound.__name__,
149
'passed_params':passed_params,
151
func_def = template % variables
153
exec func_def in locals()
155
write_locked.__doc__ = unbound.__doc__
156
write_locked.__name__ = unbound.__name__
160
def _fast_needs_write_lock(unbound):
47
161
"""Decorate unbound to take out and release a write lock."""
48
162
def write_locked(self, *args, **kwargs):
55
169
write_locked.__name__ = unbound.__name__
56
170
return write_locked
173
# Default is more functionality, 'bzr' the commandline will request fast
175
needs_read_lock = _pretty_needs_read_lock
176
needs_write_lock = _pretty_needs_write_lock
179
def use_fast_decorators():
180
"""Change the default decorators to be fast loading ones.
182
The alternative is to have decorators that do more work to produce
183
nice-looking decorated functions, but this slows startup time.
185
global needs_read_lock, needs_write_lock
186
needs_read_lock = _fast_needs_read_lock
187
needs_write_lock = _fast_needs_write_lock
190
def use_pretty_decorators():
191
"""Change the default decorators to be pretty ones."""
192
global needs_read_lock, needs_write_lock
193
needs_read_lock = _pretty_needs_read_lock
194
needs_write_lock = _pretty_needs_write_lock