-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Update fixtures.rst w/ finalizer order #10171
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
Changes from 10 commits
689176f
d5edb31
84d8996
5b3e2d9
9ee20ef
b5bdd52
22c5394
803c536
b61b613
059447c
fd31633
914ad2e
7aa6273
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -735,8 +735,78 @@ does offer some nuances for when you're in a pinch. | |
| .. code-block:: pytest | ||
|
|
||
| $ pytest -q test_emaillib.py | ||
| . [100%] | ||
| 1 passed in 0.12s | ||
| . [100%] | ||
| 1 passed in 0.12s | ||
|
|
||
| Note on finalizer order | ||
| """""""""""""""""""""""" | ||
|
|
||
| Finalizers are executed in a first-in-last-out order, while operations after yield are executed sequentially. | ||
| Consider the differences in the following examples: | ||
|
|
||
aizpurua23a marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .. regendoc:wipe | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import pytest | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def test_bar(fix_w_yield1, fix_w_yield2): | ||
| print("test_bar") | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def fix_w_yield1(): | ||
| yield | ||
| print("after_yield_1") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a good example I think, because of course both prints will be executed sequentially (pytest cannot mess with how Python executes code within a function). I suggest we use two fixtures: @pytest.fixture
def fix_w_yield1():
yield
print("after_yield_1")
@pytest.fixture
def fix_w_yield2():
yield
print("after_yield_2")And then make def test_bar(fix_w_yield1, fix_w_yield2):
print("test_bar")
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can keep the examples using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure thing, re-added. |
||
|
|
||
|
|
||
| @pytest.fixture | ||
| def fix_w_yield2(): | ||
| yield | ||
| print("after_yield_2") | ||
|
|
||
|
|
||
| .. code-block:: pytest | ||
|
|
||
| $ pytest test_module.py | ||
| =========================== test session starts ============================ | ||
| platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y | ||
| collected 1 item | ||
|
|
||
| test_module.py test_bar | ||
| .after_yield_2 | ||
| after_yield_1 | ||
|
|
||
|
|
||
| .. code-block:: python | ||
|
|
||
| import pytest | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def fix_w_finalizers(request): | ||
| request.addfinalizer(partial(print, "finalizer_2")) | ||
| request.addfinalizer(partial(print, "finalizer_1")) | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def test_bar(fix_w_finalizers): | ||
| print("test_bar") | ||
|
|
||
|
|
||
| .. code-block:: pytest | ||
|
|
||
| $ pytest test_module.py | ||
| =========================== test session starts ============================ | ||
| platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y | ||
| collected 1 item | ||
|
|
||
| test_module.py test_bar | ||
| .finalizer_1 | ||
| finalizer_2 | ||
|
|
||
|
|
||
| .. _`safe teardowns`: | ||
|
|
||
|
|
||
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.
This sentence needs tweaking if we look at the output. 👍
Finalizers are executed in FILO order, that is correct, because we can see that adding
fin2andfin1we get backfn1,fn2in the output.But the same can be said for the yield fixtures: we request them in
fix_w_yield1,fix_w_yield2order, and we getfix_w_yield2andfix_w_yield1in the output.That's because
yieldfixtures useaddfinalizerbehind the scenes: when the fixture executes, we register a function withaddfinalizerthat resumes the generator (which in turn calls the teardown code).Not sure how to "fix" this sentence, or perhaps we can explain something along the lines of what I wrote above, if that makes things clearer.
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.
Yeah, that makes sense.
I tried to explain how both examples show the similar FILO behavior, plus added the hidden usage of addfinalizer after the examples.
What do you think?