diff --git a/src/xdist/dsession.py b/src/xdist/dsession.py index 7ac5f577..2f06cb18 100644 --- a/src/xdist/dsession.py +++ b/src/xdist/dsession.py @@ -277,10 +277,17 @@ def worker_logwarning(self, message, code, nodeid, fslocation): self.config.hook.pytest_logwarning.call_historic(kwargs=kwargs) def worker_warning_captured(self, warning_message, when, item): - """Emitted when a node calls the pytest_logwarning hook.""" + """Emitted when a node calls the pytest_warning_captured hook (deprecated in 6.0).""" kwargs = dict(warning_message=warning_message, when=when, item=item) self.config.hook.pytest_warning_captured.call_historic(kwargs=kwargs) + def worker_warning_recorded(self, warning_message, when, nodeid, location): + """Emitted when a node calls the pytest_warning_recorded hook.""" + kwargs = dict( + warning_message=warning_message, when=when, nodeid=nodeid, location=location + ) + self.config.hook.pytest_warning_recorded.call_historic(kwargs=kwargs) + def _clone_node(self, node): """Return new node based on an existing one. diff --git a/src/xdist/remote.py b/src/xdist/remote.py index 28991c07..984dffbd 100644 --- a/src/xdist/remote.py +++ b/src/xdist/remote.py @@ -151,6 +151,18 @@ def pytest_warning_captured(self, warning_message, when, item): item=None, ) + # the pytest_warning_recorded hook was introduced in pytest 6.0 + if hasattr(_pytest.hookspec, "pytest_warning_recorded"): + + def pytest_warning_recorded(self, warning_message, when, nodeid, location): + self.sendevent( + "warning_recorded", + warning_message_data=serialize_warning_message(warning_message), + when=when, + nodeid=nodeid, + location=location, + ) + def serialize_warning_message(warning_message): if isinstance(warning_message.message, Warning): diff --git a/src/xdist/workermanage.py b/src/xdist/workermanage.py index 6a47e1c7..ff599f50 100644 --- a/src/xdist/workermanage.py +++ b/src/xdist/workermanage.py @@ -359,6 +359,17 @@ def process_from_remote(self, eventcall): # noqa too complex when=kwargs["when"], item=kwargs["item"], ) + elif eventname == "warning_recorded": + warning_message = unserialize_warning_message( + kwargs["warning_message_data"] + ) + self.notify_inproc( + eventname, + warning_message=warning_message, + when=kwargs["when"], + nodeid=kwargs["nodeid"], + location=kwargs["location"], + ) else: raise ValueError("unknown event: {}".format(eventname)) except KeyboardInterrupt: diff --git a/testing/conftest.py b/testing/conftest.py index 66fbac67..43c0399d 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -22,12 +22,16 @@ def _divert_atexit(request, monkeypatch): finalizers = [] - def finish(): - while finalizers: - finalizers.pop()() + def fake_register(func, *args, **kwargs): + finalizers.append((func, args, kwargs)) - monkeypatch.setattr(atexit, "register", finalizers.append) - request.addfinalizer(finish) + monkeypatch.setattr(atexit, "register", fake_register) + + yield + + while finalizers: + func, args, kwargs = finalizers.pop() + func(*args, **kwargs) def pytest_addoption(parser):