PEP 318: Is chaining decorators even possible?
Ian Bicking
ianb at colorstudy.com
Thu Jun 12 16:17:05 EDT 2003
On Thu, 2003-06-12 at 07:03, Kevin Smith wrote:
> It has been brought up a couple of times in other threads that simply
> chaining descriptors won't work (i.e. classmethod(synchronized(foo))).
> Another possibility was to use subclassing (i.e. type('newtype',(
> classmethod,synchronized,{})(foo)). When I wrote PEP 318, I wasn't sure
> myself if it was possible to chain them, but I figured someone would
> point it out if it wasn't. So my question is, is it even possible to
> chain decorators in a general way? If not, then PEP 318 might have to
> be changed to only allow one decorator. This would definitely reduce
> the amount of discussion since the proposed syntax would be reduced to
> 'def foo(self) as <callable>:'.
The chaining seems to only be a problem with decorators that create
descriptors. I'd imagine synchronized being implemented something like:
def synchronized(lock):
def wrapper(func):
return SynchronizedFunction(func, lock).call
return wrapper
class SynchronizedFunction(object):
def __init__(self, func, lock):
self.func = func
self.lock = lock
def call(self, *args, **kw):
self.lock.acquire()
value = self.func(*args, **kw)
self.lock.release()
return value
A contract system would probably work similarly. It doesn't produce a
descriptor, it just wraps the function call. Of course, "func" can't be
a descriptor, or it would mess things up. Unfortunately this doesn't
really work quite right, as it returns a method object, and not a
function object, and classes have a special case of turning functions
into methods.
So I guess a proper implementation of Synchronized would either have to
use nested scopes (to bind func and lock), or create a descriptor.
Maybe:
def synchronized(lock):
def wrapper(func):
def wrappedfunc(*args, **kw):
lock.acquire()
value = func(*args, **kw)
lock.release()
return value
return wrappedfunc
return wrapper
But objects would certainly be more comfortable, especially for
something more complex like contracts.
Ian
More information about the Python-list
mailing list