Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to Pytest's terminal reporter #162

Merged
merged 4 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
repos:
- repo: https://github.com/psf/black
rev: 22.3.0
rev: 23.12.1
hooks:
- id: black
args: [--safe, --quiet, --target-version, py36]
args: [--safe, --quiet, --target-version, py37]
- repo: https://github.com/asottile/blacken-docs
rev: v1.12.1
rev: 1.16.0
hooks:
- id: blacken-docs
additional_dependencies: [black==20.8b1]
additional_dependencies: [black==23.12.1]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -21,34 +21,30 @@ repos:
- id: debug-statements
language_version: python3
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
rev: 7.0.0
hooks:
- id: flake8
language_version: python3
additional_dependencies: [flake8-typing-imports==1.3.0]
- repo: https://github.com/FalconSocial/pre-commit-mirrors-pep257
rev: v0.3.3
hooks:
- id: pep257
additional_dependencies: [flake8-typing-imports==1.15.0]
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
rev: 7.0.0
hooks:
- id: flake8
language_version: python3
- repo: https://github.com/asottile/reorder_python_imports
rev: v3.1.0
rev: v3.12.0
hooks:
- id: reorder-python-imports
- repo: https://github.com/asottile/pyupgrade
rev: v2.32.1
rev: v3.15.0
hooks:
- id: pyupgrade
args: [--keep-percent-format, --py36-plus]
args: [--keep-percent-format, --py37-plus]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
rev: v1.10.0
hooks:
- id: rst-backticks
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.26.3
rev: v1.33.0
hooks:
- id: yamllint
5 changes: 5 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ Unreleased

- Fix debugger detection for recent VSCode, this compiles pydevd using
cython which is now correctly detected. Thanks Adrian Gielniewski.
- Switched to using Pytest's ``TerminalReporter`` instead of writing
directly to ``sys.{stdout,stderr}``.
This change also switches all output from ``sys.stderr`` to ``sys.stdout``.
Thanks Pedro Algarvio.
- Pytest 7.0.0 is now the minimum supported version. Thanks Pedro Algarvio.

2.2.0
-----
Expand Down
64 changes: 21 additions & 43 deletions pytest_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"""
import inspect
import os
import shutil
import signal
import sys
import threading
Expand Down Expand Up @@ -238,7 +237,9 @@ def is_debugging(trace_func=None):
trace_func = sys.gettrace()
trace_module = None
if trace_func:
trace_module = inspect.getmodule(trace_func) or inspect.getmodule(trace_func.__class__)
trace_module = inspect.getmodule(trace_func) or inspect.getmodule(
trace_func.__class__
)
if trace_module:
parts = trace_module.__name__.split(".")
for name in KNOWN_DEBUGGING_MODULES:
Expand Down Expand Up @@ -443,11 +444,12 @@ def timeout_sigalrm(item, settings):
return
__tracebackhide__ = True
nthreads = len(threading.enumerate())
terminal = item.config.get_terminal_writer()
if nthreads > 1:
write_title("Timeout", sep="+")
dump_stacks()
terminal.sep("+", title="Timeout")
dump_stacks(terminal)
if nthreads > 1:
write_title("Timeout", sep="+")
terminal.sep("+", title="Timeout")
pytest.fail("Timeout >%ss" % settings.timeout)


Expand All @@ -459,37 +461,39 @@ def timeout_timer(item, settings):
"""
if not settings.disable_debugger_detection and is_debugging():
return
terminal = item.config.get_terminal_writer()
try:
capman = item.config.pluginmanager.getplugin("capturemanager")
if capman:
capman.suspend_global_capture(item)
stdout, stderr = capman.read_global_capture()
else:
stdout, stderr = None, None
write_title("Timeout", sep="+")
terminal.sep("+", title="Timeout")
caplog = item.config.pluginmanager.getplugin("_capturelog")
if caplog and hasattr(item, "capturelog_handler"):
log = item.capturelog_handler.stream.getvalue()
if log:
write_title("Captured log")
write(log)
terminal.sep("~", title="Captured log")
terminal.write(log)
if stdout:
write_title("Captured stdout")
write(stdout)
terminal.sep("~", title="Captured stdout")
terminal.write(stdout)
if stderr:
write_title("Captured stderr")
write(stderr)
dump_stacks()
write_title("Timeout", sep="+")
terminal.sep("~", title="Captured stderr")
terminal.write(stderr)
dump_stacks(terminal)
terminal.sep("+", title="Timeout")
except Exception:
traceback.print_exc()
finally:
terminal.flush()
sys.stdout.flush()
sys.stderr.flush()
os._exit(1)


def dump_stacks():
def dump_stacks(terminal):
"""Dump the stacks of all threads except the current thread."""
current_ident = threading.current_thread().ident
for thread_ident, frame in sys._current_frames().items():
Expand All @@ -501,31 +505,5 @@ def dump_stacks():
break
else:
thread_name = "<unknown>"
write_title("Stack of %s (%s)" % (thread_name, thread_ident))
write("".join(traceback.format_stack(frame)))


def write_title(title, stream=None, sep="~"):
"""Write a section title.

If *stream* is None sys.stderr will be used, *sep* is used to
draw the line.
"""
if stream is None:
stream = sys.stderr
width, height = shutil.get_terminal_size()
fill = int((width - len(title) - 2) / 2)
line = " ".join([sep * fill, title, sep * fill])
if len(line) < width:
line += sep * (width - len(line))
stream.write("\n" + line + "\n")


def write(text, stream=None):
"""Write text to stream.

Pretty stupid really, only here for symmetry with .write_title().
"""
if stream is None:
stream = sys.stderr
stream.write(text)
terminal.sep("~", title="Stack of %s (%s)" % (thread_name, thread_ident))
terminal.write("".join(traceback.format_stack(frame)))
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ classifiers =
[options]
py_modules = pytest_timeout
install_requires =
pytest>=5.0.0
pytest>=7.0.0
python_requires = >=3.7

[options.entry_points]
Expand Down
Loading