typing: set disallow_any_generics
This prevents referring to a generic type without filling in its generic type parameters. The FixtureDef typing might need some more refining in the future.
This commit is contained in:
parent
49827adcb9
commit
be656dd4e4
|
@ -96,6 +96,7 @@ formats = sdist.tgz,bdist_wheel
|
||||||
[mypy]
|
[mypy]
|
||||||
mypy_path = src
|
mypy_path = src
|
||||||
check_untyped_defs = True
|
check_untyped_defs = True
|
||||||
|
disallow_any_generics = True
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
no_implicit_optional = True
|
no_implicit_optional = True
|
||||||
show_error_codes = True
|
show_error_codes = True
|
||||||
|
|
|
@ -613,7 +613,7 @@ class ExceptionInfo(Generic[_E]):
|
||||||
)
|
)
|
||||||
return fmt.repr_excinfo(self)
|
return fmt.repr_excinfo(self)
|
||||||
|
|
||||||
def match(self, regexp: "Union[str, Pattern]") -> "Literal[True]":
|
def match(self, regexp: "Union[str, Pattern[str]]") -> "Literal[True]":
|
||||||
"""Check whether the regular expression `regexp` matches the string
|
"""Check whether the regular expression `regexp` matches the string
|
||||||
representation of the exception using :func:`python:re.search`.
|
representation of the exception using :func:`python:re.search`.
|
||||||
|
|
||||||
|
@ -678,7 +678,7 @@ class FormattedExcinfo:
|
||||||
self,
|
self,
|
||||||
source: "Source",
|
source: "Source",
|
||||||
line_index: int = -1,
|
line_index: int = -1,
|
||||||
excinfo: Optional[ExceptionInfo] = None,
|
excinfo: Optional[ExceptionInfo[BaseException]] = None,
|
||||||
short: bool = False,
|
short: bool = False,
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
"""Return formatted and marked up source lines."""
|
"""Return formatted and marked up source lines."""
|
||||||
|
@ -703,7 +703,10 @@ class FormattedExcinfo:
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def get_exconly(
|
def get_exconly(
|
||||||
self, excinfo: ExceptionInfo, indent: int = 4, markall: bool = False
|
self,
|
||||||
|
excinfo: ExceptionInfo[BaseException],
|
||||||
|
indent: int = 4,
|
||||||
|
markall: bool = False,
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
lines = []
|
lines = []
|
||||||
indentstr = " " * indent
|
indentstr = " " * indent
|
||||||
|
@ -743,7 +746,9 @@ class FormattedExcinfo:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def repr_traceback_entry(
|
def repr_traceback_entry(
|
||||||
self, entry: TracebackEntry, excinfo: Optional[ExceptionInfo] = None
|
self,
|
||||||
|
entry: TracebackEntry,
|
||||||
|
excinfo: Optional[ExceptionInfo[BaseException]] = None,
|
||||||
) -> "ReprEntry":
|
) -> "ReprEntry":
|
||||||
lines = [] # type: List[str]
|
lines = [] # type: List[str]
|
||||||
style = entry._repr_style if entry._repr_style is not None else self.style
|
style = entry._repr_style if entry._repr_style is not None else self.style
|
||||||
|
@ -785,7 +790,7 @@ class FormattedExcinfo:
|
||||||
path = np
|
path = np
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def repr_traceback(self, excinfo: ExceptionInfo) -> "ReprTraceback":
|
def repr_traceback(self, excinfo: ExceptionInfo[BaseException]) -> "ReprTraceback":
|
||||||
traceback = excinfo.traceback
|
traceback = excinfo.traceback
|
||||||
if self.tbfilter:
|
if self.tbfilter:
|
||||||
traceback = traceback.filter()
|
traceback = traceback.filter()
|
||||||
|
@ -850,12 +855,14 @@ class FormattedExcinfo:
|
||||||
|
|
||||||
return traceback, extraline
|
return traceback, extraline
|
||||||
|
|
||||||
def repr_excinfo(self, excinfo: ExceptionInfo) -> "ExceptionChainRepr":
|
def repr_excinfo(
|
||||||
|
self, excinfo: ExceptionInfo[BaseException]
|
||||||
|
) -> "ExceptionChainRepr":
|
||||||
repr_chain = (
|
repr_chain = (
|
||||||
[]
|
[]
|
||||||
) # type: List[Tuple[ReprTraceback, Optional[ReprFileLocation], Optional[str]]]
|
) # type: List[Tuple[ReprTraceback, Optional[ReprFileLocation], Optional[str]]]
|
||||||
e = excinfo.value
|
e = excinfo.value # type: Optional[BaseException]
|
||||||
excinfo_ = excinfo # type: Optional[ExceptionInfo]
|
excinfo_ = excinfo # type: Optional[ExceptionInfo[BaseException]]
|
||||||
descr = None
|
descr = None
|
||||||
seen = set() # type: Set[int]
|
seen = set() # type: Set[int]
|
||||||
while e is not None and id(e) not in seen:
|
while e is not None and id(e) not in seen:
|
||||||
|
|
|
@ -710,7 +710,7 @@ class AssertionRewriter(ast.NodeVisitor):
|
||||||
node = nodes.pop()
|
node = nodes.pop()
|
||||||
for name, field in ast.iter_fields(node):
|
for name, field in ast.iter_fields(node):
|
||||||
if isinstance(field, list):
|
if isinstance(field, list):
|
||||||
new = [] # type: List
|
new = [] # type: List[ast.AST]
|
||||||
for i, child in enumerate(field):
|
for i, child in enumerate(field):
|
||||||
if isinstance(child, ast.Assert):
|
if isinstance(child, ast.Assert):
|
||||||
# Transform assert.
|
# Transform assert.
|
||||||
|
|
|
@ -181,7 +181,7 @@ class LFPluginCollWrapper:
|
||||||
self._collected_at_least_one_failure = False
|
self._collected_at_least_one_failure = False
|
||||||
|
|
||||||
@pytest.hookimpl(hookwrapper=True)
|
@pytest.hookimpl(hookwrapper=True)
|
||||||
def pytest_make_collect_report(self, collector: nodes.Collector) -> Generator:
|
def pytest_make_collect_report(self, collector: nodes.Collector):
|
||||||
if isinstance(collector, Session):
|
if isinstance(collector, Session):
|
||||||
out = yield
|
out = yield
|
||||||
res = out.get_result() # type: CollectReport
|
res = out.get_result() # type: CollectReport
|
||||||
|
|
|
@ -3,7 +3,10 @@ import argparse
|
||||||
import functools
|
import functools
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
from typing import Any
|
||||||
|
from typing import Callable
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
|
from typing import List
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
@ -91,7 +94,7 @@ class pytestPDB:
|
||||||
|
|
||||||
_pluginmanager = None # type: PytestPluginManager
|
_pluginmanager = None # type: PytestPluginManager
|
||||||
_config = None # type: Config
|
_config = None # type: Config
|
||||||
_saved = [] # type: list
|
_saved = [] # type: List[Tuple[Callable[..., None], PytestPluginManager, Config]]
|
||||||
_recursive_debug = 0
|
_recursive_debug = 0
|
||||||
_wrapped_pdb_cls = None
|
_wrapped_pdb_cls = None
|
||||||
|
|
||||||
|
@ -274,7 +277,7 @@ class pytestPDB:
|
||||||
|
|
||||||
class PdbInvoke:
|
class PdbInvoke:
|
||||||
def pytest_exception_interact(
|
def pytest_exception_interact(
|
||||||
self, node: Node, call: "CallInfo", report: BaseReport
|
self, node: Node, call: "CallInfo[Any]", report: BaseReport
|
||||||
) -> None:
|
) -> None:
|
||||||
capman = node.config.pluginmanager.getplugin("capturemanager")
|
capman = node.config.pluginmanager.getplugin("capturemanager")
|
||||||
if capman:
|
if capman:
|
||||||
|
|
|
@ -94,8 +94,8 @@ _FixtureCachedResult = Union[
|
||||||
|
|
||||||
|
|
||||||
@attr.s(frozen=True)
|
@attr.s(frozen=True)
|
||||||
class PseudoFixtureDef:
|
class PseudoFixtureDef(Generic[_FixtureValue]):
|
||||||
cached_result = attr.ib(type="_FixtureCachedResult")
|
cached_result = attr.ib(type="_FixtureCachedResult[_FixtureValue]")
|
||||||
scope = attr.ib(type="_Scope")
|
scope = attr.ib(type="_Scope")
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ def scopeproperty(name=None, doc=None):
|
||||||
return decoratescope
|
return decoratescope
|
||||||
|
|
||||||
|
|
||||||
def get_scope_package(node, fixturedef: "FixtureDef"):
|
def get_scope_package(node, fixturedef: "FixtureDef[object]"):
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
cls = pytest.Package
|
cls = pytest.Package
|
||||||
|
@ -397,7 +397,7 @@ class FuncFixtureInfo:
|
||||||
# definitions.
|
# definitions.
|
||||||
initialnames = attr.ib(type=Tuple[str, ...])
|
initialnames = attr.ib(type=Tuple[str, ...])
|
||||||
names_closure = attr.ib(type=List[str])
|
names_closure = attr.ib(type=List[str])
|
||||||
name2fixturedefs = attr.ib(type=Dict[str, Sequence["FixtureDef"]])
|
name2fixturedefs = attr.ib(type=Dict[str, Sequence["FixtureDef[Any]"]])
|
||||||
|
|
||||||
def prune_dependency_tree(self) -> None:
|
def prune_dependency_tree(self) -> None:
|
||||||
"""Recompute names_closure from initialnames and name2fixturedefs.
|
"""Recompute names_closure from initialnames and name2fixturedefs.
|
||||||
|
@ -441,7 +441,7 @@ class FixtureRequest:
|
||||||
self.fixturename = None # type: Optional[str]
|
self.fixturename = None # type: Optional[str]
|
||||||
#: Scope string, one of "function", "class", "module", "session".
|
#: Scope string, one of "function", "class", "module", "session".
|
||||||
self.scope = "function" # type: _Scope
|
self.scope = "function" # type: _Scope
|
||||||
self._fixture_defs = {} # type: Dict[str, FixtureDef]
|
self._fixture_defs = {} # type: Dict[str, FixtureDef[Any]]
|
||||||
fixtureinfo = pyfuncitem._fixtureinfo # type: FuncFixtureInfo
|
fixtureinfo = pyfuncitem._fixtureinfo # type: FuncFixtureInfo
|
||||||
self._arg2fixturedefs = fixtureinfo.name2fixturedefs.copy()
|
self._arg2fixturedefs = fixtureinfo.name2fixturedefs.copy()
|
||||||
self._arg2index = {} # type: Dict[str, int]
|
self._arg2index = {} # type: Dict[str, int]
|
||||||
|
@ -467,7 +467,7 @@ class FixtureRequest:
|
||||||
"""Underlying collection node (depends on current request scope)."""
|
"""Underlying collection node (depends on current request scope)."""
|
||||||
return self._getscopeitem(self.scope)
|
return self._getscopeitem(self.scope)
|
||||||
|
|
||||||
def _getnextfixturedef(self, argname: str) -> "FixtureDef":
|
def _getnextfixturedef(self, argname: str) -> "FixtureDef[Any]":
|
||||||
fixturedefs = self._arg2fixturedefs.get(argname, None)
|
fixturedefs = self._arg2fixturedefs.get(argname, None)
|
||||||
if fixturedefs is None:
|
if fixturedefs is None:
|
||||||
# We arrive here because of a dynamic call to
|
# We arrive here because of a dynamic call to
|
||||||
|
@ -586,7 +586,7 @@ class FixtureRequest:
|
||||||
|
|
||||||
def _get_active_fixturedef(
|
def _get_active_fixturedef(
|
||||||
self, argname: str
|
self, argname: str
|
||||||
) -> Union["FixtureDef", PseudoFixtureDef]:
|
) -> Union["FixtureDef[object]", PseudoFixtureDef[object]]:
|
||||||
try:
|
try:
|
||||||
return self._fixture_defs[argname]
|
return self._fixture_defs[argname]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -604,9 +604,9 @@ class FixtureRequest:
|
||||||
self._fixture_defs[argname] = fixturedef
|
self._fixture_defs[argname] = fixturedef
|
||||||
return fixturedef
|
return fixturedef
|
||||||
|
|
||||||
def _get_fixturestack(self) -> List["FixtureDef"]:
|
def _get_fixturestack(self) -> List["FixtureDef[Any]"]:
|
||||||
current = self
|
current = self
|
||||||
values = [] # type: List[FixtureDef]
|
values = [] # type: List[FixtureDef[Any]]
|
||||||
while 1:
|
while 1:
|
||||||
fixturedef = getattr(current, "_fixturedef", None)
|
fixturedef = getattr(current, "_fixturedef", None)
|
||||||
if fixturedef is None:
|
if fixturedef is None:
|
||||||
|
@ -616,7 +616,7 @@ class FixtureRequest:
|
||||||
assert isinstance(current, SubRequest)
|
assert isinstance(current, SubRequest)
|
||||||
current = current._parent_request
|
current = current._parent_request
|
||||||
|
|
||||||
def _compute_fixture_value(self, fixturedef: "FixtureDef") -> 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
|
||||||
of the given FixtureDef object.
|
of the given FixtureDef object.
|
||||||
|
|
||||||
|
@ -689,7 +689,7 @@ class FixtureRequest:
|
||||||
self._schedule_finalizers(fixturedef, subrequest)
|
self._schedule_finalizers(fixturedef, subrequest)
|
||||||
|
|
||||||
def _schedule_finalizers(
|
def _schedule_finalizers(
|
||||||
self, fixturedef: "FixtureDef", subrequest: "SubRequest"
|
self, fixturedef: "FixtureDef[object]", subrequest: "SubRequest"
|
||||||
) -> None:
|
) -> None:
|
||||||
# If fixture function failed it might have registered finalizers.
|
# If fixture function failed it might have registered finalizers.
|
||||||
self.session._setupstate.addfinalizer(
|
self.session._setupstate.addfinalizer(
|
||||||
|
@ -751,7 +751,7 @@ class SubRequest(FixtureRequest):
|
||||||
scope: "_Scope",
|
scope: "_Scope",
|
||||||
param,
|
param,
|
||||||
param_index: int,
|
param_index: int,
|
||||||
fixturedef: "FixtureDef",
|
fixturedef: "FixtureDef[object]",
|
||||||
) -> None:
|
) -> None:
|
||||||
self._parent_request = request
|
self._parent_request = request
|
||||||
self.fixturename = fixturedef.argname
|
self.fixturename = fixturedef.argname
|
||||||
|
@ -773,7 +773,7 @@ class SubRequest(FixtureRequest):
|
||||||
self._fixturedef.addfinalizer(finalizer)
|
self._fixturedef.addfinalizer(finalizer)
|
||||||
|
|
||||||
def _schedule_finalizers(
|
def _schedule_finalizers(
|
||||||
self, fixturedef: "FixtureDef", subrequest: "SubRequest"
|
self, fixturedef: "FixtureDef[object]", subrequest: "SubRequest"
|
||||||
) -> None:
|
) -> None:
|
||||||
# If the executing fixturedef was not explicitly requested in the argument list (via
|
# If the executing fixturedef was not explicitly requested in the argument list (via
|
||||||
# getfixturevalue inside the fixture call) then ensure this fixture def will be finished
|
# getfixturevalue inside the fixture call) then ensure this fixture def will be finished
|
||||||
|
@ -1456,8 +1456,8 @@ class FixtureManager:
|
||||||
def __init__(self, session: "Session") -> None:
|
def __init__(self, session: "Session") -> None:
|
||||||
self.session = session
|
self.session = session
|
||||||
self.config = session.config # type: Config
|
self.config = session.config # type: Config
|
||||||
self._arg2fixturedefs = {} # type: Dict[str, List[FixtureDef]]
|
self._arg2fixturedefs = {} # type: Dict[str, List[FixtureDef[Any]]]
|
||||||
self._holderobjseen = set() # type: Set
|
self._holderobjseen = set() # type: Set[object]
|
||||||
self._nodeid_and_autousenames = [
|
self._nodeid_and_autousenames = [
|
||||||
("", self.config.getini("usefixtures"))
|
("", self.config.getini("usefixtures"))
|
||||||
] # type: List[Tuple[str, List[str]]]
|
] # type: List[Tuple[str, List[str]]]
|
||||||
|
@ -1534,7 +1534,7 @@ class FixtureManager:
|
||||||
|
|
||||||
def getfixtureclosure(
|
def getfixtureclosure(
|
||||||
self, fixturenames: Tuple[str, ...], parentnode, ignore_args: Sequence[str] = ()
|
self, fixturenames: Tuple[str, ...], parentnode, ignore_args: Sequence[str] = ()
|
||||||
) -> Tuple[Tuple[str, ...], List[str], Dict[str, Sequence[FixtureDef]]]:
|
) -> Tuple[Tuple[str, ...], List[str], Dict[str, Sequence[FixtureDef[Any]]]]:
|
||||||
# Collect the closure of all fixtures, starting with the given
|
# Collect the closure of all fixtures, starting with the given
|
||||||
# fixturenames as the initial set. As we have to visit all
|
# fixturenames as the initial set. As we have to visit all
|
||||||
# factory definitions anyway, we also return an arg2fixturedefs
|
# factory definitions anyway, we also return an arg2fixturedefs
|
||||||
|
@ -1557,7 +1557,7 @@ class FixtureManager:
|
||||||
# need to return it as well, so save this.
|
# need to return it as well, so save this.
|
||||||
initialnames = tuple(fixturenames_closure)
|
initialnames = tuple(fixturenames_closure)
|
||||||
|
|
||||||
arg2fixturedefs = {} # type: Dict[str, Sequence[FixtureDef]]
|
arg2fixturedefs = {} # type: Dict[str, Sequence[FixtureDef[Any]]]
|
||||||
lastlen = -1
|
lastlen = -1
|
||||||
while lastlen != len(fixturenames_closure):
|
while lastlen != len(fixturenames_closure):
|
||||||
lastlen = len(fixturenames_closure)
|
lastlen = len(fixturenames_closure)
|
||||||
|
@ -1677,7 +1677,7 @@ class FixtureManager:
|
||||||
|
|
||||||
def getfixturedefs(
|
def getfixturedefs(
|
||||||
self, argname: str, nodeid: str
|
self, argname: str, nodeid: str
|
||||||
) -> Optional[Sequence[FixtureDef]]:
|
) -> Optional[Sequence[FixtureDef[Any]]]:
|
||||||
"""Get a list of fixtures which are applicable to the given node id.
|
"""Get a list of fixtures which are applicable to the given node id.
|
||||||
|
|
||||||
:param str argname: Name of the fixture to search for.
|
:param str argname: Name of the fixture to search for.
|
||||||
|
@ -1691,8 +1691,8 @@ class FixtureManager:
|
||||||
return tuple(self._matchfactories(fixturedefs, nodeid))
|
return tuple(self._matchfactories(fixturedefs, nodeid))
|
||||||
|
|
||||||
def _matchfactories(
|
def _matchfactories(
|
||||||
self, fixturedefs: Iterable[FixtureDef], nodeid: str
|
self, fixturedefs: Iterable[FixtureDef[Any]], nodeid: str
|
||||||
) -> Iterator[FixtureDef]:
|
) -> Iterator[FixtureDef[Any]]:
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
|
|
||||||
for fixturedef in fixturedefs:
|
for fixturedef in fixturedefs:
|
||||||
|
|
|
@ -533,7 +533,7 @@ def pytest_report_from_serializable(
|
||||||
|
|
||||||
@hookspec(firstresult=True)
|
@hookspec(firstresult=True)
|
||||||
def pytest_fixture_setup(
|
def pytest_fixture_setup(
|
||||||
fixturedef: "FixtureDef", request: "SubRequest"
|
fixturedef: "FixtureDef[Any]", request: "SubRequest"
|
||||||
) -> Optional[object]:
|
) -> Optional[object]:
|
||||||
"""Perform fixture setup execution.
|
"""Perform fixture setup execution.
|
||||||
|
|
||||||
|
@ -549,7 +549,7 @@ def pytest_fixture_setup(
|
||||||
|
|
||||||
|
|
||||||
def pytest_fixture_post_finalizer(
|
def pytest_fixture_post_finalizer(
|
||||||
fixturedef: "FixtureDef", request: "SubRequest"
|
fixturedef: "FixtureDef[Any]", request: "SubRequest"
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Called after fixture teardown, but before the cache is cleared, so
|
"""Called after fixture teardown, but before the cache is cleared, so
|
||||||
the fixture result ``fixturedef.cached_result`` is still available (not
|
the fixture result ``fixturedef.cached_result`` is still available (not
|
||||||
|
@ -826,7 +826,7 @@ def pytest_keyboard_interrupt(
|
||||||
|
|
||||||
def pytest_exception_interact(
|
def pytest_exception_interact(
|
||||||
node: Union["Item", "Collector"],
|
node: Union["Item", "Collector"],
|
||||||
call: "CallInfo[object]",
|
call: "CallInfo[Any]",
|
||||||
report: Union["CollectReport", "TestReport"],
|
report: Union["CollectReport", "TestReport"],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Called when an exception was raised which can potentially be
|
"""Called when an exception was raised which can potentially be
|
||||||
|
|
|
@ -404,7 +404,7 @@ class Failed(Exception):
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@attr.s
|
||||||
class _bestrelpath_cache(dict):
|
class _bestrelpath_cache(Dict[py.path.local, str]):
|
||||||
path = attr.ib(type=py.path.local)
|
path = attr.ib(type=py.path.local)
|
||||||
|
|
||||||
def __missing__(self, path: py.path.local) -> str:
|
def __missing__(self, path: py.path.local) -> str:
|
||||||
|
|
|
@ -5,6 +5,7 @@ import warnings
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
from typing import Iterator
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Mapping
|
from typing import Mapping
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
|
@ -30,6 +31,8 @@ from _pytest.warning_types import PytestUnknownMarkWarning
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
from ..nodes import Node
|
||||||
|
|
||||||
|
|
||||||
EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark"
|
EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark"
|
||||||
|
|
||||||
|
@ -521,13 +524,14 @@ class MarkGenerator:
|
||||||
MARK_GEN = MarkGenerator()
|
MARK_GEN = MarkGenerator()
|
||||||
|
|
||||||
|
|
||||||
class NodeKeywords(collections.abc.MutableMapping):
|
# TODO(py36): inherit from typing.MutableMapping[str, Any].
|
||||||
def __init__(self, node):
|
class NodeKeywords(collections.abc.MutableMapping): # type: ignore[type-arg]
|
||||||
|
def __init__(self, node: "Node") -> None:
|
||||||
self.node = node
|
self.node = node
|
||||||
self.parent = node.parent
|
self.parent = node.parent
|
||||||
self._markers = {node.name: True}
|
self._markers = {node.name: True}
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key: str) -> Any:
|
||||||
try:
|
try:
|
||||||
return self._markers[key]
|
return self._markers[key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -535,17 +539,17 @@ class NodeKeywords(collections.abc.MutableMapping):
|
||||||
raise
|
raise
|
||||||
return self.parent.keywords[key]
|
return self.parent.keywords[key]
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
self._markers[key] = value
|
self._markers[key] = value
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key: str) -> None:
|
||||||
raise ValueError("cannot delete key in keywords dict")
|
raise ValueError("cannot delete key in keywords dict")
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self) -> Iterator[str]:
|
||||||
seen = self._seen()
|
seen = self._seen()
|
||||||
return iter(seen)
|
return iter(seen)
|
||||||
|
|
||||||
def _seen(self):
|
def _seen(self) -> Set[str]:
|
||||||
seen = set(self._markers)
|
seen = set(self._markers)
|
||||||
if self.parent is not None:
|
if self.parent is not None:
|
||||||
seen.update(self.parent.keywords)
|
seen.update(self.parent.keywords)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
@ -167,7 +168,7 @@ class Node(metaclass=NodeMeta):
|
||||||
self.extra_keyword_matches = set() # type: Set[str]
|
self.extra_keyword_matches = set() # type: Set[str]
|
||||||
|
|
||||||
# Used for storing artificial fixturedefs for direct parametrization.
|
# Used for storing artificial fixturedefs for direct parametrization.
|
||||||
self._name2pseudofixturedef = {} # type: Dict[str, FixtureDef]
|
self._name2pseudofixturedef = {} # type: Dict[str, FixtureDef[Any]]
|
||||||
|
|
||||||
if nodeid is not None:
|
if nodeid is not None:
|
||||||
assert "::()" not in nodeid
|
assert "::()" not in nodeid
|
||||||
|
@ -354,7 +355,7 @@ class Node(metaclass=NodeMeta):
|
||||||
assert current is None or isinstance(current, cls)
|
assert current is None or isinstance(current, cls)
|
||||||
return current
|
return current
|
||||||
|
|
||||||
def _prunetraceback(self, excinfo):
|
def _prunetraceback(self, excinfo: ExceptionInfo[BaseException]) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _repr_failure_py(
|
def _repr_failure_py(
|
||||||
|
@ -479,7 +480,7 @@ class Collector(Node):
|
||||||
|
|
||||||
return self._repr_failure_py(excinfo, style=tbstyle)
|
return self._repr_failure_py(excinfo, style=tbstyle)
|
||||||
|
|
||||||
def _prunetraceback(self, excinfo):
|
def _prunetraceback(self, excinfo: ExceptionInfo[BaseException]) -> None:
|
||||||
if hasattr(self, "fspath"):
|
if hasattr(self, "fspath"):
|
||||||
traceback = excinfo.traceback
|
traceback = excinfo.traceback
|
||||||
ntraceback = traceback.cut(path=self.fspath)
|
ntraceback = traceback.cut(path=self.fspath)
|
||||||
|
|
|
@ -83,7 +83,7 @@ class Exit(Exception):
|
||||||
# Elaborate hack to work around https://github.com/python/mypy/issues/2087.
|
# Elaborate hack to work around https://github.com/python/mypy/issues/2087.
|
||||||
# Ideally would just be `exit.Exception = Exit` etc.
|
# Ideally would just be `exit.Exception = Exit` etc.
|
||||||
|
|
||||||
_F = TypeVar("_F", bound=Callable)
|
_F = TypeVar("_F", bound=Callable[..., object])
|
||||||
_ET = TypeVar("_ET", bound="Type[BaseException]")
|
_ET = TypeVar("_ET", bound="Type[BaseException]")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1179,7 +1179,7 @@ class Metafunc:
|
||||||
|
|
||||||
def _find_parametrized_scope(
|
def _find_parametrized_scope(
|
||||||
argnames: typing.Sequence[str],
|
argnames: typing.Sequence[str],
|
||||||
arg2fixturedefs: Mapping[str, typing.Sequence[fixtures.FixtureDef]],
|
arg2fixturedefs: Mapping[str, typing.Sequence[fixtures.FixtureDef[object]]],
|
||||||
indirect: Union[bool, typing.Sequence[str]],
|
indirect: Union[bool, typing.Sequence[str]],
|
||||||
) -> "fixtures._Scope":
|
) -> "fixtures._Scope":
|
||||||
"""Find the most appropriate scope for a parametrized call based on its arguments.
|
"""Find the most appropriate scope for a parametrized call based on its arguments.
|
||||||
|
@ -1578,7 +1578,7 @@ class Function(PyobjMixin, nodes.Item):
|
||||||
self.obj = self._getobj()
|
self.obj = self._getobj()
|
||||||
self._request._fillfixtures()
|
self._request._fillfixtures()
|
||||||
|
|
||||||
def _prunetraceback(self, excinfo: ExceptionInfo) -> None:
|
def _prunetraceback(self, excinfo: ExceptionInfo[BaseException]) -> None:
|
||||||
if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False):
|
if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False):
|
||||||
code = _pytest._code.Code(get_real_func(self.obj))
|
code = _pytest._code.Code(get_real_func(self.obj))
|
||||||
path, firstlineno = code.path, code.firstlineno
|
path, firstlineno = code.path, code.firstlineno
|
||||||
|
|
|
@ -526,7 +526,7 @@ _E = TypeVar("_E", bound=BaseException)
|
||||||
def raises(
|
def raises(
|
||||||
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
||||||
*,
|
*,
|
||||||
match: "Optional[Union[str, Pattern]]" = ...
|
match: "Optional[Union[str, Pattern[str]]]" = ...
|
||||||
) -> "RaisesContext[_E]":
|
) -> "RaisesContext[_E]":
|
||||||
... # pragma: no cover
|
... # pragma: no cover
|
||||||
|
|
||||||
|
@ -534,7 +534,7 @@ def raises(
|
||||||
@overload # noqa: F811
|
@overload # noqa: F811
|
||||||
def raises( # noqa: F811
|
def raises( # noqa: F811
|
||||||
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
||||||
func: Callable,
|
func: Callable[..., Any],
|
||||||
*args: Any,
|
*args: Any,
|
||||||
**kwargs: Any
|
**kwargs: Any
|
||||||
) -> _pytest._code.ExceptionInfo[_E]:
|
) -> _pytest._code.ExceptionInfo[_E]:
|
||||||
|
@ -670,7 +670,7 @@ def raises( # noqa: F811
|
||||||
message = "DID NOT RAISE {}".format(expected_exception)
|
message = "DID NOT RAISE {}".format(expected_exception)
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
match = kwargs.pop("match", None)
|
match = kwargs.pop("match", None) # type: Optional[Union[str, Pattern[str]]]
|
||||||
if kwargs:
|
if kwargs:
|
||||||
msg = "Unexpected keyword arguments passed to pytest.raises: "
|
msg = "Unexpected keyword arguments passed to pytest.raises: "
|
||||||
msg += ", ".join(sorted(kwargs))
|
msg += ", ".join(sorted(kwargs))
|
||||||
|
@ -703,7 +703,7 @@ class RaisesContext(Generic[_E]):
|
||||||
self,
|
self,
|
||||||
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
||||||
message: str,
|
message: str,
|
||||||
match_expr: Optional[Union[str, "Pattern"]] = None,
|
match_expr: Optional[Union[str, "Pattern[str]"]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.expected_exception = expected_exception
|
self.expected_exception = expected_exception
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
|
@ -40,7 +40,7 @@ def recwarn() -> Generator["WarningsRecorder", None, None]:
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def deprecated_call(
|
def deprecated_call(
|
||||||
*, match: Optional[Union[str, "Pattern"]] = ...
|
*, match: Optional[Union[str, "Pattern[str]"]] = ...
|
||||||
) -> "WarningsRecorder":
|
) -> "WarningsRecorder":
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ def deprecated_call( # noqa: F811
|
||||||
|
|
||||||
|
|
||||||
def deprecated_call( # noqa: F811
|
def deprecated_call( # noqa: F811
|
||||||
func: Optional[Callable] = None, *args: Any, **kwargs: Any
|
func: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any
|
||||||
) -> Union["WarningsRecorder", Any]:
|
) -> Union["WarningsRecorder", Any]:
|
||||||
"""Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``.
|
"""Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``.
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ def deprecated_call( # noqa: F811
|
||||||
def warns(
|
def warns(
|
||||||
expected_warning: Optional[Union["Type[Warning]", Tuple["Type[Warning]", ...]]],
|
expected_warning: Optional[Union["Type[Warning]", Tuple["Type[Warning]", ...]]],
|
||||||
*,
|
*,
|
||||||
match: "Optional[Union[str, Pattern]]" = ...
|
match: "Optional[Union[str, Pattern[str]]]" = ...
|
||||||
) -> "WarningsChecker":
|
) -> "WarningsChecker":
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ def warns( # noqa: F811
|
||||||
def warns( # noqa: F811
|
def warns( # noqa: F811
|
||||||
expected_warning: Optional[Union["Type[Warning]", Tuple["Type[Warning]", ...]]],
|
expected_warning: Optional[Union["Type[Warning]", Tuple["Type[Warning]", ...]]],
|
||||||
*args: Any,
|
*args: Any,
|
||||||
match: Optional[Union[str, "Pattern"]] = None,
|
match: Optional[Union[str, "Pattern[str]"]] = None,
|
||||||
**kwargs: Any
|
**kwargs: Any
|
||||||
) -> Union["WarningsChecker", Any]:
|
) -> Union["WarningsChecker", Any]:
|
||||||
r"""Assert that code raises a particular class of warning.
|
r"""Assert that code raises a particular class of warning.
|
||||||
|
@ -234,7 +234,7 @@ class WarningsChecker(WarningsRecorder):
|
||||||
expected_warning: Optional[
|
expected_warning: Optional[
|
||||||
Union["Type[Warning]", Tuple["Type[Warning]", ...]]
|
Union["Type[Warning]", Tuple["Type[Warning]", ...]]
|
||||||
] = None,
|
] = None,
|
||||||
match_expr: Optional[Union[str, "Pattern"]] = None,
|
match_expr: Optional[Union[str, "Pattern[str]"]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
|
|
@ -514,7 +514,7 @@ def _report_kwargs_from_json(reportdict: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
]
|
]
|
||||||
return ReprTraceback(**repr_traceback_dict)
|
return ReprTraceback(**repr_traceback_dict)
|
||||||
|
|
||||||
def deserialize_repr_crash(repr_crash_dict: Optional[dict]):
|
def deserialize_repr_crash(repr_crash_dict: Optional[Dict[str, Any]]):
|
||||||
if repr_crash_dict is not None:
|
if repr_crash_dict is not None:
|
||||||
return ReprFileLocation(**repr_crash_dict)
|
return ReprFileLocation(**repr_crash_dict)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -213,7 +213,7 @@ def call_and_report(
|
||||||
return report
|
return report
|
||||||
|
|
||||||
|
|
||||||
def check_interactive_exception(call: "CallInfo", report: BaseReport) -> bool:
|
def check_interactive_exception(call: "CallInfo[object]", report: BaseReport) -> bool:
|
||||||
"""Check whether the call raised an exception that should be reported as
|
"""Check whether the call raised an exception that should be reported as
|
||||||
interactive."""
|
interactive."""
|
||||||
if call.excinfo is None:
|
if call.excinfo is None:
|
||||||
|
@ -247,11 +247,11 @@ def call_runtest_hook(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
_T = TypeVar("_T")
|
TResult = TypeVar("TResult", covariant=True)
|
||||||
|
|
||||||
|
|
||||||
@attr.s(repr=False)
|
@attr.s(repr=False)
|
||||||
class CallInfo(Generic[_T]):
|
class CallInfo(Generic[TResult]):
|
||||||
"""Result/Exception info a function invocation.
|
"""Result/Exception info a function invocation.
|
||||||
|
|
||||||
:param T result:
|
:param T result:
|
||||||
|
@ -269,7 +269,7 @@ class CallInfo(Generic[_T]):
|
||||||
The context of invocation: "setup", "call", "teardown", ...
|
The context of invocation: "setup", "call", "teardown", ...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_result = attr.ib(type="Optional[_T]")
|
_result = attr.ib(type="Optional[TResult]")
|
||||||
excinfo = attr.ib(type=Optional[ExceptionInfo[BaseException]])
|
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)
|
||||||
|
@ -277,26 +277,26 @@ class CallInfo(Generic[_T]):
|
||||||
when = attr.ib(type="Literal['collect', 'setup', 'call', 'teardown']")
|
when = attr.ib(type="Literal['collect', 'setup', 'call', 'teardown']")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def result(self) -> _T:
|
def result(self) -> TResult:
|
||||||
if self.excinfo is not None:
|
if self.excinfo is not None:
|
||||||
raise AttributeError("{!r} has no valid result".format(self))
|
raise AttributeError("{!r} has no valid result".format(self))
|
||||||
# The cast is safe because an exception wasn't raised, hence
|
# The cast is safe because an exception wasn't raised, hence
|
||||||
# _result has the expected function return type (which may be
|
# _result has the expected function return type (which may be
|
||||||
# None, that's why a cast and not an assert).
|
# None, that's why a cast and not an assert).
|
||||||
return cast(_T, self._result)
|
return cast(TResult, self._result)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_call(
|
def from_call(
|
||||||
cls,
|
cls,
|
||||||
func: "Callable[[], _T]",
|
func: "Callable[[], TResult]",
|
||||||
when: "Literal['collect', 'setup', 'call', 'teardown']",
|
when: "Literal['collect', 'setup', 'call', 'teardown']",
|
||||||
reraise: "Optional[Union[Type[BaseException], Tuple[Type[BaseException], ...]]]" = None,
|
reraise: "Optional[Union[Type[BaseException], Tuple[Type[BaseException], ...]]]" = None,
|
||||||
) -> "CallInfo[_T]":
|
) -> "CallInfo[TResult]":
|
||||||
excinfo = None
|
excinfo = None
|
||||||
start = timing.time()
|
start = timing.time()
|
||||||
precise_start = timing.perf_counter()
|
precise_start = timing.perf_counter()
|
||||||
try:
|
try:
|
||||||
result = func() # type: Optional[_T]
|
result = func() # type: Optional[TResult]
|
||||||
except BaseException:
|
except BaseException:
|
||||||
excinfo = ExceptionInfo.from_current()
|
excinfo = ExceptionInfo.from_current()
|
||||||
if reraise is not None and isinstance(excinfo.value, reraise):
|
if reraise is not None and isinstance(excinfo.value, reraise):
|
||||||
|
|
|
@ -29,7 +29,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
|
|
||||||
@pytest.hookimpl(hookwrapper=True)
|
@pytest.hookimpl(hookwrapper=True)
|
||||||
def pytest_fixture_setup(
|
def pytest_fixture_setup(
|
||||||
fixturedef: FixtureDef, request: SubRequest
|
fixturedef: FixtureDef[object], request: SubRequest
|
||||||
) -> Generator[None, None, None]:
|
) -> Generator[None, None, None]:
|
||||||
yield
|
yield
|
||||||
if request.config.option.setupshow:
|
if request.config.option.setupshow:
|
||||||
|
@ -47,7 +47,7 @@ def pytest_fixture_setup(
|
||||||
_show_fixture_action(fixturedef, "SETUP")
|
_show_fixture_action(fixturedef, "SETUP")
|
||||||
|
|
||||||
|
|
||||||
def pytest_fixture_post_finalizer(fixturedef: FixtureDef) -> None:
|
def pytest_fixture_post_finalizer(fixturedef: FixtureDef[object]) -> None:
|
||||||
if fixturedef.cached_result is not None:
|
if fixturedef.cached_result is not None:
|
||||||
config = fixturedef._fixturemanager.config
|
config = fixturedef._fixturemanager.config
|
||||||
if config.option.setupshow:
|
if config.option.setupshow:
|
||||||
|
@ -56,7 +56,7 @@ def pytest_fixture_post_finalizer(fixturedef: FixtureDef) -> None:
|
||||||
del fixturedef.cached_param # type: ignore[attr-defined]
|
del fixturedef.cached_param # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
|
||||||
def _show_fixture_action(fixturedef: FixtureDef, msg: str) -> None:
|
def _show_fixture_action(fixturedef: FixtureDef[object], msg: str) -> None:
|
||||||
config = fixturedef._fixturemanager.config
|
config = fixturedef._fixturemanager.config
|
||||||
capman = config.pluginmanager.getplugin("capturemanager")
|
capman = config.pluginmanager.getplugin("capturemanager")
|
||||||
if capman:
|
if capman:
|
||||||
|
|
|
@ -22,7 +22,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
|
|
||||||
@pytest.hookimpl(tryfirst=True)
|
@pytest.hookimpl(tryfirst=True)
|
||||||
def pytest_fixture_setup(
|
def pytest_fixture_setup(
|
||||||
fixturedef: FixtureDef, request: SubRequest
|
fixturedef: FixtureDef[object], request: SubRequest
|
||||||
) -> Optional[object]:
|
) -> Optional[object]:
|
||||||
# Will return a dummy fixture if the setuponly option is provided.
|
# Will return a dummy fixture if the setuponly option is provided.
|
||||||
if request.config.option.setupplan:
|
if request.config.option.setupplan:
|
||||||
|
|
|
@ -319,7 +319,7 @@ class TerminalReporter:
|
||||||
|
|
||||||
self.stats = {} # type: Dict[str, List[Any]]
|
self.stats = {} # type: Dict[str, List[Any]]
|
||||||
self._main_color = None # type: Optional[str]
|
self._main_color = None # type: Optional[str]
|
||||||
self._known_types = None # type: Optional[List]
|
self._known_types = None # type: Optional[List[str]]
|
||||||
self.startdir = config.invocation_dir
|
self.startdir = config.invocation_dir
|
||||||
if file is None:
|
if file is None:
|
||||||
file = sys.stdout
|
file = sys.stdout
|
||||||
|
@ -469,7 +469,7 @@ class TerminalReporter:
|
||||||
def line(self, msg: str, **kw: bool) -> None:
|
def line(self, msg: str, **kw: bool) -> None:
|
||||||
self._tw.line(msg, **kw)
|
self._tw.line(msg, **kw)
|
||||||
|
|
||||||
def _add_stats(self, category: str, items: Sequence) -> None:
|
def _add_stats(self, category: str, items: Sequence[Any]) -> None:
|
||||||
set_main_color = category not in self.stats
|
set_main_color = category not in self.stats
|
||||||
self.stats.setdefault(category, []).extend(items)
|
self.stats.setdefault(category, []).extend(items)
|
||||||
if set_main_color:
|
if set_main_color:
|
||||||
|
|
|
@ -141,7 +141,7 @@ def _make_xunit_fixture(
|
||||||
|
|
||||||
class TestCaseFunction(Function):
|
class TestCaseFunction(Function):
|
||||||
nofuncargs = True
|
nofuncargs = True
|
||||||
_excinfo = None # type: Optional[List[_pytest._code.ExceptionInfo]]
|
_excinfo = None # type: Optional[List[_pytest._code.ExceptionInfo[BaseException]]]
|
||||||
_testcase = None # type: Optional[unittest.TestCase]
|
_testcase = None # type: Optional[unittest.TestCase]
|
||||||
|
|
||||||
def setup(self) -> None:
|
def setup(self) -> None:
|
||||||
|
@ -279,7 +279,9 @@ class TestCaseFunction(Function):
|
||||||
finally:
|
finally:
|
||||||
delattr(self._testcase, self.name)
|
delattr(self._testcase, self.name)
|
||||||
|
|
||||||
def _prunetraceback(self, excinfo: _pytest._code.ExceptionInfo) -> None:
|
def _prunetraceback(
|
||||||
|
self, excinfo: _pytest._code.ExceptionInfo[BaseException]
|
||||||
|
) -> None:
|
||||||
Function._prunetraceback(self, excinfo)
|
Function._prunetraceback(self, excinfo)
|
||||||
traceback = excinfo.traceback.filter(
|
traceback = excinfo.traceback.filter(
|
||||||
lambda x: not x.frame.f_globals.get("__unittest")
|
lambda x: not x.frame.f_globals.get("__unittest")
|
||||||
|
|
|
@ -144,7 +144,7 @@ class TestMetafunc:
|
||||||
scope = attr.ib()
|
scope = attr.ib()
|
||||||
|
|
||||||
fixtures_defs = cast(
|
fixtures_defs = cast(
|
||||||
Dict[str, Sequence[fixtures.FixtureDef]],
|
Dict[str, Sequence[fixtures.FixtureDef[object]]],
|
||||||
dict(
|
dict(
|
||||||
session_fix=[DummyFixtureDef("session")],
|
session_fix=[DummyFixtureDef("session")],
|
||||||
package_fix=[DummyFixtureDef("package")],
|
package_fix=[DummyFixtureDef("package")],
|
||||||
|
|
|
@ -640,7 +640,8 @@ class TestAssert_reprcompare:
|
||||||
|
|
||||||
def test_Sequence(self) -> None:
|
def test_Sequence(self) -> None:
|
||||||
# Test comparing with a Sequence subclass.
|
# Test comparing with a Sequence subclass.
|
||||||
class TestSequence(collections.abc.MutableSequence):
|
# TODO(py36): Inherit from typing.MutableSequence[int].
|
||||||
|
class TestSequence(collections.abc.MutableSequence): # type: ignore[type-arg]
|
||||||
def __init__(self, iterable):
|
def __init__(self, iterable):
|
||||||
self.elements = list(iterable)
|
self.elements = list(iterable)
|
||||||
|
|
||||||
|
|
|
@ -1564,66 +1564,66 @@ def tr() -> TerminalReporter:
|
||||||
# dict value, not the actual contents, so tuples of anything
|
# dict value, not the actual contents, so tuples of anything
|
||||||
# suffice
|
# suffice
|
||||||
# Important statuses -- the highest priority of these always wins
|
# Important statuses -- the highest priority of these always wins
|
||||||
("red", [("1 failed", {"bold": True, "red": True})], {"failed": (1,)}),
|
("red", [("1 failed", {"bold": True, "red": True})], {"failed": [1]}),
|
||||||
(
|
(
|
||||||
"red",
|
"red",
|
||||||
[
|
[
|
||||||
("1 failed", {"bold": True, "red": True}),
|
("1 failed", {"bold": True, "red": True}),
|
||||||
("1 passed", {"bold": False, "green": True}),
|
("1 passed", {"bold": False, "green": True}),
|
||||||
],
|
],
|
||||||
{"failed": (1,), "passed": (1,)},
|
{"failed": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
("red", [("1 error", {"bold": True, "red": True})], {"error": (1,)}),
|
("red", [("1 error", {"bold": True, "red": True})], {"error": [1]}),
|
||||||
("red", [("2 errors", {"bold": True, "red": True})], {"error": (1, 2)}),
|
("red", [("2 errors", {"bold": True, "red": True})], {"error": [1, 2]}),
|
||||||
(
|
(
|
||||||
"red",
|
"red",
|
||||||
[
|
[
|
||||||
("1 passed", {"bold": False, "green": True}),
|
("1 passed", {"bold": False, "green": True}),
|
||||||
("1 error", {"bold": True, "red": True}),
|
("1 error", {"bold": True, "red": True}),
|
||||||
],
|
],
|
||||||
{"error": (1,), "passed": (1,)},
|
{"error": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
# (a status that's not known to the code)
|
# (a status that's not known to the code)
|
||||||
("yellow", [("1 weird", {"bold": True, "yellow": True})], {"weird": (1,)}),
|
("yellow", [("1 weird", {"bold": True, "yellow": True})], {"weird": [1]}),
|
||||||
(
|
(
|
||||||
"yellow",
|
"yellow",
|
||||||
[
|
[
|
||||||
("1 passed", {"bold": False, "green": True}),
|
("1 passed", {"bold": False, "green": True}),
|
||||||
("1 weird", {"bold": True, "yellow": True}),
|
("1 weird", {"bold": True, "yellow": True}),
|
||||||
],
|
],
|
||||||
{"weird": (1,), "passed": (1,)},
|
{"weird": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
("yellow", [("1 warning", {"bold": True, "yellow": True})], {"warnings": (1,)}),
|
("yellow", [("1 warning", {"bold": True, "yellow": True})], {"warnings": [1]}),
|
||||||
(
|
(
|
||||||
"yellow",
|
"yellow",
|
||||||
[
|
[
|
||||||
("1 passed", {"bold": False, "green": True}),
|
("1 passed", {"bold": False, "green": True}),
|
||||||
("1 warning", {"bold": True, "yellow": True}),
|
("1 warning", {"bold": True, "yellow": True}),
|
||||||
],
|
],
|
||||||
{"warnings": (1,), "passed": (1,)},
|
{"warnings": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"green",
|
"green",
|
||||||
[("5 passed", {"bold": True, "green": True})],
|
[("5 passed", {"bold": True, "green": True})],
|
||||||
{"passed": (1, 2, 3, 4, 5)},
|
{"passed": [1, 2, 3, 4, 5]},
|
||||||
),
|
),
|
||||||
# "Boring" statuses. These have no effect on the color of the summary
|
# "Boring" statuses. These have no effect on the color of the summary
|
||||||
# line. Thus, if *every* test has a boring status, the summary line stays
|
# line. Thus, if *every* test has a boring status, the summary line stays
|
||||||
# at its default color, i.e. yellow, to warn the user that the test run
|
# at its default color, i.e. yellow, to warn the user that the test run
|
||||||
# produced no useful information
|
# produced no useful information
|
||||||
("yellow", [("1 skipped", {"bold": True, "yellow": True})], {"skipped": (1,)}),
|
("yellow", [("1 skipped", {"bold": True, "yellow": True})], {"skipped": [1]}),
|
||||||
(
|
(
|
||||||
"green",
|
"green",
|
||||||
[
|
[
|
||||||
("1 passed", {"bold": True, "green": True}),
|
("1 passed", {"bold": True, "green": True}),
|
||||||
("1 skipped", {"bold": False, "yellow": True}),
|
("1 skipped", {"bold": False, "yellow": True}),
|
||||||
],
|
],
|
||||||
{"skipped": (1,), "passed": (1,)},
|
{"skipped": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"yellow",
|
"yellow",
|
||||||
[("1 deselected", {"bold": True, "yellow": True})],
|
[("1 deselected", {"bold": True, "yellow": True})],
|
||||||
{"deselected": (1,)},
|
{"deselected": [1]},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"green",
|
"green",
|
||||||
|
@ -1631,34 +1631,34 @@ def tr() -> TerminalReporter:
|
||||||
("1 passed", {"bold": True, "green": True}),
|
("1 passed", {"bold": True, "green": True}),
|
||||||
("1 deselected", {"bold": False, "yellow": True}),
|
("1 deselected", {"bold": False, "yellow": True}),
|
||||||
],
|
],
|
||||||
{"deselected": (1,), "passed": (1,)},
|
{"deselected": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
("yellow", [("1 xfailed", {"bold": True, "yellow": True})], {"xfailed": (1,)}),
|
("yellow", [("1 xfailed", {"bold": True, "yellow": True})], {"xfailed": [1]}),
|
||||||
(
|
(
|
||||||
"green",
|
"green",
|
||||||
[
|
[
|
||||||
("1 passed", {"bold": True, "green": True}),
|
("1 passed", {"bold": True, "green": True}),
|
||||||
("1 xfailed", {"bold": False, "yellow": True}),
|
("1 xfailed", {"bold": False, "yellow": True}),
|
||||||
],
|
],
|
||||||
{"xfailed": (1,), "passed": (1,)},
|
{"xfailed": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
("yellow", [("1 xpassed", {"bold": True, "yellow": True})], {"xpassed": (1,)}),
|
("yellow", [("1 xpassed", {"bold": True, "yellow": True})], {"xpassed": [1]}),
|
||||||
(
|
(
|
||||||
"yellow",
|
"yellow",
|
||||||
[
|
[
|
||||||
("1 passed", {"bold": False, "green": True}),
|
("1 passed", {"bold": False, "green": True}),
|
||||||
("1 xpassed", {"bold": True, "yellow": True}),
|
("1 xpassed", {"bold": True, "yellow": True}),
|
||||||
],
|
],
|
||||||
{"xpassed": (1,), "passed": (1,)},
|
{"xpassed": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
# Likewise if no tests were found at all
|
# Likewise if no tests were found at all
|
||||||
("yellow", [("no tests ran", {"yellow": True})], {}),
|
("yellow", [("no tests ran", {"yellow": True})], {}),
|
||||||
# Test the empty-key special case
|
# Test the empty-key special case
|
||||||
("yellow", [("no tests ran", {"yellow": True})], {"": (1,)}),
|
("yellow", [("no tests ran", {"yellow": True})], {"": [1]}),
|
||||||
(
|
(
|
||||||
"green",
|
"green",
|
||||||
[("1 passed", {"bold": True, "green": True})],
|
[("1 passed", {"bold": True, "green": True})],
|
||||||
{"": (1,), "passed": (1,)},
|
{"": [1], "passed": [1]},
|
||||||
),
|
),
|
||||||
# A couple more complex combinations
|
# A couple more complex combinations
|
||||||
(
|
(
|
||||||
|
@ -1668,7 +1668,7 @@ def tr() -> TerminalReporter:
|
||||||
("2 passed", {"bold": False, "green": True}),
|
("2 passed", {"bold": False, "green": True}),
|
||||||
("3 xfailed", {"bold": False, "yellow": True}),
|
("3 xfailed", {"bold": False, "yellow": True}),
|
||||||
],
|
],
|
||||||
{"passed": (1, 2), "failed": (1,), "xfailed": (1, 2, 3)},
|
{"passed": [1, 2], "failed": [1], "xfailed": [1, 2, 3]},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"green",
|
"green",
|
||||||
|
@ -1679,10 +1679,10 @@ def tr() -> TerminalReporter:
|
||||||
("2 xfailed", {"bold": False, "yellow": True}),
|
("2 xfailed", {"bold": False, "yellow": True}),
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
"passed": (1,),
|
"passed": [1],
|
||||||
"skipped": (1, 2),
|
"skipped": [1, 2],
|
||||||
"deselected": (1, 2, 3),
|
"deselected": [1, 2, 3],
|
||||||
"xfailed": (1, 2),
|
"xfailed": [1, 2],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1691,7 +1691,7 @@ def test_summary_stats(
|
||||||
tr: TerminalReporter,
|
tr: TerminalReporter,
|
||||||
exp_line: List[Tuple[str, Dict[str, bool]]],
|
exp_line: List[Tuple[str, Dict[str, bool]]],
|
||||||
exp_color: str,
|
exp_color: str,
|
||||||
stats_arg: Dict[str, List],
|
stats_arg: Dict[str, List[object]],
|
||||||
) -> None:
|
) -> None:
|
||||||
tr.stats = stats_arg
|
tr.stats = stats_arg
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue