_pytest.compat.get_real_func doesn't work as expected in Python 2.7:
Example:
from _pytest.compat import get_real_func
import functools
def my_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwds):
print('Calling decorated function')
return f(*args, **kwds)
return wrapper
#@my_decorator
def example():
"""Docstring"""
print('Called example function')
decorated_example = my_decorator(example)
if get_real_func(decorated_example) is example:
print('get_real_func works')
else:
print('get_real_func fails')
Python 3.5 output:
$ python3.5 test.py
get_real_func works
Python 2.7 output:
$ python2.7 test.py
get_real_func fails
Tested with PyTest 3.0.6 though the same idea (isinstance(obj, functools.partial)) is attempted in master.
I believe this is because of a limitation in Python 2's functools.wrap, I recall a discussion about this recently but can't find it at the moment. Perhaps @RonnyPfannschmidt can point to that discussion?
Well, yes, functools.wraps won't leave any metadata in Python 2. But the testing the decorated function for inheritance from functools.partial is wrong. While isinstance(functools.wraps(f), functools.partial) == True for most Python versions, the partial function would be executed and another function would be produced, thus losing the inheritance. So, it's better to give up completely in py2 or do some magic with code inspection maybe.
i recall six has a fixed version, also you can just put the __wraps__ attribute there manually
It can by solved by either using wraps from six module or by getting wrapped function from obj.__closure__[0].cell_contents in get_real_func function.
What is the preferred general solution to this?
@kchomski-reef using six is the preferred solution as the guess abut what closure cell to use is potentially incorrect in edge cases
can this be closed as upstream python issue fixed by six?
can this be closed as upstream python issue fixed by six?
There's nothing we can reliably do about this otherwise, so I'm happy to close as "Use six or upgrade to Python3" :snake::snake::snake: