-
-
Notifications
You must be signed in to change notification settings - Fork 147
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
Fix performance when raising ValueError when used as context-manager #192
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Say, unless I'm missing something, I thought the issue was not really that the user was mocking an object that could be used as a context manager, but rather that mocker.patch
(for example) would be used as a context manager, similar how python's mock module can be used, e.g. given a non-context manager method called some_method()
:
with mock.patch('some_method') as mock_some_method:
# do stuff that invokes `some_method()`
mock_some_method.assert_called()
whereas I understood the idea with mocker
was that this would be disallowed, opting rather for something like:
mock_some_method = mocker.patch('some_method')
# do stuff that invokes `some_method()`
mock_some_method.assert_called()
So I figured we could add a method like this to mocker.patch
and mocker.patch.object
:
def __enter__(self):
raise ValueError("Using mocker ... etc.")
But TBH, I haven't dug all that deep into the code so I may be wrong here.
Thoughts..?
@tomage I think the way it is implemented in this PR is the proper way to override the @nicoddemus the code lgtm. Thanks for getting this together! I tried it out locally just to make sure I could still mock out a context manager alright. |
@tomage the object returned by
Sure! I will add an example to ensure this works as well and we don't regress in the future. |
Actually, @wesleykendall can you post the test you did? I want to make sure we are discussing the same thing. |
@nicoddemus basically what I did was create this:
And then verify that I can patch |
But I am overriding the Can you post the "And then verify that I can patch my_dec without issues" part as well? It is exactly that part I want to see what you expect to work. 😁 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, of course - I forgot that it's the mock
module that makes the patched objects be context managers, not pytest-mock
. So the fix makes good sense!
Barring any issue coming from your and Wes' discussion, I'm good with this patch.
@nicoddemus @tomage this should be safe to merge. I'll try to elaborate on some things since it is difficult to explain in text :) Take the following code
And the following test:
I was originally concerned that this PR would override the However, this test works fine because If it was possible to use the decorator like this (note the missing parens), we would have issues with it hitting the side effect of the mock:
This, however, is invalid and shouldn't happen in practice unless a user has a typo in their code. If a user did have this error in their code, they would inadvertently run into the side effect in this PR and have a confusing message, but I think this is less likely to happen in practice than a user trying to use the mock as a context manager. This was the source of my initial confusion. Happy to elaborate more, but this PR lgtm! |
Thanks again for following up and helping get a fix out for the performance issues. We love using this plugin! |
Thanks, appreciate it! 😁 3.1.1 released. 👍 |
This change broke one of my unit tests and I write scarcely any unit tests so this situation is not that rare. In my case, I am testing that some code acquires a Sample system under test:
Sample test code:
While the documentation about usage as context manager should stay, I suggest not raising the exception at all. One of the main principles of Python is that "we're all consenting adults" so it doesn't make much sense to actively block the context manager usage. |
Hey @iforapsy,
Not sure, I'm into automated tests for more than 15 years and I don't recall once needing to mock
Unfortunately not blocking the context-manager usage results in things not getting un-mocked properly, confused users, and bug reports, so I believe the exception should stay. |
How about changing from raising an exception to a warning, à la |
OK sounds good; a warning should at least give a chance of users to spot the misuse when it happens, and for people really wanting that behavior they can silence the warning in the test which makes use of it by adding a |
Fix #191