Fix faulthandler for Twisted Logger when used with "--capture=no"

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`.
This commit is contained in:
Andreas Motl 2021-01-17 19:23:57 +01:00
parent c9e9a599fe
commit 9ba1821e91
4 changed files with 33 additions and 1 deletions

View File

@ -21,6 +21,7 @@ Anders Hovmöller
Andras Mitzki Andras Mitzki
Andras Tim Andras Tim
Andrea Cimatoribus Andrea Cimatoribus
Andreas Motl
Andreas Zeidler Andreas Zeidler
Andrey Paramonov Andrey Paramonov
Andrzej Klajnert Andrzej Klajnert

View File

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

View File

@ -69,7 +69,12 @@ class FaultHandlerHooks:
@staticmethod @staticmethod
def _get_stderr_fileno(): def _get_stderr_fileno():
try: 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): except (AttributeError, io.UnsupportedOperation):
# pytest-xdist monkeypatches sys.stderr with an object that is not an actual file. # 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 # https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors

View File

@ -1,3 +1,4 @@
import io
import sys import sys
import pytest 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.no_fnmatch_line(warning_line)
result.stdout.fnmatch_lines("*1 passed*") result.stdout.fnmatch_lines("*1 passed*")
assert result.ret == 0 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