Type annotate more of _pytest.fixtures
This commit is contained in:
parent
f8bb61ae5b
commit
1bd7d025d9
|
@ -57,8 +57,9 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
from _pytest.main import Session
|
from _pytest.main import Session
|
||||||
from _pytest.python import Metafunc
|
|
||||||
from _pytest.python import CallSpec2
|
from _pytest.python import CallSpec2
|
||||||
|
from _pytest.python import Function
|
||||||
|
from _pytest.python import Metafunc
|
||||||
|
|
||||||
_Scope = Literal["session", "package", "module", "class", "function"]
|
_Scope = Literal["session", "package", "module", "class", "function"]
|
||||||
|
|
||||||
|
@ -189,29 +190,32 @@ def add_funcarg_pseudo_fixture_def(
|
||||||
arg2fixturedefs[argname] = [node._name2pseudofixturedef[argname]]
|
arg2fixturedefs[argname] = [node._name2pseudofixturedef[argname]]
|
||||||
else:
|
else:
|
||||||
fixturedef = FixtureDef(
|
fixturedef = FixtureDef(
|
||||||
fixturemanager,
|
fixturemanager=fixturemanager,
|
||||||
"",
|
baseid="",
|
||||||
argname,
|
argname=argname,
|
||||||
get_direct_param_fixture_func,
|
func=get_direct_param_fixture_func,
|
||||||
arg2scope[argname],
|
scope=arg2scope[argname],
|
||||||
valuelist,
|
params=valuelist,
|
||||||
False,
|
unittest=False,
|
||||||
False,
|
ids=None,
|
||||||
)
|
)
|
||||||
arg2fixturedefs[argname] = [fixturedef]
|
arg2fixturedefs[argname] = [fixturedef]
|
||||||
if node is not None:
|
if node is not None:
|
||||||
node._name2pseudofixturedef[argname] = fixturedef
|
node._name2pseudofixturedef[argname] = fixturedef
|
||||||
|
|
||||||
|
|
||||||
def getfixturemarker(obj):
|
def getfixturemarker(obj: object) -> Optional["FixtureFunctionMarker"]:
|
||||||
""" return fixturemarker or None if it doesn't exist or raised
|
""" return fixturemarker or None if it doesn't exist or raised
|
||||||
exceptions."""
|
exceptions."""
|
||||||
try:
|
try:
|
||||||
return getattr(obj, "_pytestfixturefunction", None)
|
fixturemarker = getattr(
|
||||||
|
obj, "_pytestfixturefunction", None
|
||||||
|
) # type: Optional[FixtureFunctionMarker]
|
||||||
except TEST_OUTCOME:
|
except TEST_OUTCOME:
|
||||||
# some objects raise errors like request (from flask import request)
|
# some objects raise errors like request (from flask import request)
|
||||||
# we don't expect them to be fixture functions
|
# we don't expect them to be fixture functions
|
||||||
return None
|
return None
|
||||||
|
return fixturemarker
|
||||||
|
|
||||||
|
|
||||||
# Parametrized fixture key, helper alias for code below.
|
# Parametrized fixture key, helper alias for code below.
|
||||||
|
@ -334,7 +338,7 @@ def reorder_items_atscope(
|
||||||
return items_done
|
return items_done
|
||||||
|
|
||||||
|
|
||||||
def fillfixtures(function) -> None:
|
def fillfixtures(function: "Function") -> None:
|
||||||
""" fill missing funcargs for a test function. """
|
""" fill missing funcargs for a test function. """
|
||||||
warnings.warn(FILLFUNCARGS, stacklevel=2)
|
warnings.warn(FILLFUNCARGS, stacklevel=2)
|
||||||
try:
|
try:
|
||||||
|
@ -344,6 +348,7 @@ def fillfixtures(function) -> None:
|
||||||
# with the oejskit plugin. It uses classes with funcargs
|
# with the oejskit plugin. It uses classes with funcargs
|
||||||
# and we thus have to work a bit to allow this.
|
# and we thus have to work a bit to allow this.
|
||||||
fm = function.session._fixturemanager
|
fm = function.session._fixturemanager
|
||||||
|
assert function.parent is not None
|
||||||
fi = fm.getfixtureinfo(function.parent, function.obj, None)
|
fi = fm.getfixtureinfo(function.parent, function.obj, None)
|
||||||
function._fixtureinfo = fi
|
function._fixtureinfo = fi
|
||||||
request = function._request = FixtureRequest(function)
|
request = function._request = FixtureRequest(function)
|
||||||
|
@ -866,7 +871,7 @@ def fail_fixturefunc(fixturefunc, msg: str) -> "NoReturn":
|
||||||
fail(msg + ":\n\n" + str(source.indent()) + "\n" + location, pytrace=False)
|
fail(msg + ":\n\n" + str(source.indent()) + "\n" + location, pytrace=False)
|
||||||
|
|
||||||
|
|
||||||
def call_fixture_func(fixturefunc, request: FixtureRequest, kwargs) -> object:
|
def call_fixture_func(fixturefunc, request: FixtureRequest, kwargs):
|
||||||
yieldctx = is_generator(fixturefunc)
|
yieldctx = is_generator(fixturefunc)
|
||||||
if yieldctx:
|
if yieldctx:
|
||||||
generator = fixturefunc(**kwargs)
|
generator = fixturefunc(**kwargs)
|
||||||
|
@ -896,9 +901,15 @@ def _teardown_yield_fixture(fixturefunc, it) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _eval_scope_callable(scope_callable, fixture_name: str, config: Config) -> str:
|
def _eval_scope_callable(
|
||||||
|
scope_callable: "Callable[[str, Config], _Scope]",
|
||||||
|
fixture_name: str,
|
||||||
|
config: Config,
|
||||||
|
) -> "_Scope":
|
||||||
try:
|
try:
|
||||||
result = scope_callable(fixture_name=fixture_name, config=config)
|
# Type ignored because there is no typing mechanism to specify
|
||||||
|
# keyword arguments, currently.
|
||||||
|
result = scope_callable(fixture_name=fixture_name, config=config) # type: ignore[call-arg] # noqa: F821
|
||||||
except Exception:
|
except Exception:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Error evaluating {} while defining fixture '{}'.\n"
|
"Error evaluating {} while defining fixture '{}'.\n"
|
||||||
|
@ -924,10 +935,15 @@ class FixtureDef:
|
||||||
baseid,
|
baseid,
|
||||||
argname: str,
|
argname: str,
|
||||||
func,
|
func,
|
||||||
scope: str,
|
scope: "Union[_Scope, Callable[[str, Config], _Scope]]",
|
||||||
params: Optional[Sequence[object]],
|
params: Optional[Sequence[object]],
|
||||||
unittest: bool = False,
|
unittest: bool = False,
|
||||||
ids=None,
|
ids: Optional[
|
||||||
|
Union[
|
||||||
|
Tuple[Union[None, str, float, int, bool], ...],
|
||||||
|
Callable[[object], Optional[object]],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._fixturemanager = fixturemanager
|
self._fixturemanager = fixturemanager
|
||||||
self.baseid = baseid or ""
|
self.baseid = baseid or ""
|
||||||
|
@ -935,16 +951,15 @@ class FixtureDef:
|
||||||
self.func = func
|
self.func = func
|
||||||
self.argname = argname
|
self.argname = argname
|
||||||
if callable(scope):
|
if callable(scope):
|
||||||
scope = _eval_scope_callable(scope, argname, fixturemanager.config)
|
scope_ = _eval_scope_callable(scope, argname, fixturemanager.config)
|
||||||
|
else:
|
||||||
|
scope_ = scope
|
||||||
self.scopenum = scope2index(
|
self.scopenum = scope2index(
|
||||||
scope or "function",
|
scope_ or "function",
|
||||||
descr="Fixture '{}'".format(func.__name__),
|
descr="Fixture '{}'".format(func.__name__),
|
||||||
where=baseid,
|
where=baseid,
|
||||||
)
|
)
|
||||||
# The cast is verified by scope2index.
|
self.scope = scope_
|
||||||
# (Some of the type annotations below are supposed to be inferred,
|
|
||||||
# but mypy 0.761 has some trouble without them.)
|
|
||||||
self.scope = cast("_Scope", scope) # type: _Scope
|
|
||||||
self.params = params # type: Optional[Sequence[object]]
|
self.params = params # type: Optional[Sequence[object]]
|
||||||
self.argnames = getfuncargnames(
|
self.argnames = getfuncargnames(
|
||||||
func, name=argname, is_method=unittest
|
func, name=argname, is_method=unittest
|
||||||
|
@ -1068,9 +1083,21 @@ def pytest_fixture_setup(fixturedef: FixtureDef, request: SubRequest) -> object:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def _ensure_immutable_ids(ids):
|
def _ensure_immutable_ids(
|
||||||
|
ids: Optional[
|
||||||
|
Union[
|
||||||
|
Iterable[Union[None, str, float, int, bool]],
|
||||||
|
Callable[[object], Optional[object]],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
) -> Optional[
|
||||||
|
Union[
|
||||||
|
Tuple[Union[None, str, float, int, bool], ...],
|
||||||
|
Callable[[object], Optional[object]],
|
||||||
|
]
|
||||||
|
]:
|
||||||
if ids is None:
|
if ids is None:
|
||||||
return
|
return None
|
||||||
if callable(ids):
|
if callable(ids):
|
||||||
return ids
|
return ids
|
||||||
return tuple(ids)
|
return tuple(ids)
|
||||||
|
@ -1102,10 +1129,16 @@ def wrap_function_to_error_out_if_called_directly(function, fixture_marker):
|
||||||
class FixtureFunctionMarker:
|
class FixtureFunctionMarker:
|
||||||
scope = attr.ib()
|
scope = attr.ib()
|
||||||
params = attr.ib(converter=attr.converters.optional(tuple))
|
params = attr.ib(converter=attr.converters.optional(tuple))
|
||||||
autouse = attr.ib(default=False)
|
autouse = attr.ib(type=bool, default=False)
|
||||||
# Ignore type because of https://github.com/python/mypy/issues/6172.
|
ids = attr.ib(
|
||||||
ids = attr.ib(default=None, converter=_ensure_immutable_ids) # type: ignore
|
type=Union[
|
||||||
name = attr.ib(default=None)
|
Tuple[Union[None, str, float, int, bool], ...],
|
||||||
|
Callable[[object], Optional[object]],
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
converter=_ensure_immutable_ids,
|
||||||
|
)
|
||||||
|
name = attr.ib(type=Optional[str], default=None)
|
||||||
|
|
||||||
def __call__(self, function):
|
def __call__(self, function):
|
||||||
if inspect.isclass(function):
|
if inspect.isclass(function):
|
||||||
|
@ -1133,12 +1166,17 @@ class FixtureFunctionMarker:
|
||||||
|
|
||||||
def fixture(
|
def fixture(
|
||||||
fixture_function=None,
|
fixture_function=None,
|
||||||
*args,
|
*args: Any,
|
||||||
scope="function",
|
scope: "Union[_Scope, Callable[[str, Config], _Scope]]" = "function",
|
||||||
params=None,
|
params=None,
|
||||||
autouse=False,
|
autouse: bool = False,
|
||||||
ids=None,
|
ids: Optional[
|
||||||
name=None
|
Union[
|
||||||
|
Iterable[Union[None, str, float, int, bool]],
|
||||||
|
Callable[[object], Optional[object]],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
name: Optional[str] = None
|
||||||
):
|
):
|
||||||
"""Decorator to mark a fixture factory function.
|
"""Decorator to mark a fixture factory function.
|
||||||
|
|
||||||
|
@ -1343,7 +1381,7 @@ class FixtureManager:
|
||||||
] # type: List[Tuple[str, List[str]]]
|
] # type: List[Tuple[str, List[str]]]
|
||||||
session.config.pluginmanager.register(self, "funcmanage")
|
session.config.pluginmanager.register(self, "funcmanage")
|
||||||
|
|
||||||
def _get_direct_parametrize_args(self, node) -> List[str]:
|
def _get_direct_parametrize_args(self, node: "nodes.Node") -> List[str]:
|
||||||
"""This function returns all the direct parametrization
|
"""This function returns all the direct parametrization
|
||||||
arguments of a node, so we don't mistake them for fixtures
|
arguments of a node, so we don't mistake them for fixtures
|
||||||
|
|
||||||
|
@ -1362,7 +1400,9 @@ class FixtureManager:
|
||||||
|
|
||||||
return parametrize_argnames
|
return parametrize_argnames
|
||||||
|
|
||||||
def getfixtureinfo(self, node, func, cls, funcargs: bool = True) -> FuncFixtureInfo:
|
def getfixtureinfo(
|
||||||
|
self, node: "nodes.Node", func, cls, funcargs: bool = True
|
||||||
|
) -> FuncFixtureInfo:
|
||||||
if funcargs and not getattr(node, "nofuncargs", False):
|
if funcargs and not getattr(node, "nofuncargs", False):
|
||||||
argnames = getfuncargnames(func, name=node.name, cls=cls)
|
argnames = getfuncargnames(func, name=node.name, cls=cls)
|
||||||
else:
|
else:
|
||||||
|
@ -1526,12 +1566,12 @@ class FixtureManager:
|
||||||
obj = get_real_method(obj, holderobj)
|
obj = get_real_method(obj, holderobj)
|
||||||
|
|
||||||
fixture_def = FixtureDef(
|
fixture_def = FixtureDef(
|
||||||
self,
|
fixturemanager=self,
|
||||||
nodeid,
|
baseid=nodeid,
|
||||||
name,
|
argname=name,
|
||||||
obj,
|
func=obj,
|
||||||
marker.scope,
|
scope=marker.scope,
|
||||||
marker.params,
|
params=marker.params,
|
||||||
unittest=unittest,
|
unittest=unittest,
|
||||||
ids=marker.ids,
|
ids=marker.ids,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue