Created
January 11, 2012 20:14
-
-
Save voldmar/1596545 to your computer and use it in GitHub Desktop.
nested_getattr — getattr for inner functions in decorators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
from functools import wraps | |
def decorator_wraps(f): | |
@wraps(f) | |
def inner(*args, **kwargs): | |
return f(*args, **kwargs) | |
inner.test = 'ok' | |
return inner | |
def outer_decorator_wraps(f): | |
@wraps(f) | |
def inner(*args, **kwargs): | |
return f(*args, **kwargs) | |
return inner | |
def decorator_non_wraps(f): | |
def inner(*args, **kwargs): | |
return f(*args, **kwargs) | |
inner.test = 'ok' | |
return inner | |
def outer_decorator_non_wraps(f): | |
def inner(*args, **kwargs): | |
return f(*args, **kwargs) | |
return inner | |
@outer_decorator_wraps | |
@outer_decorator_wraps | |
@decorator_wraps | |
def func_wraps(*args, **kwargs): | |
pass | |
@outer_decorator_non_wraps | |
@outer_decorator_non_wraps | |
@decorator_non_wraps | |
def func_non_wraps(*args, **kwargs): | |
pass | |
def nested_getattr(func, name, *args): | |
'''Get attr for nested functions''' | |
if len(args) > 1: | |
raise TypeError('nested_getattr expected at most 3 arguments, got {0}'.format(2 + len(args))) | |
nested = func | |
while 1: | |
if hasattr(nested, name): | |
return getattr(nested, name) | |
if getattr(nested, 'func_closure', None) is None: | |
if args: | |
return args[0] | |
raise AttributeError(name) | |
nested = nested.func_closure[0].cell_contents | |
def test_not_fail_wraps(): | |
assert getattr(func_wraps, 'test') == 'ok' | |
def test_ok_wraps(): | |
assert nested_getattr(func_wraps, 'test') == 'ok' | |
def test_fail_non_wraps(): | |
assert not hasattr(func_non_wraps, 'test') | |
def test_ok_non_wraps(): | |
assert nested_getattr(func_non_wraps, 'test') == 'ok' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment