blob: e19aaa7303f984a0213d01e8067371c81ae37df2 [file] [edit]
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Pytest hooks."""
import warnings
import pytest
# Activate pytest hooks defined in test_process_all.py.
from .test_process_all import pytest_runtest_makereport # noqa: F401
from .test_process_all import pytest_terminal_summary # noqa: F401
def _escape_surrogates(text):
try:
text.encode("utf-8")
except UnicodeEncodeError:
return text.encode("utf-8", "backslashreplace").decode("utf-8")
else:
return text
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_logreport(report):
"""Escape the non-UTF8 paths used by test_unicode.py when a test
fails. If one of them ends up in a report, xdist can't send it to
the master process, and the whole run dies.
"""
if isinstance(report.longrepr, tuple):
path, lineno, reason = report.longrepr
report.longrepr = (path, lineno, _escape_surrogates(reason))
elif report.longrepr is not None:
text = str(report.longrepr)
escaped = _escape_surrogates(text)
if escaped != text:
report.longrepr = escaped
report.sections = [
(name, _escape_surrogates(content))
for name, content in report.sections
]
# Monkey patch pytest-instafail so that we ALSO get the full
# traceback/failure summary at the end of the run, see:
# https://github.com/pytest-dev/pytest-instafail/issues/21.
try:
import pytest_instafail
from _pytest.terminal import TerminalReporter
pytest_instafail.InstafailingTerminalReporter # noqa: B018
except (ImportError, AttributeError):
warnings.warn(
"failed to monkey patch pytest-instafail",
category=DeprecationWarning,
stacklevel=2,
)
else:
pytest_instafail.InstafailingTerminalReporter.summary_failures = (
TerminalReporter.summary_failures
)
pytest_instafail.InstafailingTerminalReporter.summary_errors = (
TerminalReporter.summary_errors
)