faulthandler: avoid accessing sys.stderr.encoding
Fixes a pytest-xdist regression after
762bb61562
(not yet released).
pytest-xdist patches sys.stderr with an object which doesn't have
`encoding`. Strictly speaking, this should be fixed there (or more
precisely, in execnet), but it will drop support for older versions
which don't want.
But in any case, the fix turns out to simplify the code, using FD
support added in Python 3.5, so it's good anyway!
Refs: https://github.com/pytest-dev/pytest-xdist/pull/900
This commit is contained in:
parent
a88ae8289c
commit
aac5d5d08b
|
@ -2,7 +2,6 @@ import io
|
|||
import os
|
||||
import sys
|
||||
from typing import Generator
|
||||
from typing import TextIO
|
||||
|
||||
import pytest
|
||||
from _pytest.config import Config
|
||||
|
@ -11,7 +10,7 @@ from _pytest.nodes import Item
|
|||
from _pytest.stash import StashKey
|
||||
|
||||
|
||||
fault_handler_stderr_key = StashKey[TextIO]()
|
||||
fault_handler_stderr_fd_key = StashKey[int]()
|
||||
fault_handler_originally_enabled_key = StashKey[bool]()
|
||||
|
||||
|
||||
|
@ -26,12 +25,9 @@ def pytest_addoption(parser: Parser) -> None:
|
|||
def pytest_configure(config: Config) -> None:
|
||||
import faulthandler
|
||||
|
||||
stderr_fd_copy = os.dup(get_stderr_fileno())
|
||||
config.stash[fault_handler_stderr_key] = open(
|
||||
stderr_fd_copy, "w", encoding=sys.stderr.encoding
|
||||
)
|
||||
config.stash[fault_handler_stderr_fd_key] = os.dup(get_stderr_fileno())
|
||||
config.stash[fault_handler_originally_enabled_key] = faulthandler.is_enabled()
|
||||
faulthandler.enable(file=config.stash[fault_handler_stderr_key])
|
||||
faulthandler.enable(file=config.stash[fault_handler_stderr_fd_key])
|
||||
|
||||
|
||||
def pytest_unconfigure(config: Config) -> None:
|
||||
|
@ -39,9 +35,9 @@ def pytest_unconfigure(config: Config) -> None:
|
|||
|
||||
faulthandler.disable()
|
||||
# Close the dup file installed during pytest_configure.
|
||||
if fault_handler_stderr_key in config.stash:
|
||||
config.stash[fault_handler_stderr_key].close()
|
||||
del config.stash[fault_handler_stderr_key]
|
||||
if fault_handler_stderr_fd_key in config.stash:
|
||||
os.close(config.stash[fault_handler_stderr_fd_key])
|
||||
del config.stash[fault_handler_stderr_fd_key]
|
||||
if config.stash.get(fault_handler_originally_enabled_key, False):
|
||||
# Re-enable the faulthandler if it was originally enabled.
|
||||
faulthandler.enable(file=get_stderr_fileno())
|
||||
|
@ -69,10 +65,10 @@ def get_timeout_config_value(config: Config) -> float:
|
|||
@pytest.hookimpl(hookwrapper=True, trylast=True)
|
||||
def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]:
|
||||
timeout = get_timeout_config_value(item.config)
|
||||
stderr = item.config.stash[fault_handler_stderr_key]
|
||||
if timeout > 0 and stderr is not None:
|
||||
if timeout > 0:
|
||||
import faulthandler
|
||||
|
||||
stderr = item.config.stash[fault_handler_stderr_fd_key]
|
||||
faulthandler.dump_traceback_later(timeout, file=stderr)
|
||||
try:
|
||||
yield
|
||||
|
|
Loading…
Reference in New Issue