reports: support any PathLike instead of only Path, py.path

The goal is to avoid referring to the legacy py.path.
This commit is contained in:
Ran Benita 2021-03-15 17:20:55 +02:00
parent 202dd9f423
commit 4690e4c510
2 changed files with 13 additions and 7 deletions

View File

@ -1,5 +1,5 @@
import os
from io import StringIO from io import StringIO
from pathlib import Path
from pprint import pprint from pprint import pprint
from typing import Any from typing import Any
from typing import cast from typing import cast
@ -29,7 +29,6 @@ from _pytest._code.code import ReprTraceback
from _pytest._code.code import TerminalRepr from _pytest._code.code import TerminalRepr
from _pytest._io import TerminalWriter from _pytest._io import TerminalWriter
from _pytest.compat import final from _pytest.compat import final
from _pytest.compat import LEGACY_PATH
from _pytest.config import Config from _pytest.config import Config
from _pytest.nodes import Collector from _pytest.nodes import Collector
from _pytest.nodes import Item from _pytest.nodes import Item
@ -500,8 +499,8 @@ def _report_to_json(report: BaseReport) -> Dict[str, Any]:
else: else:
d["longrepr"] = report.longrepr d["longrepr"] = report.longrepr
for name in d: for name in d:
if isinstance(d[name], (LEGACY_PATH, Path)): if isinstance(d[name], os.PathLike):
d[name] = str(d[name]) d[name] = os.fspath(d[name])
elif name == "result": elif name == "result":
d[name] = None # for now d[name] = None # for now
return d return d

View File

@ -4,7 +4,6 @@ from typing import Union
import pytest import pytest
from _pytest._code.code import ExceptionChainRepr from _pytest._code.code import ExceptionChainRepr
from _pytest._code.code import ExceptionRepr from _pytest._code.code import ExceptionRepr
from _pytest.compat import legacy_path
from _pytest.config import Config from _pytest.config import Config
from _pytest.pytester import Pytester from _pytest.pytester import Pytester
from _pytest.reports import CollectReport from _pytest.reports import CollectReport
@ -225,18 +224,26 @@ class TestReportSerialization:
assert newrep.longrepr == str(rep.longrepr) assert newrep.longrepr == str(rep.longrepr)
def test_paths_support(self, pytester: Pytester) -> None: def test_paths_support(self, pytester: Pytester) -> None:
"""Report attributes which are py.path or pathlib objects should become strings.""" """Report attributes which are path-like should become strings."""
pytester.makepyfile( pytester.makepyfile(
""" """
def test_a(): def test_a():
assert False assert False
""" """
) )
class MyPathLike:
def __init__(self, path: str) -> None:
self.path = path
def __fspath__(self) -> str:
return self.path
reprec = pytester.inline_run() reprec = pytester.inline_run()
reports = reprec.getreports("pytest_runtest_logreport") reports = reprec.getreports("pytest_runtest_logreport")
assert len(reports) == 3 assert len(reports) == 3
test_a_call = reports[1] test_a_call = reports[1]
test_a_call.path1 = legacy_path(pytester.path) # type: ignore[attr-defined] test_a_call.path1 = MyPathLike(str(pytester.path)) # type: ignore[attr-defined]
test_a_call.path2 = pytester.path # type: ignore[attr-defined] test_a_call.path2 = pytester.path # type: ignore[attr-defined]
data = test_a_call._to_json() data = test_a_call._to_json()
assert data["path1"] == str(pytester.path) assert data["path1"] == str(pytester.path)