def teardown_exact(self, nextitem: Item | None) -> None:
        """Teardown the current stack up until reaching nodes that nextitem
        also descends from.

        When nextitem is None (meaning we're at the last item), the entire
        stack is torn down.
        """
        needed_collectors = (nextitem and nextitem.listchain()) or []
        exceptions: list[BaseException] = []
        while self.stack:
            if list(self.stack.keys()) == needed_collectors[: len(self.stack)]:
                break
            node, (finalizers, _) = self.stack.popitem()
            these_exceptions = []
            while finalizers:
                fin = finalizers.pop()
                try:
                    fin()
                except TEST_OUTCOME as e:
                    these_exceptions.append(e)

            if len(these_exceptions) == 1:
                exceptions.extend(these_exceptions)
            elif these_exceptions:
                msg = f"errors while tearing down {node!r}"
                exceptions.append(BaseExceptionGroup(msg, these_exceptions[::-1]))

        if len(exceptions) == 1:
            raise exceptions[0]
        elif exceptions:
            raise BaseExceptionGroup("errors during test teardown", exceptions[::-1])
        if nextitem is None:
            assert not self.stack
Teardown the current stack up until reaching nodes that nextitem
        also descends from.

        When nextitem is None (meaning we're at the last item), the entire
        stack is torn down.
        
src/_pytest/runner.py