[RFC] locking decorators and iterators
Andrew Bennetts
andrew at canonical.com
Tue Feb 13 03:44:43 GMT 2007
Robert Collins wrote:
[...]
>
> After a conversation with Andrew about this, I have several things to
> suggest. I think our needs_*_lock decorators should check, and complain,
> if the function they are decorating is a generator. This can be done at
> load time, and should be very fast. The reason is that these decorators
> are ineffective on generators.
"f.func_code.co_code & 0x20" is the test for this (unfortunately there's no
python definition of the CO_GENERATOR constant in inspect.py).
Here's a quick & dirty patch, complete with the warnings it produces just from
running bzr diff to generate it! So there's already some bugs lurking due to
this.
$ ./bzr diff
/home/andrew/code/bzr/bzrlib/decorators.py:127: UserWarning: <function unknowns at 0xb7b30f7c> is a generator
import warnings; warnings.warn("%r is a generator" % unbound)
/home/andrew/code/bzr/bzrlib/decorators.py:127: UserWarning: <function get_deltas_for_revisions at 0xb7343a3c> is a generator
import warnings; warnings.warn("%r is a generator" % unbound)
/home/andrew/code/bzr/bzrlib/decorators.py:127: UserWarning: <function revision_trees at 0xb726810c> is a generator
import warnings; warnings.warn("%r is a generator" % unbound)
Subversion version too old for working tree support.
=== modified file 'bzrlib/decorators.py'
--- bzrlib/decorators.py 2007-01-25 15:54:29 +0000
+++ bzrlib/decorators.py 2007-02-13 03:41:44 +0000
@@ -76,6 +76,8 @@
def branch_method(self, ...):
stuff
"""
+ if unbound.func_code.co_flags & 0x20:
+ import warnings; warnings.warn("%r is a generator" % unbound)
# This compiles a function with a similar name, but wrapped with
# lock_read/unlock calls. We use dynamic creation, because we need the
# internal name of the function to be modified so that --lsprof will see
@@ -121,6 +123,8 @@
def branch_method(self, ...):
stuff
"""
+ if unbound.func_code.co_flags & 0x20:
+ import warnings; warnings.warn("%r is a generator" % unbound)
def read_locked(self, *args, **kwargs):
self.lock_read()
try:
@@ -143,6 +147,8 @@
self.unlock()
write_locked = %(name)s_write_locked
"""
+ if unbound.func_code.co_flags & 0x20:
+ import warnings; warnings.warn("%r is a generator" % unbound)
params, passed_params = _get_parameters(unbound)
variables = {'name':unbound.__name__,
'params':params,
@@ -159,6 +165,8 @@
def _fast_needs_write_lock(unbound):
"""Decorate unbound to take out and release a write lock."""
+ if unbound.func_code.co_flags & 0x20:
+ import warnings; warnings.warn("%r is a generator" % unbound)
def write_locked(self, *args, **kwargs):
self.lock_write()
try:
-Andrew.
More information about the bazaar
mailing list