Skip to content

Commit 1003bea

Browse files
authored
Merge pull request #8323 from bluetech/setupstate-refactor-3
runner: a few more tweaks to SetupState
2 parents f85427b + 5822888 commit 1003bea

File tree

5 files changed

+31
-26
lines changed

5 files changed

+31
-26
lines changed

src/_pytest/fixtures.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ def _fill_fixtures_impl(function: "Function") -> None:
372372
fi = fm.getfixtureinfo(function.parent, function.obj, None)
373373
function._fixtureinfo = fi
374374
request = function._request = FixtureRequest(function, _ispytest=True)
375-
fm.session._setupstate.prepare(function)
375+
fm.session._setupstate.setup(function)
376376
request._fillfixtures()
377377
# Prune out funcargs for jstests.
378378
newfuncargs = {}

src/_pytest/hookspec.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -509,9 +509,9 @@ def pytest_runtest_teardown(item: "Item", nextitem: Optional["Item"]) -> None:
509509
510510
:param nextitem:
511511
The scheduled-to-be-next test item (None if no further test item is
512-
scheduled). This argument can be used to perform exact teardowns,
513-
i.e. calling just enough finalizers so that nextitem only needs to
514-
call setup-functions.
512+
scheduled). This argument is used to perform exact teardowns, i.e.
513+
calling just enough finalizers so that nextitem only needs to call
514+
setup functions.
515515
"""
516516

517517

src/_pytest/runner.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ def runtestprotocol(
120120
) -> List[TestReport]:
121121
hasrequest = hasattr(item, "_request")
122122
if hasrequest and not item._request: # type: ignore[attr-defined]
123+
# This only happens if the item is re-run, as is done by
124+
# pytest-rerunfailures.
123125
item._initrequest() # type: ignore[attr-defined]
124126
rep = call_and_report(item, "setup", log)
125127
reports = [rep]
@@ -151,7 +153,7 @@ def show_test_item(item: Item) -> None:
151153

152154
def pytest_runtest_setup(item: Item) -> None:
153155
_update_current_test_var(item, "setup")
154-
item.session._setupstate.prepare(item)
156+
item.session._setupstate.setup(item)
155157

156158

157159
def pytest_runtest_call(item: Item) -> None:
@@ -417,7 +419,7 @@ class SetupState:
417419
418420
[]
419421
420-
During the setup phase of item1, prepare(item1) is called. What it does
422+
During the setup phase of item1, setup(item1) is called. What it does
421423
is:
422424
423425
push session to stack, run session.setup()
@@ -441,7 +443,7 @@ class SetupState:
441443
442444
[session]
443445
444-
During the setup phase of item2, prepare(item2) is called. What it does
446+
During the setup phase of item2, setup(item2) is called. What it does
445447
is:
446448
447449
push mod2 to stack, run mod2.setup()
@@ -477,23 +479,26 @@ def __init__(self) -> None:
477479
],
478480
] = {}
479481

480-
def prepare(self, item: Item) -> None:
482+
def setup(self, item: Item) -> None:
481483
"""Setup objects along the collector chain to the item."""
484+
needed_collectors = item.listchain()
485+
482486
# If a collector fails its setup, fail its entire subtree of items.
483487
# The setup is not retried for each item - the same exception is used.
484-
for col, (finalizers, prepare_exc) in self.stack.items():
485-
if prepare_exc:
486-
raise prepare_exc
488+
for col, (finalizers, exc) in self.stack.items():
489+
assert col in needed_collectors, "previous item was not torn down properly"
490+
if exc:
491+
raise exc
487492

488-
needed_collectors = item.listchain()
489493
for col in needed_collectors[len(self.stack) :]:
490494
assert col not in self.stack
495+
# Push onto the stack.
491496
self.stack[col] = ([col.teardown], None)
492497
try:
493498
col.setup()
494-
except TEST_OUTCOME as e:
495-
self.stack[col] = (self.stack[col][0], e)
496-
raise e
499+
except TEST_OUTCOME as exc:
500+
self.stack[col] = (self.stack[col][0], exc)
501+
raise exc
497502

498503
def addfinalizer(self, finalizer: Callable[[], object], node: Node) -> None:
499504
"""Attach a finalizer to the given node.
@@ -517,7 +522,7 @@ def teardown_exact(self, nextitem: Optional[Item]) -> None:
517522
while self.stack:
518523
if list(self.stack.keys()) == needed_collectors[: len(self.stack)]:
519524
break
520-
node, (finalizers, prepare_exc) = self.stack.popitem()
525+
node, (finalizers, _) = self.stack.popitem()
521526
while finalizers:
522527
fin = finalizers.pop()
523528
try:

