Improve types around repr_failure()
This commit is contained in:
parent
54ad048be7
commit
2b05faff0a
|
@ -47,7 +47,7 @@ if TYPE_CHECKING:
|
||||||
from typing_extensions import Literal
|
from typing_extensions import Literal
|
||||||
from weakref import ReferenceType
|
from weakref import ReferenceType
|
||||||
|
|
||||||
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value"]
|
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
|
||||||
|
|
||||||
|
|
||||||
class Code:
|
class Code:
|
||||||
|
|
|
@ -300,7 +300,10 @@ class DoctestItem(pytest.Item):
|
||||||
sys.stdout.write(out)
|
sys.stdout.write(out)
|
||||||
sys.stderr.write(err)
|
sys.stderr.write(err)
|
||||||
|
|
||||||
def repr_failure(self, excinfo):
|
# TODO: Type ignored -- breaks Liskov Substitution.
|
||||||
|
def repr_failure( # type: ignore[override] # noqa: F821
|
||||||
|
self, excinfo: ExceptionInfo[BaseException],
|
||||||
|
) -> Union[str, TerminalRepr]:
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
failures = (
|
failures = (
|
||||||
|
|
|
@ -17,9 +17,8 @@ import py
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
from _pytest._code import getfslineno
|
from _pytest._code import getfslineno
|
||||||
from _pytest._code.code import ExceptionChainRepr
|
|
||||||
from _pytest._code.code import ExceptionInfo
|
from _pytest._code.code import ExceptionInfo
|
||||||
from _pytest._code.code import ReprExceptionInfo
|
from _pytest._code.code import TerminalRepr
|
||||||
from _pytest.compat import cached_property
|
from _pytest.compat import cached_property
|
||||||
from _pytest.compat import overload
|
from _pytest.compat import overload
|
||||||
from _pytest.compat import TYPE_CHECKING
|
from _pytest.compat import TYPE_CHECKING
|
||||||
|
@ -29,7 +28,6 @@ from _pytest.config import PytestPluginManager
|
||||||
from _pytest.deprecated import NODE_USE_FROM_PARENT
|
from _pytest.deprecated import NODE_USE_FROM_PARENT
|
||||||
from _pytest.fixtures import FixtureDef
|
from _pytest.fixtures import FixtureDef
|
||||||
from _pytest.fixtures import FixtureLookupError
|
from _pytest.fixtures import FixtureLookupError
|
||||||
from _pytest.fixtures import FixtureLookupErrorRepr
|
|
||||||
from _pytest.mark.structures import Mark
|
from _pytest.mark.structures import Mark
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
from _pytest.mark.structures import NodeKeywords
|
from _pytest.mark.structures import NodeKeywords
|
||||||
|
@ -43,6 +41,7 @@ if TYPE_CHECKING:
|
||||||
# Imported here due to circular import.
|
# Imported here due to circular import.
|
||||||
from _pytest.main import Session
|
from _pytest.main import Session
|
||||||
from _pytest.warning_types import PytestWarning
|
from _pytest.warning_types import PytestWarning
|
||||||
|
from _pytest._code.code import _TracebackStyle
|
||||||
|
|
||||||
|
|
||||||
SEP = "/"
|
SEP = "/"
|
||||||
|
@ -355,8 +354,10 @@ class Node(metaclass=NodeMeta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _repr_failure_py(
|
def _repr_failure_py(
|
||||||
self, excinfo: ExceptionInfo[BaseException], style=None,
|
self,
|
||||||
) -> Union[str, ReprExceptionInfo, ExceptionChainRepr, FixtureLookupErrorRepr]:
|
excinfo: ExceptionInfo[BaseException],
|
||||||
|
style: "Optional[_TracebackStyle]" = None,
|
||||||
|
) -> TerminalRepr:
|
||||||
if isinstance(excinfo.value, ConftestImportFailure):
|
if isinstance(excinfo.value, ConftestImportFailure):
|
||||||
excinfo = ExceptionInfo(excinfo.value.excinfo)
|
excinfo = ExceptionInfo(excinfo.value.excinfo)
|
||||||
if isinstance(excinfo.value, fail.Exception):
|
if isinstance(excinfo.value, fail.Exception):
|
||||||
|
@ -406,8 +407,10 @@ class Node(metaclass=NodeMeta):
|
||||||
)
|
)
|
||||||
|
|
||||||
def repr_failure(
|
def repr_failure(
|
||||||
self, excinfo, style=None
|
self,
|
||||||
) -> Union[str, ReprExceptionInfo, ExceptionChainRepr, FixtureLookupErrorRepr]:
|
excinfo: ExceptionInfo[BaseException],
|
||||||
|
style: "Optional[_TracebackStyle]" = None,
|
||||||
|
) -> Union[str, TerminalRepr]:
|
||||||
"""
|
"""
|
||||||
Return a representation of a collection or test failure.
|
Return a representation of a collection or test failure.
|
||||||
|
|
||||||
|
@ -453,13 +456,16 @@ class Collector(Node):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError("abstract")
|
raise NotImplementedError("abstract")
|
||||||
|
|
||||||
def repr_failure(self, excinfo):
|
# TODO: This omits the style= parameter which breaks Liskov Substitution.
|
||||||
|
def repr_failure( # type: ignore[override] # noqa: F821
|
||||||
|
self, excinfo: ExceptionInfo[BaseException]
|
||||||
|
) -> Union[str, TerminalRepr]:
|
||||||
"""
|
"""
|
||||||
Return a representation of a collection failure.
|
Return a representation of a collection failure.
|
||||||
|
|
||||||
:param excinfo: Exception information for the failure.
|
:param excinfo: Exception information for the failure.
|
||||||
"""
|
"""
|
||||||
if excinfo.errisinstance(self.CollectError) and not self.config.getoption(
|
if isinstance(excinfo.value, self.CollectError) and not self.config.getoption(
|
||||||
"fulltrace", False
|
"fulltrace", False
|
||||||
):
|
):
|
||||||
exc = excinfo.value
|
exc = excinfo.value
|
||||||
|
|
|
@ -60,6 +60,7 @@ from _pytest.mark.structures import normalize_mark_list
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
from _pytest.outcomes import skip
|
from _pytest.outcomes import skip
|
||||||
from _pytest.pathlib import parts
|
from _pytest.pathlib import parts
|
||||||
|
from _pytest.reports import TerminalRepr
|
||||||
from _pytest.warning_types import PytestCollectionWarning
|
from _pytest.warning_types import PytestCollectionWarning
|
||||||
from _pytest.warning_types import PytestUnhandledCoroutineWarning
|
from _pytest.warning_types import PytestUnhandledCoroutineWarning
|
||||||
|
|
||||||
|
@ -1591,7 +1592,10 @@ class Function(PyobjMixin, nodes.Item):
|
||||||
for entry in excinfo.traceback[1:-1]:
|
for entry in excinfo.traceback[1:-1]:
|
||||||
entry.set_repr_style("short")
|
entry.set_repr_style("short")
|
||||||
|
|
||||||
def repr_failure(self, excinfo, outerr=None):
|
# TODO: Type ignored -- breaks Liskov Substitution.
|
||||||
|
def repr_failure( # type: ignore[override] # noqa: F821
|
||||||
|
self, excinfo: ExceptionInfo[BaseException], outerr: None = None
|
||||||
|
) -> Union[str, TerminalRepr]:
|
||||||
assert outerr is None, "XXX outerr usage is deprecated"
|
assert outerr is None, "XXX outerr usage is deprecated"
|
||||||
style = self.config.getoption("tbstyle", "auto")
|
style = self.config.getoption("tbstyle", "auto")
|
||||||
if style == "auto":
|
if style == "auto":
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import bdb
|
import bdb
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import cast
|
from typing import cast
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
@ -256,7 +257,7 @@ class CallInfo(Generic[_T]):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_result = attr.ib(type="Optional[_T]")
|
_result = attr.ib(type="Optional[_T]")
|
||||||
excinfo = attr.ib(type=Optional[ExceptionInfo])
|
excinfo = attr.ib(type=Optional[ExceptionInfo[BaseException]])
|
||||||
start = attr.ib(type=float)
|
start = attr.ib(type=float)
|
||||||
stop = attr.ib(type=float)
|
stop = attr.ib(type=float)
|
||||||
duration = attr.ib(type=float)
|
duration = attr.ib(type=float)
|
||||||
|
@ -313,7 +314,8 @@ def pytest_runtest_makereport(item: Item, call: CallInfo[None]) -> TestReport:
|
||||||
|
|
||||||
def pytest_make_collect_report(collector: Collector) -> CollectReport:
|
def pytest_make_collect_report(collector: Collector) -> CollectReport:
|
||||||
call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
|
call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
|
||||||
longrepr = None
|
# TODO: Better typing for longrepr.
|
||||||
|
longrepr = None # type: Optional[Any]
|
||||||
if not call.excinfo:
|
if not call.excinfo:
|
||||||
outcome = "passed" # type: Literal["passed", "skipped", "failed"]
|
outcome = "passed" # type: Literal["passed", "skipped", "failed"]
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -148,7 +148,8 @@ def pytest_runtest_makereport(item: Item, call: CallInfo[None]):
|
||||||
|
|
||||||
elif item.config.option.runxfail:
|
elif item.config.option.runxfail:
|
||||||
pass # don't interfere
|
pass # don't interfere
|
||||||
elif call.excinfo and call.excinfo.errisinstance(xfail.Exception):
|
elif call.excinfo and isinstance(call.excinfo.value, xfail.Exception):
|
||||||
|
assert call.excinfo.value.msg is not None
|
||||||
rep.wasxfail = "reason: " + call.excinfo.value.msg
|
rep.wasxfail = "reason: " + call.excinfo.value.msg
|
||||||
rep.outcome = "skipped"
|
rep.outcome = "skipped"
|
||||||
elif evalxfail and not rep.skipped and evalxfail.wasvalid() and evalxfail.istrue():
|
elif evalxfail and not rep.skipped and evalxfail.wasvalid() and evalxfail.istrue():
|
||||||
|
|
Loading…
Reference in New Issue