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
requests-mock decorator not recognised in Python 3 #2749
Comments
based on http://bazaar.launchpad.net/~jamielennox/requests-mock/master/view/head:/requests_mock/mocker.py#L210 its not directly possible to figure this from pytest - requests-mocker itself kills it the difference between py2 and py3 is that on python2 functools.wraps is simply completely broken this also means that pytest cant even hope to fix it without requests-mocker providing metadata i'm inclined to either close this or mark it as upstream being too broken to fix this sanely |
@RonnyPfannschmidt thanks for your quick reply, I've opened https://bugs.launchpad.net/requests-mock/+bug/1714756 for upstream. |
thanks for the followup - it may be necessary to work a bit together to handle it similar to https://github.com/pytest-dev/pytest/blob/master/_pytest/compat.py#L86 however as requests-mock is not part of the stdlib/as well used, it may work out better if it provided a pytest fixture instead as far as i understood its internal api is very suitable for that kind of approach and integration with pytest would be more clean also |
Hi, so i'll admit i'm not a big fan of the class decorator approach in general, but it was contributed to emulate an existing pattern so I see the benefit in having it there. I know some of the problems of wraps() but have never really used pytest to know what it is doing here. If anything I was under the impression this was better in python3, not worse. So I can dive into this because I certainly would like requests-mock to work with pytest (and thought it did), but if can you short circuit that for me and tell me what metadata is required that would be faster. On that though I completely agree with @RonnyPfannschmidt my preferred use of requests-mock is via the requests_mock/contrib/fixture.py fixture for the testing-cabal/fixtures library. I'd happily add a pytest equivalent of that to contrib/ to make it work in a pytest native way, I just don't know what that looks like. |
@jamielennox the "problem" here is that wraps is better on python3 - so py.test is able to see the actual function with actual parameters instead of the wrapper function only since there is no declared signature mechanism to understand the arguments added by the decorators, its not handle-able for mock as in the stdlib we hook into its own metadata which sets up a list of patchings so we can make a reasonable cut-off |
Ok, understood - in python 3 you can see the mocked_obj parameter where it wasn't introspectable on python 2. Just to understood i caught that right about the signature mechanism - you're saying that pytest has no way to mark that a parameter is just a parameter and not a reference to a fixture? I'd happily add it as like a function attribute or to a docstring or something that won't get in the way of any other suite. In which case really the only option may be the pytest specific fixture as any of the current mockers that pass the mocker as a parameter are not going to work in pytest. Is there an existing example of how a third party would provide this fixture in a reasonable way. I can see the basics, but there's a whole lot of parameters and location hierarchy (newbie) that makes fixtures seem like something projects should define individually. |
the most easy way wouldbe for you to provide either a manually addable or a automatically loaded pytest plugin all that would have to do is declare a pytest fixture then it would be available either automatically or by requesting a |
I have the same problem as originally reported in this issue. I have no problem switching from the decorator approach (shown in the example in the original post) to an explicit pytest.fixture in my test program, but I don't know how that would be done with requests_mock (the example in its - very short- chapter about fixtures seems to only work with testtools). How can I use pytest with requests_mock today? |
Hey, sorry for the delay, i've been on a beach :). So the fixtures doc is specifically about the fixtures module: https://pypi.python.org/pypi/fixtures - this is unfortunately very generically named, but what i was working with a lot at the time. The problem I'm having here is not can requests_mock and pytest integrate, but I don't know enough about pytest to know how to do this in a useful repeatable way that is worth including into the library. Here's the simplest thing i can see to combine the two: https://gist.github.com/jamielennox/d996d818eb98c5f38a8e0eb3b7376bd7 |
@jamielennox I forked your gist to show how to take advantage of pytest's support for fixtures that yield, which solves the problem of proper teardown. This lets you use the existing requests_mock.Mocker context manager like so:
You can then use this fixture with other pytest fixtures in test cases like:
https://gist.github.com/mykwillis/3785c8f92e600abf9a33b46568206b10 |
that's pretty cool and definitely better looking, thanks. I guess where we get to with this thread though is still: is there a way i can/should ship that snippet requests_mock or do i just document it for people? The existing example of this is using fixtures you can and then
Having not used pytest, i read through docs and can't tell if it's even possible to have fixtures in external modules, or what the scopes should be. But that yield based snippet is so simple maybe the best thing is to just include it in the documentation? |
Perhaps
Definitely, that's what plugins do. 😁 Basically you need to define that setup(
...
# the following makes a plugin available to pytest
entry_points = {
'pytest11': [
'requests_mock = requests_mock.pytest_plugin',
]
},
) And that's it. pytest users installing See more info at writing plugins. |
Is it possible add a note about this kind of issue in an FAQ? Not every project will be able to convert to fixtures, so some guidance would be great. In my case, I'm converting StackInABox (https://pypi.python.org/pypi/stackinabox) from using The work-around works for me, but it'd be great to give it some visibility for those in my situation - especially once this issue is closed out. $0.02 |
with recent pytest you should be able to use signature objects via funcsigs/funcsigs2 |
Meanwhile @jamielennox, any news on making that fixture available? |
If someone can test jamielennox/requests-mock#51 for me i'll merge it soon and do a new release. I'll try and add some local tests tomorrow, but they won't really merge with the existing ones. |
I tested in jamielennox/requests-mock#51 (comment) and it is working fine, nice job! 👍 |
The fixture 'requests_mock' is not available on py3, as per [0]. 'requests_mock' fixture, on the other hand is, and is injected into the pytest framework through a plugin. [0] - pytest-dev/pytest#2749 Bug-Url: https://bugzilla.redhat.com/1641353 Change-Id: I53311c8a569edf7be201ba512c199ab8ef018d61 Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com>
Error
When running the following code with
pytest
, it passes on Python 2.7 but fails on Python 3.6 withE fixture 'mocked_obj' not found
:It seems to me that pytest is not recognising the
mocked_obj
parameter as the one already passed by the decorator hence looks for a fixture with that name and fail.I'm unsure if the different behaviour between Python 2 and Python 3 is in pytest or mock-requests modules (or both). If you are confident that it is not related to pytest let me know and I'll open the issue for the mock-requests project.
Workaround
If I change the function/method signatures replacing
mocked_obj
with*args
it works as expected: theargs
tuple has only one element and is an instance ofrequests_mock.mocker.Mocker
.Test enviroments
pip freeze
is identical for both virtualenvs:The text was updated successfully, but these errors were encountered: