(fixtures): Replace fixture represenation with a class#12473
(fixtures): Replace fixture represenation with a class#12473nicoddemus merged 53 commits intopytest-dev:mainfrom
Conversation
bf90fca to
d25a8d9
Compare
3d2ec33 to
84cc5b7
Compare
|
Hey @The-Compiler @RonnyPfannschmidt I rebased the PR could you please take a look? |
testing/code/test_source.py
Outdated
|
|
||
| src = inspect.getsource(deco_fixture) | ||
| # Since deco_fixture is now an instance of FixtureFunctionDef the getsource function will not work on it. | ||
| with pytest.raises(Exception): |
There was a problem hiding this comment.
Could you assert against a more specific exception? As I understand, this is not testing that something went wrong but it's not clear what exactly. Also, it's usually a good idea to use the match= regex with this helper.
There was a problem hiding this comment.
Yes will apply. This tries to document the behavior more than testing anything. Before introducing the FixtureFunctionDefinition it was possible to run inspect.getsource on fixtures but now it's not. This is just describing the behavior. I'm open to removing it as well.
There was a problem hiding this comment.
I changed it to a more specific error. Do you think we can remove the test? This just tests that you cannot use inspect on fixture functions.
There was a problem hiding this comment.
I think we can remove this test. I removed it.
f0324a5 to
9d2a916
Compare
|
Hey @Glyphack, could you resolve the merge conflicts / rebase this? |
Yes will do today. |
641a3a1 to
bc0a0e5
Compare
RonnyPfannschmidt
left a comment
There was a problem hiding this comment.
Iove where this is going
It opens up nice follow ups
src/_pytest/compat.py
Outdated
| """Get the real function object of the (possibly) wrapped object by | ||
| functools.wraps or functools.partial.""" | ||
| :func:`functools.wraps`, or :func:`functools.partial`, or :func:`pytest.fixture`.""" | ||
| from _pytest.fixtures import FixtureFunctionDefinition |
There was a problem hiding this comment.
I believe we can drop fixture definition from that , we should pass the definitions attribute
There was a problem hiding this comment.
Are you suggesting to pass the FixtureFunctionDefinition object to this function? If I understand correctly this function is expected to take any object and return the real object according to this test testing the behavior:
https://github.com/Glyphack/pytest/blob/3d7416c2dd5dcf2d60a8b30636dcc90978c64215/testing/test_compat.py#L63
There was a problem hiding this comment.
As fixture definitions are no longer wrapping functions into other functions
The suggestion is to no longer consider them wrappers and passing the function directly
There was a problem hiding this comment.
@RonnyPfannschmidt Sorry I didn't fully understand your comment.
The current unwrapping behavior here is only for two cases:
- The pytest fixture is applied on a function so I can display this case with Fixture(f)
- The pytest fixture is decorated so we have deco(Fixture(f))
The first case is handled by obj = obj._get_wrapped_function() line and second case is handled by obj = inspect.unwrap(obj, stop=lambda x: type(x) is FixtureFunctionDefinition).
If we drop any of them we cannot handle one of those two cases.
But I feel I am missing your point but unwrapping to me are these two lines.
There was a problem hiding this comment.
Decorators cannot apply to a fixture definition
So that should trigger a error
It's wrong even now
There was a problem hiding this comment.
I was wrong about that but the behavior is still needed. For example this test fails if we don't do unwrapping in this function:
https://github.com/Glyphack/pytest/blob/a6318c944f907bc350922c3961365e9ecd8d3e81/testing/python/integration.py#L11
The reason is that getfslineno is using this function to unwrap a decorator:
https://github.com/Glyphack/pytest/blob/a6318c944f907bc350922c3961365e9ecd8d3e81/src/_pytest/_code/code.py#L1341
I think the solution is to make a separate function for the cases when we want to perform the unwrapping? What is your suggestion?
There was a problem hiding this comment.
What I meant is that we no longer ought to pass fixture definition to anything that unwrapped
Definition is no longer a function
Perhaps we should drop the call altogether
There was a problem hiding this comment.
Thanks I realized the reason my code required this check to be here was that I was getting objects using the fixture name instead of their actual name and mistakenly I calling this on non fixture objects. After fixing that I could remove the get_real_method and simplify this function.
|
Thank you both for the review. I left some TODO comments I will address them in a follow up PR. |
Ah sorry for the assumption. The reason I thought it would be better to combine is that merging as-is would introduce a typing regression (fixture functions would lose their signature). But it's only temporary so not a problem. |
* Carry around parameters and return value in `FixtureFunctionDefinition`. * Add `FixtureParams` to `FixtureDef`. Follow up to pytest-dev#12473.
* Carry around parameters and return value in `FixtureFunctionDefinition`. * Add `FixtureParams` to `FixtureDef`. Follow up to pytest-dev#12473.
|
FYI, this breaks pytest-factoryboy, but that's something I have to deal with. That being said, |
pytest-8.4.0 removed the __pytest_wrapped__ atribute on a fixture object, instead of unwrapping the object, it now keeps __wrapped__ that we can use instead. This commit makes sure we can work with both old and new pytest. See: pytest-dev/pytest#12473
pytest-8.4.0 removed the __pytest_wrapped__ atribute on a fixture object, instead of unwrapping the object, it now keeps __wrapped__ that we can use instead. This commit makes sure we can work with both old and new pytest. See: pytest-dev/pytest#12473
pytest-8.4.0 removed the __pytest_wrapped__ atribute on a fixture object, instead of unwrapping the object, it now keeps __wrapped__ that we can use instead. This commit makes sure we can work with both old and new pytest. See: pytest-dev/pytest#12473
Reference: pytest-dev/pytest#12473 Caused-by: smarie/python-pytest-cases#364
Reference: pytest-dev/pytest#12473 Caused-by: smarie/python-pytest-cases#364
pytest-dev/pytest#12473 removed `_pytestfixturefunction`. The `getfixturemarker` function is still private, but has existed across all pytest versions that we support. Fixes: bitprophet#33
Closes #11525
During the sprint we discussed fixing the above issue and thought maybe it's a better idea to add a better represenation to fixtures. To do this without patching the object more, this PR refactors fixtures to have a class with attributes.
The main rational behind that is:
Example
Previously we had:
where fixt is a pytest fixture function that is not replaced by it's value(directly used)
Now we print: