Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyTest won't inject fixtures into decorated functions in Python 2.7 #2782

Closed
nonsleepr opened this issue Sep 14, 2017 · 7 comments
Closed

PyTest won't inject fixtures into decorated functions in Python 2.7 #2782

nonsleepr opened this issue Sep 14, 2017 · 7 comments
Labels
topic: fixtures anything involving fixtures directly or indirectly type: bug problem that needs to be addressed

Comments

@nonsleepr
Copy link

_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.

@nicoddemus
Copy link
Member

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?

@nonsleepr
Copy link
Author

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.

@nicoddemus nicoddemus added topic: fixtures anything involving fixtures directly or indirectly type: bug problem that needs to be addressed labels Sep 14, 2017
@RonnyPfannschmidt
Copy link
Member

i recall six has a fixed version, also you can just put the __wraps__ attribute there manually

@ghost
Copy link

ghost commented Oct 26, 2017

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?

@RonnyPfannschmidt
Copy link
Member

@kchomski-reef using six is the preferred solution as the guess abut what closure cell to use is potentially incorrect in edge cases

@RonnyPfannschmidt
Copy link
Member

can this be closed as upstream python issue fixed by six?

@Zac-HD
Copy link
Member

Zac-HD commented Oct 21, 2018

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" 🐍🐍🐍

@Zac-HD Zac-HD closed this as completed Oct 21, 2018
EdDev added a commit to EdDev/nmstate that referenced this issue Jun 8, 2019
Link state monitoring is used to detect link state changes while
executing apply changes. In particular, to detect links that change to
anything but UP.

In order to allow simpler usage in selected tests, a decorator is
introduced in addition to the existing context-manager.

Note: six is used to overcome functools.wraps limitations with pytest
(pytest-dev/pytest#2782)

Signed-off-by: Edward Haas <edwardh@redhat.com>
EdDev added a commit to EdDev/nmstate that referenced this issue Jun 8, 2019
Link state monitoring is used to detect link state changes while
executing apply changes. In particular, to detect links that change to
anything but UP.

In order to allow simpler usage in selected tests, a decorator is
introduced in addition to the existing context-manager.

Note: six is used to overcome functools.wraps limitations with pytest
(pytest-dev/pytest#2782)

Signed-off-by: Edward Haas <edwardh@redhat.com>
cathay4t pushed a commit to nmstate/nmstate that referenced this issue Jun 11, 2019
Link state monitoring is used to detect link state changes while
executing apply changes. In particular, to detect links that change to
anything but UP.

In order to allow simpler usage in selected tests, a decorator is
introduced in addition to the existing context-manager.

Note: six is used to overcome functools.wraps limitations with pytest
(pytest-dev/pytest#2782)

Signed-off-by: Edward Haas <edwardh@redhat.com>
Kyle-Verhoog pushed a commit to DataDog/dd-trace-py that referenced this issue Oct 22, 2020
In using snapshot decorator with pytest tests with fixtures, a TypeError error is raised. This is due to a known limitation of functools.wraps with Python 2.7 and pytest: pytest-dev/pytest#2782. This fix uses wrapt.decorator instead.

* fix snapshot decorator for pytest fixtures

* flush before starting snapshot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: fixtures anything involving fixtures directly or indirectly type: bug problem that needs to be addressed
Projects
None yet
Development

No branches or pull requests

4 participants