From 7968383ddd1dd076edaa890d6760d29774a76055 Mon Sep 17 00:00:00 2001 From: Yuval Date: Fri, 31 May 2024 04:29:31 +0300 Subject: [PATCH] Add empty sentinel item in WorkerInteractor queue When pytest_runtest_protocol is called with item==nextitem multiple times, with a test that accepts some fixtures -> the second call forward raises an error. This is causes in WorkerInteractor when the same test appears twice in a row in its items queue. To deal with this, we define an "empty" item that shall allow us to call pytest_runtest_protocol with nextitem=None, effectively solving this problem so long sequential executions of the same items are delimited by these empty items in the queue. --- src/xdist/remote.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/xdist/remote.py b/src/xdist/remote.py index dd1f9883..47f18a83 100644 --- a/src/xdist/remote.py +++ b/src/xdist/remote.py @@ -67,6 +67,7 @@ def worker_title(title: str) -> None: class Marker(enum.Enum): SHUTDOWN = 0 QUEUE_REPLACED = 1 + EMPTY = 2 class WorkerInteractor: @@ -144,6 +145,8 @@ def handle_command( self.torun.put(Marker.SHUTDOWN) elif name == "steal": self.steal(kwargs["indices"]) + elif name == "empty": + self.torun.put(Marker.EMPTY) def steal(self, indices: Sequence[int]) -> None: indices_set = set(indices) @@ -171,6 +174,8 @@ def pytest_runtestloop(self, session: pytest.Session) -> bool: self.channel.setcallback(self.handle_command, endmarker=Marker.SHUTDOWN) self.nextitem_index = self._get_next_item_index() while self.nextitem_index is not Marker.SHUTDOWN: + while self.nextitem_index is Marker.EMPTY: + self.nextitem_index = self._get_next_item_index() self.run_one_test() if session.shouldfail or session.shouldstop: break @@ -183,7 +188,7 @@ def run_one_test(self) -> None: items = self.session.items item = items[self.item_index] - if self.nextitem_index is Marker.SHUTDOWN: + if self.nextitem_index in [Marker.SHUTDOWN, Marker.EMPTY]: nextitem = None else: assert self.nextitem_index is not None