Open mbra opened 5 years ago
Mhh, actually just guarding against self._finalizers
being empty won't prevent the hook from being executed completely. Changing the fixtures to use return
will still execute the hook for lower1
and lower2
because upper
registers itself as a finalizer on both, making the check for self._finalizers
pass. :-(
The example below shows that the
pytest_fixture_post_finalizer
hook is executed n+1 times, where n is the number of fixtures depended upon. From a quick look this seems to be caused by the fact that theFixtureDef.finish
method is both registered for every sub-fixture inFixtureDef.execute
(https://github.com/pytest-dev/pytest/blob/702acdba4658ad0a7e732059d18b22b185c79e5c/src/_pytest/fixtures.py#L860) as well as byFixtureRequest._schedule_finalizers
(https://github.com/pytest-dev/pytest/blob/702acdba4658ad0a7e732059d18b22b185c79e5c/src/_pytest/fixtures.py#L577).Since
FixtureDef.finish
clearsself._finalizers
at the end, this does not lead to finalizers being executed multiple times, the hook however is executed in thefinally
clause every time.I did not dig far enough into the code to tell what effect registering
finish
with the fixtures' dependency has. I assume this is probably for a reason and cannot be helped, but it did not feel right to just create a pull request that protects the hook by checkingself._finalizers
first. Even though I do not know what to do about it, the code looks like someone with a little more in depth knowledge might be able to not only fix the bug but cleanup the way the finalizers are registered a little.On the other hand, the hook is currently executed even when no finalizer is registered (I used
yield
in the example butreturn
will produce the exact same result). That might be considered something between a bug and an inconsistency, but perhaps it would be a good idea to checkself._finalizers
before executing the hook no matter what happens to the rest of the code.test.py:
conftest.py: