Merge pull request #8218 from bluetech/reports2
Misc small code improvements
This commit is contained in:
commit
5336ba28cc
|
@ -16,6 +16,7 @@ from typing import Generic
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from typing import Iterator
|
from typing import Iterator
|
||||||
from typing import List
|
from typing import List
|
||||||
|
from typing import MutableMapping
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import overload
|
from typing import overload
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
@ -525,9 +526,10 @@ class FixtureRequest:
|
||||||
return self._pyfuncitem.fspath # type: ignore
|
return self._pyfuncitem.fspath # type: ignore
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def keywords(self):
|
def keywords(self) -> MutableMapping[str, Any]:
|
||||||
"""Keywords/markers dictionary for the underlying node."""
|
"""Keywords/markers dictionary for the underlying node."""
|
||||||
return self.node.keywords
|
node: nodes.Node = self.node
|
||||||
|
return node.keywords
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def session(self) -> "Session":
|
def session(self) -> "Session":
|
||||||
|
@ -607,14 +609,11 @@ class FixtureRequest:
|
||||||
def _get_fixturestack(self) -> List["FixtureDef[Any]"]:
|
def _get_fixturestack(self) -> List["FixtureDef[Any]"]:
|
||||||
current = self
|
current = self
|
||||||
values: List[FixtureDef[Any]] = []
|
values: List[FixtureDef[Any]] = []
|
||||||
while 1:
|
while isinstance(current, SubRequest):
|
||||||
fixturedef = getattr(current, "_fixturedef", None)
|
values.append(current._fixturedef) # type: ignore[has-type]
|
||||||
if fixturedef is None:
|
|
||||||
values.reverse()
|
|
||||||
return values
|
|
||||||
values.append(fixturedef)
|
|
||||||
assert isinstance(current, SubRequest)
|
|
||||||
current = current._parent_request
|
current = current._parent_request
|
||||||
|
values.reverse()
|
||||||
|
return values
|
||||||
|
|
||||||
def _compute_fixture_value(self, fixturedef: "FixtureDef[object]") -> None:
|
def _compute_fixture_value(self, fixturedef: "FixtureDef[object]") -> None:
|
||||||
"""Create a SubRequest based on "self" and call the execute method
|
"""Create a SubRequest based on "self" and call the execute method
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
from _pytest import python
|
from _pytest import python
|
||||||
from _pytest import unittest
|
from _pytest import unittest
|
||||||
from _pytest.config import hookimpl
|
from _pytest.config import hookimpl
|
||||||
|
from _pytest.fixtures import getfixturemarker
|
||||||
from _pytest.nodes import Item
|
from _pytest.nodes import Item
|
||||||
|
|
||||||
|
|
||||||
@hookimpl(trylast=True)
|
@hookimpl(trylast=True)
|
||||||
def pytest_runtest_setup(item):
|
def pytest_runtest_setup(item) -> None:
|
||||||
if is_potential_nosetest(item):
|
if is_potential_nosetest(item):
|
||||||
if not call_optional(item.obj, "setup"):
|
if not call_optional(item.obj, "setup"):
|
||||||
# Call module level setup if there is no object level one.
|
# Call module level setup if there is no object level one.
|
||||||
|
@ -15,7 +16,7 @@ def pytest_runtest_setup(item):
|
||||||
item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item)
|
item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item)
|
||||||
|
|
||||||
|
|
||||||
def teardown_nose(item):
|
def teardown_nose(item) -> None:
|
||||||
if is_potential_nosetest(item):
|
if is_potential_nosetest(item):
|
||||||
if not call_optional(item.obj, "teardown"):
|
if not call_optional(item.obj, "teardown"):
|
||||||
call_optional(item.parent.obj, "teardown")
|
call_optional(item.parent.obj, "teardown")
|
||||||
|
@ -29,11 +30,16 @@ def is_potential_nosetest(item: Item) -> bool:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def call_optional(obj, name):
|
def call_optional(obj: object, name: str) -> bool:
|
||||||
method = getattr(obj, name, None)
|
method = getattr(obj, name, None)
|
||||||
isfixture = hasattr(method, "_pytestfixturefunction")
|
if method is None:
|
||||||
if method is not None and not isfixture and callable(method):
|
return False
|
||||||
# If there's any problems allow the exception to raise rather than
|
is_fixture = getfixturemarker(method) is not None
|
||||||
# silently ignoring them.
|
if is_fixture:
|
||||||
method()
|
return False
|
||||||
return True
|
if not callable(method):
|
||||||
|
return False
|
||||||
|
# If there are any problems allow the exception to raise rather than
|
||||||
|
# silently ignoring it.
|
||||||
|
method()
|
||||||
|
return True
|
||||||
|
|
|
@ -922,10 +922,6 @@ class CallSpec2:
|
||||||
cs._idlist = list(self._idlist)
|
cs._idlist = list(self._idlist)
|
||||||
return cs
|
return cs
|
||||||
|
|
||||||
def _checkargnotcontained(self, arg: str) -> None:
|
|
||||||
if arg in self.params or arg in self.funcargs:
|
|
||||||
raise ValueError(f"duplicate {arg!r}")
|
|
||||||
|
|
||||||
def getparam(self, name: str) -> object:
|
def getparam(self, name: str) -> object:
|
||||||
try:
|
try:
|
||||||
return self.params[name]
|
return self.params[name]
|
||||||
|
@ -947,7 +943,8 @@ class CallSpec2:
|
||||||
param_index: int,
|
param_index: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
for arg, val in zip(argnames, valset):
|
for arg, val in zip(argnames, valset):
|
||||||
self._checkargnotcontained(arg)
|
if arg in self.params or arg in self.funcargs:
|
||||||
|
raise ValueError(f"duplicate {arg!r}")
|
||||||
valtype_for_arg = valtypes[arg]
|
valtype_for_arg = valtypes[arg]
|
||||||
if valtype_for_arg == "params":
|
if valtype_for_arg == "params":
|
||||||
self.params[arg] = val
|
self.params[arg] = val
|
||||||
|
|
|
@ -65,6 +65,7 @@ class BaseReport:
|
||||||
]
|
]
|
||||||
sections: List[Tuple[str, str]]
|
sections: List[Tuple[str, str]]
|
||||||
nodeid: str
|
nodeid: str
|
||||||
|
outcome: "Literal['passed', 'failed', 'skipped']"
|
||||||
|
|
||||||
def __init__(self, **kw: Any) -> None:
|
def __init__(self, **kw: Any) -> None:
|
||||||
self.__dict__.update(kw)
|
self.__dict__.update(kw)
|
||||||
|
@ -141,9 +142,17 @@ class BaseReport:
|
||||||
content for (prefix, content) in self.get_sections("Captured stderr")
|
content for (prefix, content) in self.get_sections("Captured stderr")
|
||||||
)
|
)
|
||||||
|
|
||||||
passed = property(lambda x: x.outcome == "passed")
|
@property
|
||||||
failed = property(lambda x: x.outcome == "failed")
|
def passed(self) -> bool:
|
||||||
skipped = property(lambda x: x.outcome == "skipped")
|
return self.outcome == "passed"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def failed(self) -> bool:
|
||||||
|
return self.outcome == "failed"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def skipped(self) -> bool:
|
||||||
|
return self.outcome == "skipped"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fspath(self) -> str:
|
def fspath(self) -> str:
|
||||||
|
@ -348,8 +357,10 @@ class CollectReport(BaseReport):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
nodeid: str,
|
nodeid: str,
|
||||||
outcome: "Literal['passed', 'skipped', 'failed']",
|
outcome: "Literal['passed', 'failed', 'skipped']",
|
||||||
longrepr,
|
longrepr: Union[
|
||||||
|
None, ExceptionInfo[BaseException], Tuple[str, int, str], str, TerminalRepr
|
||||||
|
],
|
||||||
result: Optional[List[Union[Item, Collector]]],
|
result: Optional[List[Union[Item, Collector]]],
|
||||||
sections: Iterable[Tuple[str, str]] = (),
|
sections: Iterable[Tuple[str, str]] = (),
|
||||||
**extra,
|
**extra,
|
||||||
|
|
|
@ -3,6 +3,7 @@ from typing import Any
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest import runner
|
from _pytest import runner
|
||||||
from _pytest._code import getfslineno
|
from _pytest._code import getfslineno
|
||||||
|
from _pytest.fixtures import getfixturemarker
|
||||||
from _pytest.pytester import Pytester
|
from _pytest.pytester import Pytester
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,7 +335,8 @@ class TestReRunTests:
|
||||||
def test_pytestconfig_is_session_scoped() -> None:
|
def test_pytestconfig_is_session_scoped() -> None:
|
||||||
from _pytest.fixtures import pytestconfig
|
from _pytest.fixtures import pytestconfig
|
||||||
|
|
||||||
marker = pytestconfig._pytestfixturefunction # type: ignore
|
marker = getfixturemarker(pytestconfig)
|
||||||
|
assert marker is not None
|
||||||
assert marker.scope == "session"
|
assert marker.scope == "session"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2230,19 +2230,19 @@ def test_skip_reasons_folding() -> None:
|
||||||
|
|
||||||
ev1 = cast(CollectReport, X())
|
ev1 = cast(CollectReport, X())
|
||||||
ev1.when = "execute"
|
ev1.when = "execute"
|
||||||
ev1.skipped = True
|
ev1.skipped = True # type: ignore[misc]
|
||||||
ev1.longrepr = longrepr
|
ev1.longrepr = longrepr
|
||||||
|
|
||||||
ev2 = cast(CollectReport, X())
|
ev2 = cast(CollectReport, X())
|
||||||
ev2.when = "execute"
|
ev2.when = "execute"
|
||||||
ev2.longrepr = longrepr
|
ev2.longrepr = longrepr
|
||||||
ev2.skipped = True
|
ev2.skipped = True # type: ignore[misc]
|
||||||
|
|
||||||
# ev3 might be a collection report
|
# ev3 might be a collection report
|
||||||
ev3 = cast(CollectReport, X())
|
ev3 = cast(CollectReport, X())
|
||||||
ev3.when = "collect"
|
ev3.when = "collect"
|
||||||
ev3.longrepr = longrepr
|
ev3.longrepr = longrepr
|
||||||
ev3.skipped = True
|
ev3.skipped = True # type: ignore[misc]
|
||||||
|
|
||||||
values = _folded_skips(Path.cwd(), [ev1, ev2, ev3])
|
values = _folded_skips(Path.cwd(), [ev1, ev2, ev3])
|
||||||
assert len(values) == 1
|
assert len(values) == 1
|
||||||
|
|
Loading…
Reference in New Issue