36
36
from _pytest .outcomes import OutcomeException
37
37
from _pytest .outcomes import Skipped
38
38
from _pytest .outcomes import TEST_OUTCOME
39
- from _pytest .store import StoreKey
40
39
41
40
if TYPE_CHECKING :
42
41
from typing_extensions import Literal
@@ -467,29 +466,33 @@ class SetupState:
467
466
"""
468
467
469
468
def __init__ (self ) -> None :
470
- # Maps node -> the node's finalizers.
471
469
# The stack is in the dict insertion order.
472
- self .stack : Dict [Node , List [Callable [[], object ]]] = {}
473
-
474
- _prepare_exc_key = StoreKey [Union [OutcomeException , Exception ]]()
470
+ self .stack : Dict [
471
+ Node ,
472
+ Tuple [
473
+ # Node's finalizers.
474
+ List [Callable [[], object ]],
475
+ # Node's exception, if its setup raised.
476
+ Optional [Union [OutcomeException , Exception ]],
477
+ ],
478
+ ] = {}
475
479
476
480
def prepare (self , item : Item ) -> None :
477
481
"""Setup objects along the collector chain to the item."""
478
482
# If a collector fails its setup, fail its entire subtree of items.
479
483
# The setup is not retried for each item - the same exception is used.
480
- for col in self .stack :
481
- prepare_exc = col ._store .get (self ._prepare_exc_key , None )
484
+ for col , (finalizers , prepare_exc ) in self .stack .items ():
482
485
if prepare_exc :
483
486
raise prepare_exc
484
487
485
488
needed_collectors = item .listchain ()
486
489
for col in needed_collectors [len (self .stack ) :]:
487
490
assert col not in self .stack
488
- self .stack [col ] = [col .teardown ]
491
+ self .stack [col ] = ( [col .teardown ], None )
489
492
try :
490
493
col .setup ()
491
494
except TEST_OUTCOME as e :
492
- col . _store [ self ._prepare_exc_key ] = e
495
+ self .stack [ col ] = ( self . stack [ col ][ 0 ], e )
493
496
raise e
494
497
495
498
def addfinalizer (self , finalizer : Callable [[], object ], node : Node ) -> None :
@@ -500,7 +503,7 @@ def addfinalizer(self, finalizer: Callable[[], object], node: Node) -> None:
500
503
assert node and not isinstance (node , tuple )
501
504
assert callable (finalizer )
502
505
assert node in self .stack , (node , self .stack )
503
- self .stack [node ].append (finalizer )
506
+ self .stack [node ][ 0 ] .append (finalizer )
504
507
505
508
def teardown_exact (self , nextitem : Optional [Item ]) -> None :
506
509
"""Teardown the current stack up until reaching nodes that nextitem
@@ -514,7 +517,7 @@ def teardown_exact(self, nextitem: Optional[Item]) -> None:
514
517
while self .stack :
515
518
if list (self .stack .keys ()) == needed_collectors [: len (self .stack )]:
516
519
break
517
- node , finalizers = self .stack .popitem ()
520
+ node , ( finalizers , prepare_exc ) = self .stack .popitem ()
518
521
while finalizers :
519
522
fin = finalizers .pop ()
520
523
try :
0 commit comments