fix(pytest): stop reporting pytest's own finalizer as a phantom teardown - #921
Open
Mohanad49 wants to merge 1 commit into
Open
Conversation
From pytest 9.1, FixtureDef.execute attaches an internal finalizer to every fixture. The listener wrapped it along with the real ones, producing a <fixture>::<lambda> afterStage that pytest never invokes through the wrapper - so it was written out with no status and rendered as 'unknown', once per fixture, in every report. Finalizers owned by _pytest are now skipped. The check is on the owning module rather than on the name, because a lambda passed to request.addfinalizer by a test author is a real teardown and must still be reported. Two tests: one fails without the fix, and one guards against the fix being too aggressive by asserting a user's own lambda finalizer is still reported.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Closes #918.
From pytest 9.1,
FixtureDef.executeattaches an internal finalizer to every fixture.pytest_fixture_setupwrapped it along with the real ones, so every fixture produced an extra afterStage:pytest never calls that finalizer through Allure's wrapper, so nothing ever closes the stage and it is written out with no status — which the report renders as
unknown, once per fixture, on every run.Confirmed as
FixtureDef.execute.<locals>.<lambda>, owned by_pytest.fixtures:The fix
Skip finalizers owned by
_pytest.The check is on the owning module, not on the name. Filtering
<lambda>would have been shorter and wrong: a lambda passed torequest.addfinalizerby a test author is a real teardown and has to keep being reported. Thefunctools.partialthat implements yield-fixture teardown is likewise untouched, sosimple_fixture::1still appears.Testing
tests/allure_pytest— 273 passed, 2 xfailed (271 before, plus the two added here).ruffclean.The two tests do different jobs, deliberately:
test_pytest_internal_finalizer_is_not_reportedtest_user_lambda_finalizer_is_still_reportedThe first is the regression test — I checked it fails on unpatched
main, otherwise it would be asserting nothing. The second passes either way on purpose: it guards the fix against becoming too aggressive, and would start failing if someone later narrowed the filter to the name.I ran the existing suite on unpatched
maintoo — 271 passed there as well, so nothing currently covers this, which is presumably how it shipped.Verified against pytest 9.1.1 / Python 3.11. The filter is a no-op on older pytest, which has no such finalizer.