python: export pytest.Metafunc for typing purposes

The type cannot be constructed directly, but is exported for use in type
annotations, since it is reachable through existing public API.
This commit is contained in:
Ran Benita 2020-12-26 20:49:17 +02:00
parent 6d3a66d947
commit bd76042344
8 changed files with 22 additions and 8 deletions

View File

@ -3,5 +3,6 @@ Directly constructing the following classes is now deprecated:
- ``_pytest.mark.structures.Mark``
- ``_pytest.mark.structures.MarkDecorator``
- ``_pytest.mark.structures.MarkGenerator``
- ``_pytest.python.Metafunc``
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.

View File

@ -5,6 +5,7 @@ The newly-exported types are:
- ``pytest.Mark`` for :class:`marks <pytest.Mark>`.
- ``pytest.MarkDecorator`` for :class:`mark decorators <pytest.MarkDecorator>`.
- ``pytest.MarkGenerator`` for the :class:`pytest.mark <pytest.MarkGenerator>` singleton.
- ``pytest.Metafunc`` for the :class:`metafunc <pytest.MarkGenerator>` argument to the `pytest_generate_tests <pytest.hookspec.pytest_generate_tests>` hook.
Constructing them directly is not supported; they are only meant for use in type annotations.
Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.

View File

@ -397,8 +397,8 @@ Metafunc.addcall
.. versionremoved:: 4.0
``_pytest.python.Metafunc.addcall`` was a precursor to the current parametrized mechanism. Users should use
:meth:`_pytest.python.Metafunc.parametrize` instead.
``Metafunc.addcall`` was a precursor to the current parametrized mechanism. Users should use
:meth:`pytest.Metafunc.parametrize` instead.
Example:

View File

@ -47,7 +47,7 @@ There are several limitations and difficulties with this approach:
2. parametrizing the "db" resource is not straight forward:
you need to apply a "parametrize" decorator or implement a
:py:func:`~hookspec.pytest_generate_tests` hook
calling :py:func:`~python.Metafunc.parametrize` which
calling :py:func:`~pytest.Metafunc.parametrize` which
performs parametrization at the places where the resource
is used. Moreover, you need to modify the factory to use an
``extrakey`` parameter containing ``request.param`` to the
@ -113,7 +113,7 @@ This new way of parametrizing funcarg factories should in many cases
allow to re-use already written factories because effectively
``request.param`` was already used when test functions/classes were
parametrized via
:py:func:`metafunc.parametrize(indirect=True) <_pytest.python.Metafunc.parametrize>` calls.
:py:func:`metafunc.parametrize(indirect=True) <pytest.Metafunc.parametrize>` calls.
Of course it's perfectly fine to combine parametrization and scoping:

View File

@ -138,7 +138,7 @@ pytest.mark.parametrize
**Tutorial**: :doc:`parametrize`.
This mark has the same signature as :py:meth:`_pytest.python.Metafunc.parametrize`; see there.
This mark has the same signature as :py:meth:`pytest.Metafunc.parametrize`; see there.
.. _`pytest.mark.skip ref`:
@ -870,7 +870,7 @@ Mark
Metafunc
~~~~~~~~
.. autoclass:: _pytest.python.Metafunc
.. autoclass:: pytest.Metafunc()
:members:
Module

View File

@ -55,6 +55,7 @@ from _pytest.config import Config
from _pytest.config import ExitCode
from _pytest.config import hookimpl
from _pytest.config.argparsing import Parser
from _pytest.deprecated import check_ispytest
from _pytest.deprecated import FSCOLLECTOR_GETHOOKPROXY_ISINITPATH
from _pytest.fixtures import FuncFixtureInfo
from _pytest.main import Session
@ -467,7 +468,12 @@ class PyCollector(PyobjMixin, nodes.Collector):
fixtureinfo = definition._fixtureinfo
metafunc = Metafunc(
definition, fixtureinfo, self.config, cls=cls, module=module
definition=definition,
fixtureinfo=fixtureinfo,
config=self.config,
cls=cls,
module=module,
_ispytest=True,
)
methods = []
if hasattr(module, "pytest_generate_tests"):
@ -971,7 +977,11 @@ class Metafunc:
config: Config,
cls=None,
module=None,
*,
_ispytest: bool = False,
) -> None:
check_ispytest(_ispytest)
#: Access to the underlying :class:`_pytest.python.FunctionDefinition`.
self.definition = definition

View File

@ -40,6 +40,7 @@ from _pytest.pytester import Testdir
from _pytest.python import Class
from _pytest.python import Function
from _pytest.python import Instance
from _pytest.python import Metafunc
from _pytest.python import Module
from _pytest.python import Package
from _pytest.python_api import approx
@ -95,6 +96,7 @@ __all__ = [
"Mark",
"MarkDecorator",
"MarkGenerator",
"Metafunc",
"Module",
"MonkeyPatch",
"Package",

View File

@ -47,7 +47,7 @@ class TestMetafunc:
names = getfuncargnames(func)
fixtureinfo: Any = FuncFixtureInfoMock(names)
definition: Any = DefinitionMock._create(func, "mock::nodeid")
return python.Metafunc(definition, fixtureinfo, config)
return python.Metafunc(definition, fixtureinfo, config, _ispytest=True)
def test_no_funcargs(self) -> None:
def function():