summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--changelog/8249.bugfix.rst1
-rw-r--r--src/_pytest/faulthandler.py7
-rw-r--r--testing/test_faulthandler.py25
4 files changed, 33 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index e75baa8cd..0c721a496 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -21,6 +21,7 @@ Anders Hovmöller
Andras Mitzki
Andras Tim
Andrea Cimatoribus
+Andreas Motl
Andreas Zeidler
Andrey Paramonov
Andrzej Klajnert
diff --git a/changelog/8249.bugfix.rst b/changelog/8249.bugfix.rst
new file mode 100644
index 000000000..aa084c757
--- /dev/null
+++ b/changelog/8249.bugfix.rst
@@ -0,0 +1 @@
+Fix the ``faulthandler`` plugin for occasions when running with ``twisted.logger`` and using ``pytest --capture=no``.
diff --git a/src/_pytest/faulthandler.py b/src/_pytest/faulthandler.py
index d0cc0430c..ff673b5b1 100644
--- a/src/_pytest/faulthandler.py
+++ b/src/_pytest/faulthandler.py
@@ -69,7 +69,12 @@ class FaultHandlerHooks:
@staticmethod
def _get_stderr_fileno():
try:
- return sys.stderr.fileno()
+ fileno = sys.stderr.fileno()
+ # The Twisted Logger will return an invalid file descriptor since it is not backed
+ # by an FD. So, let's also forward this to the same code path as with pytest-xdist.
+ if fileno == -1:
+ raise AttributeError()
+ return fileno
except (AttributeError, io.UnsupportedOperation):
# pytest-xdist monkeypatches sys.stderr with an object that is not an actual file.
# https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors
diff --git a/testing/test_faulthandler.py b/testing/test_faulthandler.py
index caf39813c..370084c12 100644
--- a/testing/test_faulthandler.py
+++ b/testing/test_faulthandler.py
@@ -1,3 +1,4 @@
+import io
import sys
import pytest
@@ -135,3 +136,27 @@ def test_already_initialized(faulthandler_timeout: int, pytester: Pytester) -> N
result.stdout.no_fnmatch_line(warning_line)
result.stdout.fnmatch_lines("*1 passed*")
assert result.ret == 0
+
+
+def test_get_stderr_fileno_invalid_fd() -> None:
+ """Test for faulthandler being able to handle invalid file descriptors for stderr (#8249)."""
+ from _pytest.faulthandler import FaultHandlerHooks
+
+ class StdErrWrapper(io.StringIO):
+ """
+ Mimic ``twisted.logger.LoggingFile`` to simulate returning an invalid file descriptor.
+
+ https://github.com/twisted/twisted/blob/twisted-20.3.0/src/twisted/logger/_io.py#L132-L139
+ """
+
+ def fileno(self):
+ return -1
+
+ wrapper = StdErrWrapper()
+
+ with pytest.MonkeyPatch.context() as mp:
+ mp.setattr("sys.stderr", wrapper)
+
+ # Even when the stderr wrapper signals an invalid file descriptor,
+ # ``_get_stderr_fileno()`` should return the real one.
+ assert FaultHandlerHooks._get_stderr_fileno() == 2