Skip to content

Commit 8d605b9

Browse files
committed
Merge pull request #8250 from daq-tools/fix-twisted-capture
1 parent 14e0c3e commit 8d605b9

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Anders Hovmöller
2121
Andras Mitzki
2222
Andras Tim
2323
Andrea Cimatoribus
24+
Andreas Motl
2425
Andreas Zeidler
2526
Andrey Paramonov
2627
Andrzej Klajnert

changelog/8249.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix the ``faulthandler`` plugin for occasions when running with ``twisted.logger`` and using ``pytest --capture=no``.

src/_pytest/faulthandler.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ def pytest_unconfigure(self, config: Config) -> None:
6969
@staticmethod
7070
def _get_stderr_fileno():
7171
try:
72-
return sys.stderr.fileno()
72+
fileno = sys.stderr.fileno()
73+
# The Twisted Logger will return an invalid file descriptor since it is not backed
74+
# by an FD. So, let's also forward this to the same code path as with pytest-xdist.
75+
if fileno == -1:
76+
raise AttributeError()
77+
return fileno
7378
except (AttributeError, io.UnsupportedOperation):
7479
# pytest-xdist monkeypatches sys.stderr with an object that is not an actual file.
7580
# https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors

testing/test_faulthandler.py

+25
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import io
12
import sys
23

34
import pytest
@@ -135,3 +136,27 @@ def test():
135136
result.stdout.no_fnmatch_line(warning_line)
136137
result.stdout.fnmatch_lines("*1 passed*")
137138
assert result.ret == 0
139+
140+
141+
def test_get_stderr_fileno_invalid_fd() -> None:
142+
"""Test for faulthandler being able to handle invalid file descriptors for stderr (#8249)."""
143+
from _pytest.faulthandler import FaultHandlerHooks
144+
145+
class StdErrWrapper(io.StringIO):
146+
"""
147+
Mimic ``twisted.logger.LoggingFile`` to simulate returning an invalid file descriptor.
148+
149+
https://github.com/twisted/twisted/blob/twisted-20.3.0/src/twisted/logger/_io.py#L132-L139
150+
"""
151+
152+
def fileno(self):
153+
return -1
154+
155+
wrapper = StdErrWrapper()
156+
157+
with pytest.MonkeyPatch.context() as mp:
158+
mp.setattr("sys.stderr", wrapper)
159+
160+
# Even when the stderr wrapper signals an invalid file descriptor,
161+
# ``_get_stderr_fileno()`` should return the real one.
162+
assert FaultHandlerHooks._get_stderr_fileno() == 2

0 commit comments

Comments
 (0)