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 weakref import ReferenceType | ||||
| 
 | ||||
|     _TracebackStyle = Literal["long", "short", "line", "no", "native", "value"] | ||||
|     _TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"] | ||||
| 
 | ||||
| 
 | ||||
| class Code: | ||||
|  |  | |||
|  | @ -300,7 +300,10 @@ class DoctestItem(pytest.Item): | |||
|             sys.stdout.write(out) | ||||
|             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 | ||||
| 
 | ||||
|         failures = ( | ||||
|  |  | |||
|  | @ -17,9 +17,8 @@ import py | |||
| 
 | ||||
| import _pytest._code | ||||
| from _pytest._code import getfslineno | ||||
| from _pytest._code.code import ExceptionChainRepr | ||||
| 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 overload | ||||
| 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.fixtures import FixtureDef | ||||
| from _pytest.fixtures import FixtureLookupError | ||||
| from _pytest.fixtures import FixtureLookupErrorRepr | ||||
| from _pytest.mark.structures import Mark | ||||
| from _pytest.mark.structures import MarkDecorator | ||||
| from _pytest.mark.structures import NodeKeywords | ||||
|  | @ -43,6 +41,7 @@ if TYPE_CHECKING: | |||
|     # Imported here due to circular import. | ||||
|     from _pytest.main import Session | ||||
|     from _pytest.warning_types import PytestWarning | ||||
|     from _pytest._code.code import _TracebackStyle | ||||
| 
 | ||||
| 
 | ||||
| SEP = "/" | ||||
|  | @ -355,8 +354,10 @@ class Node(metaclass=NodeMeta): | |||
|         pass | ||||
| 
 | ||||
|     def _repr_failure_py( | ||||
|         self, excinfo: ExceptionInfo[BaseException], style=None, | ||||
|     ) -> Union[str, ReprExceptionInfo, ExceptionChainRepr, FixtureLookupErrorRepr]: | ||||
|         self, | ||||
|         excinfo: ExceptionInfo[BaseException], | ||||
|         style: "Optional[_TracebackStyle]" = None, | ||||
|     ) -> TerminalRepr: | ||||
|         if isinstance(excinfo.value, ConftestImportFailure): | ||||
|             excinfo = ExceptionInfo(excinfo.value.excinfo) | ||||
|         if isinstance(excinfo.value, fail.Exception): | ||||
|  | @ -406,8 +407,10 @@ class Node(metaclass=NodeMeta): | |||
|         ) | ||||
| 
 | ||||
|     def repr_failure( | ||||
|         self, excinfo, style=None | ||||
|     ) -> Union[str, ReprExceptionInfo, ExceptionChainRepr, FixtureLookupErrorRepr]: | ||||
|         self, | ||||
|         excinfo: ExceptionInfo[BaseException], | ||||
|         style: "Optional[_TracebackStyle]" = None, | ||||
|     ) -> Union[str, TerminalRepr]: | ||||
|         """ | ||||
|         Return a representation of a collection or test failure. | ||||
| 
 | ||||
|  | @ -453,13 +456,16 @@ class Collector(Node): | |||
|         """ | ||||
|         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. | ||||
| 
 | ||||
|         :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 | ||||
|         ): | ||||
|             exc = excinfo.value | ||||
|  |  | |||
|  | @ -60,6 +60,7 @@ from _pytest.mark.structures import normalize_mark_list | |||
| from _pytest.outcomes import fail | ||||
| from _pytest.outcomes import skip | ||||
| from _pytest.pathlib import parts | ||||
| from _pytest.reports import TerminalRepr | ||||
| from _pytest.warning_types import PytestCollectionWarning | ||||
| from _pytest.warning_types import PytestUnhandledCoroutineWarning | ||||
| 
 | ||||
|  | @ -1591,7 +1592,10 @@ class Function(PyobjMixin, nodes.Item): | |||
|                     for entry in excinfo.traceback[1:-1]: | ||||
|                         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" | ||||
|         style = self.config.getoption("tbstyle", "auto") | ||||
|         if style == "auto": | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| import bdb | ||||
| import os | ||||
| import sys | ||||
| from typing import Any | ||||
| from typing import Callable | ||||
| from typing import cast | ||||
| from typing import Dict | ||||
|  | @ -256,7 +257,7 @@ class CallInfo(Generic[_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) | ||||
|     stop = 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: | ||||
|     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: | ||||
|         outcome = "passed"  # type: Literal["passed", "skipped", "failed"] | ||||
|     else: | ||||
|  |  | |||
|  | @ -148,7 +148,8 @@ def pytest_runtest_makereport(item: Item, call: CallInfo[None]): | |||
| 
 | ||||
|     elif item.config.option.runxfail: | ||||
|         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.outcome = "skipped" | ||||
|     elif evalxfail and not rep.skipped and evalxfail.wasvalid() and evalxfail.istrue(): | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue