-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
python: fix instance handling in static and class method tests #12096
Conversation
No longer does unittest stuff. Also the rest of the sentence is not really necessary for a docstring.
No need to compute the property multiple times.
and also fixes a regression in pytest 8.0.0 where `setup_method` crashes if the class has static or class method tests. It is allowed to have a test class with static/class methods which request non-static/class method fixtures (including `setup_method` xunit-fixture). I take it as a given that we need to support this somewhat odd scenario (stdlib unittest also supports it). This raises a question -- when a staticmethod test requests a bound fixture, what is that fixture's `self`? stdlib unittest says - a fresh instance for the test. Previously, pytest said - some instance that is shared by all static/class methods. This is definitely broken since it breaks test isolation. Change pytest to behave like stdlib unittest here. In practice, this means stopping to rely on `self.obj.__self__` to get to the instance from the test function's binding. This doesn't work because staticmethods are not bound to anything. Instead, keep the instance explicitly and use that. BTW, I think this will allow us to change `Class`'s fixture collection (`parsefactories`) to happen on the class itself instead of a class instance, allowing us to avoid one class instantiation. But needs more work. Fixes pytest-dev#12065.
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.
Great work!
assert isinstance(items[1], Function) | ||
assert items[1].name == "test_method" | ||
assert items[1].instance is not None | ||
assert items[1].instance.__class__.__name__ == "TestIt" | ||
|
||
# Even class and static methods get an instance! |
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.
I guess it is possible for this to break some plugin which is using instance
to check if the method is a static/classmethod, but I suppose this is far fetched.
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.
You prompted me to check how plugins use instance
. Overall it's almost not used, the only prominent case I found is pytest-asyncio, whose usage is not problematic if I'm reading correctly and according to its tests.
pytest-asyncio however was broken by yesterday's removal of FixtureDef.unittest
(#12089), for which I will send them a fix.
and also fixes a regression in pytest 8.0.0 where
setup_method
crashes if the class has static or class method tests.It is allowed to have a test class with static/class methods which request non-static/class method fixtures (including
setup_method
xunit-fixture). I take it as a given that we need to support this somewhat odd scenario (stdlib unittest also supports it).This raises a question -- when a staticmethod test requests a bound fixture, what is that fixture's
self
?stdlib unittest says - a fresh instance for the test.
Previously, pytest said - some instance that is shared by all static/class methods. This is definitely broken since it breaks test isolation.
Change pytest to behave like stdlib unittest here.
In practice, this means stopping to rely on
self.obj.__self__
to get to the instance from the test function's binding. This doesn't work because staticmethods are not bound to anything.Instead, keep the instance explicitly and use that.
BTW, I think this will allow us to change
Class
's fixture collection (parsefactories
) to happen on the class itself instead of a class instance, allowing us to avoid one class instantiation. But needs more work.Fixes #12065.