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