55
66import argparse
77import collections .abc
8+ import contextlib
89import copy
910import dataclasses
1011import enum
7374 from _pytest .cacheprovider import Cache
7475 from _pytest .terminal import TerminalReporter
7576
76-
7777_PluggyPlugin = object
7878"""A type to represent plugin objects.
7979
@@ -1077,7 +1077,7 @@ def __init__(
10771077 self ._inicache : dict [str , Any ] = {}
10781078 self ._override_ini : Sequence [str ] = ()
10791079 self ._opt2dest : dict [str , str ] = {}
1080- self ._cleanup : list [ Callable [[], None ]] = []
1080+ self ._cleanup_stack = contextlib . ExitStack ()
10811081 self .pluginmanager .register (self , "pytestconfig" )
10821082 self ._configured = False
10831083 self .hook .pytest_addoption .call_historic (
@@ -1106,8 +1106,9 @@ def inipath(self) -> pathlib.Path | None:
11061106
11071107 def add_cleanup (self , func : Callable [[], None ]) -> None :
11081108 """Add a function to be called when the config object gets out of
1109- use (usually coinciding with pytest_unconfigure)."""
1110- self ._cleanup .append (func )
1109+ use (usually coinciding with pytest_unconfigure).
1110+ """
1111+ self ._cleanup_stack .callback (func )
11111112
11121113 def _do_configure (self ) -> None :
11131114 assert not self ._configured
@@ -1117,13 +1118,18 @@ def _do_configure(self) -> None:
11171118 self .hook .pytest_configure .call_historic (kwargs = dict (config = self ))
11181119
11191120 def _ensure_unconfigure (self ) -> None :
1120- if self ._configured :
1121- self ._configured = False
1122- self .hook .pytest_unconfigure (config = self )
1123- self .hook .pytest_configure ._call_history = []
1124- while self ._cleanup :
1125- fin = self ._cleanup .pop ()
1126- fin ()
1121+ try :
1122+ if self ._configured :
1123+ self ._configured = False
1124+ try :
1125+ self .hook .pytest_unconfigure (config = self )
1126+ finally :
1127+ self .hook .pytest_configure ._call_history = []
1128+ finally :
1129+ try :
1130+ self ._cleanup_stack .close ()
1131+ finally :
1132+ self ._cleanup_stack = contextlib .ExitStack ()
11271133
11281134 def get_terminal_writer (self ) -> TerminalWriter :
11291135 terminalreporter : TerminalReporter | None = self .pluginmanager .get_plugin (
0 commit comments