testing/python/fixtures.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def test_funcarg_basic(self, pytester: Pytester) -> None:
131131
item = pytester.getitem(Path("test_funcarg_basic.py"))
132132
assert isinstance(item, Function)
133133
# Execute's item's setup, which fills fixtures.
134-
item.session._setupstate.prepare(item)
134+
item.session._setupstate.setup(item)
135135
del item.funcargs["request"]
136136
assert len(get_public_names(item.funcargs)) == 2
137137
assert item.funcargs["some"] == "test_func"
@@ -827,7 +827,7 @@ def test_func(something): pass
827827
req = item._request
828828

829829
# Execute item's setup.
830-
item.session._setupstate.prepare(item)
830+
item.session._setupstate.setup(item)
831831

832832
with pytest.raises(pytest.FixtureLookupError):
833833
req.getfixturevalue("notexists")
@@ -855,7 +855,7 @@ def test_func(something): pass
855855
"""
856856
)
857857
assert isinstance(item, Function)
858-
item.session._setupstate.prepare(item)
858+
item.session._setupstate.setup(item)
859859
item._request._fillfixtures()
860860
# successively check finalization calls
861861
parent = item.getparent(pytest.Module)

testing/test_runner.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def test_setup(self, pytester: Pytester) -> None:
2525
item = pytester.getitem("def test_func(): pass")
2626
ss = item.session._setupstate
2727
values = [1]
28-
ss.prepare(item)
28+
ss.setup(item)
2929
ss.addfinalizer(values.pop, item)
3030
assert values
3131
ss.teardown_exact(None)
@@ -34,7 +34,7 @@ def test_setup(self, pytester: Pytester) -> None:
3434
def test_teardown_exact_stack_empty(self, pytester: Pytester) -> None:
3535
item = pytester.getitem("def test_func(): pass")
3636
ss = item.session._setupstate
37-
ss.prepare(item)
37+
ss.setup(item)
3838
ss.teardown_exact(None)
3939
ss.teardown_exact(None)
4040
ss.teardown_exact(None)
@@ -49,9 +49,9 @@ def test_func(): pass
4949
)
5050
ss = item.session._setupstate
5151
with pytest.raises(ValueError):
52-
ss.prepare(item)
52+
ss.setup(item)
5353
with pytest.raises(ValueError):
54-
ss.prepare(item)
54+
ss.setup(item)
5555

5656
def test_teardown_multiple_one_fails(self, pytester: Pytester) -> None:
5757
r = []
@@ -67,7 +67,7 @@ def fin3():
6767

6868
item = pytester.getitem("def test_func(): pass")
6969
ss = item.session._setupstate
70-
ss.prepare(item)
70+
ss.setup(item)
7171
ss.addfinalizer(fin1, item)
7272
ss.addfinalizer(fin2, item)
7373
ss.addfinalizer(fin3, item)
@@ -87,7 +87,7 @@ def fin2():
8787

8888
item = pytester.getitem("def test_func(): pass")
8989
ss = item.session._setupstate
90-
ss.prepare(item)
90+
ss.setup(item)
9191
ss.addfinalizer(fin1, item)
9292
ss.addfinalizer(fin2, item)
9393
with pytest.raises(Exception) as err:
@@ -106,7 +106,7 @@ def fin_module():
106106
item = pytester.getitem("def test_func(): pass")
107107
mod = item.listchain()[-2]
108108
ss = item.session._setupstate
109-
ss.prepare(item)
109+
ss.setup(item)
110110
ss.addfinalizer(fin_module, mod)
111111
ss.addfinalizer(fin_func, item)
112112
with pytest.raises(Exception, match="oops1"):

0 commit comments

Comments
 (0)