[Python-ideas] make __closure__ writable

Mark Shannon mark at hotpy.org
Tue Mar 20 15:43:06 CET 2012

Yury Selivanov wrote:
> I did provide such example earlier in this thread.  I'm copying and
> pasting it to this mail.  Please read the example carefully, as it
> explains why returning new types.FunctionType() is not enough.
> ----
> Yes, your approach will work if your decorator is the only one applied.
> But, as I said, if you have many of them (see below), you can't just
> return a new function out of your decorator, you need to change the
> underlying "in-place".  Consider the following:
> def modifier(func):
>  orig_func = func
>  while func.__wrapped__:
>    func = func.__wrapped__
>  # patch func.__code__ and func.__closure__
>  return orig_func # no need to wrap anything
> def some_decorator(func):
>  def wrapper(*args, **kwargs):
>      # some code
>      return func(*args, **kwargs)
>  functools.wraps(wrapper, func)
>  return wrapper
> @modifier
> @some_decorator
> def foo():
>  # this code needs to be verified/augmented/etc
> So, in the above snippet, if you don't want to discard the
> @some_decorator by returning a new function object, you need to modify 
> the 'foo' from the @modifier.
> In a complex framework, where you can't guarantee that your magic
> decorator will always be called first, rewriting the __closure__ 
> attribute is the only way.  

So why won't this work?

def f_with_new_closure(f, closure):
     return types.FunctionType(f.__code__,

def modifier(func, closure):
     if func.__wrapped__:
	while func.__wrapped__.__wrapped__:
  	    func = func.__wrapped__
	func.__wrapped__ = f_with_new_closure(func.__wrapped__,
         return f_with_new_closure(func, closure)
     if func.__wrapped__:
	return f_with_new_closure(func,
	return f_with_new_closure(func, closure)


More information about the Python-ideas mailing list