Skip to content
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
17 changes: 8 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,31 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.36.0
rev: 0.36.1
hooks:
- id: check-github-workflows
args: ["--verbose"]
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies: ["tomli>=2.2.1"]
- repo: https://github.com/tox-dev/tox-ini-fmt
rev: "1.7.1"
additional_dependencies: ["tomli>=2.4"]
- repo: https://github.com/tox-dev/tox-toml-fmt
rev: "v1.5.4"
hooks:
- id: tox-ini-fmt
args: ["-p", "fix"]
- id: tox-toml-fmt
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "v2.11.1"
rev: "v2.15.2"
hooks:
- id: pyproject-fmt
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.14.10"
rev: "v0.15.0"
hooks:
- id: ruff-format
- id: ruff
args: ["--fix", "--unsafe-fixes", "--exit-non-zero-on-fix"]
- repo: https://github.com/rbubley/mirrors-prettier
rev: "v3.7.4"
rev: "v3.8.1"
hooks:
- id: prettier
args: ["--print-width=120", "--prose-wrap=always"]
Expand Down
42 changes: 22 additions & 20 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
build-backend = "hatchling.build"
requires = [
"hatch-vcs>=0.5",
"hatchling>=1.27",
"hatchling>=1.28",
]

[project]
name = "pytest-print"
description = "pytest-print adds the printer fixture you can use to print messages to the user (directly to the pytest runner, not stdout)"
description = """\
pytest-print adds the printer fixture you can use to print messages to the user (directly to the pytest runner, not \
stdout)\
"""
readme = "README.md"
keywords = [
"env",
Expand Down Expand Up @@ -36,11 +39,11 @@ dynamic = [
"version",
]
dependencies = [
"pytest>=8.4.2",
"pytest>=9.0.2",
]
optional-dependencies.test = [
"covdefaults>=2.3",
"coverage>=7.10.7",
"coverage>=7.13.4",
"pytest-mock>=3.15.1",
]
urls.Homepage = "https://github.com/pytest-dev/pytest-print"
Expand All @@ -67,6 +70,7 @@ lint.ignore = [
"D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
"DOC", # no support
"ISC001", # Conflict with formatter
"RUF067", # code in __init__ modules is intentional
"S104", # Possible binding to all interface
]
lint.per-file-ignores."tests/**/*.py" = [
Expand All @@ -93,20 +97,16 @@ count = true
max_supported_python = "3.13"

[tool.coverage]
run.branch = true
run.dynamic_context = "test_function"
run.parallel = true
run.plugins = [
"covdefaults",
]
run.source = [
"pytest_print",
"tests",
]
run.dynamic_context = "test_function"
run.branch = true
run.parallel = true
report.omit = [
"tests/example_*.py",
]
report.fail_under = 100
report.show_missing = true
html.show_contexts = true
html.skip_covered = false
paths.source = [
"src",
".tox*/*/lib/python*/site-packages",
Expand All @@ -115,11 +115,13 @@ paths.source = [
"*/src",
"*\\src",
]
run.plugins = [
"covdefaults",
report.fail_under = 100
report.omit = [
"tests/example_*.py",
]
report.show_missing = true
html.show_contexts = true
html.skip_covered = false

[tool.mypy]
python_version = "3.13"
show_error_codes = true
strict = true
[tool.ty]
environment.python-version = "3.14"
18 changes: 7 additions & 11 deletions src/pytest_print/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from __future__ import annotations

import sys
from dataclasses import dataclass, replace
from timeit import default_timer
from typing import TYPE_CHECKING, Protocol, TypeVar, cast
Expand All @@ -11,8 +10,6 @@

if TYPE_CHECKING:
from _pytest.capture import CaptureManager
from _pytest.fixtures import SubRequest
from _pytest.terminal import TerminalReporter


def pytest_addoption(parser: pytest.Parser) -> None:
Expand Down Expand Up @@ -45,7 +42,7 @@ def __call__(self, msg: str) -> None:


@pytest.fixture(scope="session")
def printer_session(request: SubRequest) -> Printer:
def printer_session(request: pytest.FixtureRequest) -> Printer:
"""Pytest plugin to print test progress steps in verbose mode (session scoped)."""
return _create(request, _Printer, Formatter())

Expand Down Expand Up @@ -76,7 +73,7 @@ def indent(self, *, icon: str) -> PrettyPrinter:


@pytest.fixture(scope="session")
def pretty_printer(request: SubRequest) -> PrettyPrinter:
def pretty_printer(request: pytest.FixtureRequest) -> PrettyPrinter:
"""Pytest plugin to print test progress steps in verbose mode."""
formatter = Formatter(head=" ", icon="⏩", space=" ", indentation=" ", timer_fmt="[{elapsed:.20f}]")
return _create(request, _PrettyPrinter, formatter)
Expand All @@ -94,17 +91,16 @@ def __call__(self, *, formatter: Formatter) -> PrettyPrinter:


@pytest.fixture(scope="session")
def create_pretty_printer(request: SubRequest) -> PrettyPrinterFactory:
def create_pretty_printer(request: pytest.FixtureRequest) -> PrettyPrinterFactory:
"""Pytest plugin to print test progress steps in verbose mode."""
Formatter(head=" ", icon="⏩", space=" ", indentation=" ", timer_fmt="[{elapsed:.20f}]")

def meth(*, formatter: Formatter) -> PrettyPrinter:
return _create(request, _PrettyPrinter, formatter)

return meth


@dataclass(frozen=True, **{"slots": True, "kw_only": True} if sys.version_info >= (3, 10) else {})
@dataclass(frozen=True, slots=True, kw_only=True)
class Formatter:
"""Configures how to format messages to be printed."""

Expand Down Expand Up @@ -137,7 +133,7 @@ class _Printer:
def __init__(
self,
*,
reporter: TerminalReporter | None,
reporter: pytest.TerminalReporter | None,
capture_manager: CaptureManager | None,
formatter: Formatter,
level: int,
Expand Down Expand Up @@ -177,9 +173,9 @@ def indent(self, *, icon: str) -> PrettyPrinter:
_OfType = TypeVar("_OfType", bound=_Printer)


def _create(request: SubRequest, of_type: type[_OfType], formatter: Formatter) -> _OfType:
def _create(request: pytest.FixtureRequest, of_type: type[_OfType], formatter: Formatter) -> _OfType:
return of_type(
reporter=cast("TerminalReporter | None", request.config.pluginmanager.getplugin("terminalreporter"))
reporter=cast("pytest.TerminalReporter | None", request.config.pluginmanager.getplugin("terminalreporter"))
if request.config.getoption("pytest_print_on") or cast("int", request.config.getoption("verbose")) > 0
else None,
capture_manager=cast("CaptureManager | None", request.config.pluginmanager.getplugin("capturemanager")),
Expand Down
7 changes: 3 additions & 4 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ def extract_printer_text(lines: list[str]) -> str:
return re.sub(r"[ \t]+\n", "\n", output)


def seed_test(filename: str, testdir: pytest.Testdir) -> pytest.Testdir:
def seed_test(filename: str, pytester: pytest.Pytester) -> pytest.Pytester:
src = Path(__file__).parent / filename
assert src.exists()
dest = Path(str(testdir.tmpdir)) / "test_a.py"
copy2(src, dest)
return testdir
copy2(src, pytester.path / "test_a.py")
return pytester


__all__ = [
Expand Down
12 changes: 6 additions & 6 deletions tests/test_create_pretty_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@


@pytest.fixture
def example(testdir: pytest.Testdir) -> pytest.Testdir:
return seed_test("example_create_pretty_print.py", testdir)
def example(pytester: pytest.Pytester) -> pytest.Pytester:
return seed_test("example_create_pretty_print.py", pytester)


def fix_floats_in_relative_time(txt: str) -> str:
float_pattern = r"[-+]?\d*\.\d+([eE][-+]?\d+)?"
return re.sub(float_pattern, "0.1", txt)


def test_progress_no_v(example: pytest.Testdir) -> None:
def test_progress_no_v(example: pytest.Pytester) -> None:
result = example.runpytest()
result.assert_outcomes(passed=3)
assert " start server from virtual env" not in result.outlines
assert "global peace" not in result.outlines


def test_progress_v_no_relative(example: pytest.Testdir) -> None:
def test_progress_v_no_relative(example: pytest.Pytester) -> None:
result_verbose = example.runpytest("-v", "--print")
result_verbose.assert_outcomes(passed=3)

Expand Down Expand Up @@ -57,7 +57,7 @@ def test_progress_v_no_relative(example: pytest.Testdir) -> None:
assert output == expected


def test_progress_v_relative(example: pytest.Testdir) -> None:
def test_progress_v_relative(example: pytest.Pytester) -> None:
result_verbose_relative = example.runpytest(
"--print",
"-v",
Expand All @@ -83,7 +83,7 @@ def test_progress_v_relative(example: pytest.Testdir) -> None:
assert output == expected


def test_progress_no_v_but_with_print_request(example: pytest.Testdir) -> None:
def test_progress_no_v_but_with_print_request(example: pytest.Pytester) -> None:
result = example.runpytest("--print")
result.assert_outcomes(passed=3)
assert " 🚀 start server from virtual env" in result.outlines
Expand Down
8 changes: 4 additions & 4 deletions tests/test_pretty_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@


@pytest.fixture
def example(testdir: pytest.Testdir) -> pytest.Testdir:
return seed_test("example_pretty_print.py", testdir)
def example(pytester: pytest.Pytester) -> pytest.Pytester:
return seed_test("example_pretty_print.py", pytester)


def fix_floats_in_relative_time(txt: str) -> str:
float_pattern = r"[-+]?\d*\.\d+([eE][-+]?\d+)?"
return re.sub(float_pattern, "0.1", txt)


def test_progress_v_no_relative(example: pytest.Testdir) -> None:
def test_progress_v_no_relative(example: pytest.Pytester) -> None:
result = example.runpytest("-v", "--print")
result.assert_outcomes(passed=1)

Expand All @@ -37,7 +37,7 @@ def test_progress_v_no_relative(example: pytest.Testdir) -> None:
assert output == expected


def test_progress_v_relative(example: pytest.Testdir) -> None:
def test_progress_v_relative(example: pytest.Pytester) -> None:
result = example.runpytest(
"--print",
"-v",
Expand Down
12 changes: 6 additions & 6 deletions tests/test_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@


@pytest.fixture
def example(testdir: pytest.Testdir) -> pytest.Testdir:
return seed_test("example_print.py", testdir)
def example(pytester: pytest.Pytester) -> pytest.Pytester:
return seed_test("example_print.py", pytester)


def test_progress_no_v(example: pytest.Testdir) -> None:
def test_progress_no_v(example: pytest.Pytester) -> None:
result = example.runpytest()
result.assert_outcomes(passed=2)
assert " start server from virtual env" not in result.outlines
assert "global peace" not in result.outlines


def test_progress_v_no_relative(example: pytest.Testdir, monkeypatch: pytest.MonkeyPatch) -> None:
def test_progress_v_no_relative(example: pytest.Pytester, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr("_pytest._io.terminalwriter.get_terminal_width", lambda: 80)
monkeypatch.setenv("COLUMNS", str(80))
result_verbose = example.runpytest("-v", "--print")
Expand All @@ -40,7 +40,7 @@ def test_progress_v_no_relative(example: pytest.Testdir, monkeypatch: pytest.Mon
assert found == expected


def test_progress_v_relative(example: pytest.Testdir) -> None:
def test_progress_v_relative(example: pytest.Pytester) -> None:
result_verbose_relative = example.runpytest(
"--print",
"-v",
Expand Down Expand Up @@ -69,7 +69,7 @@ def test_progress_v_relative(example: pytest.Testdir) -> None:
], session


def test_progress_no_v_but_with_print_request(example: pytest.Testdir) -> None:
def test_progress_no_v_but_with_print_request(example: pytest.Pytester) -> None:
result = example.runpytest("--print")
result.assert_outcomes(passed=2)
assert " start server from virtual env" in result.outlines
Expand Down
Loading