15

In conftest (in an autouse fixture):

monkeypatch.setattr('collector.util.download_data', lambda url:"Winning" )

In collector/util.py:

def download_data(url):
    assert False

In the_caller.py:

from collector.util import download_data
def some_function():
    download_data("blah")

When I call some_function(), I get the assert. However, if I change the_caller.py to:

import collector
def some_function():
    collector.util.download_data("blah")

then I get "Winning".

Why is this behaving differently, and how can I make the monkeypatch work for both scenarios?

1

1 Answer 1

17

In general, it seems that the issue relates to how imports work in python. I'm not sure that there is a good solution.

The best work-around that I have found so far is the following:

monkeypatch.setattr('collector.util.download_data.__code__', replacement_function.__code__)

This works with both import types. One limitation is that this doesn't work with closures.


This functionality can be added to the framework via:

from _pytest.monkeypatch import monkeypatch

monkeypatch.setcode = lambda self, func_str, replacement_func: \
    monkeypatch.setattr(self, func_str + ".__code__", replacement_func.__code__)

Reference: https://mail.python.org/pipermail/pytest-dev/2013-October/002386.html

Sign up to request clarification or add additional context in comments.

4 Comments

I think it's worth to note that that code up there is monkeypatching a monkeypatch library.
See the unittest docs for a good explanation of this.
Wow, I was deeply lost in an unpleasant monkeypatching rabbit hole, and this is the only thing that works. Unfortunately, understanding why (it works) will need to wait for another day..
It turned out to be the only viable way to make monkeypatch work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.