diff --git a/changelog/7469.deprecation.rst b/changelog/7469.deprecation.rst index 6bbc80755..bcf4266d8 100644 --- a/changelog/7469.deprecation.rst +++ b/changelog/7469.deprecation.rst @@ -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. diff --git a/changelog/7469.feature.rst b/changelog/7469.feature.rst index 81f93d1f7..0ab2b48c4 100644 --- a/changelog/7469.feature.rst +++ b/changelog/7469.feature.rst @@ -5,6 +5,7 @@ The newly-exported types are: - ``pytest.Mark`` for :class:`marks `. - ``pytest.MarkDecorator`` for :class:`mark decorators `. - ``pytest.MarkGenerator`` for the :class:`pytest.mark ` singleton. +- ``pytest.Metafunc`` for the :class:`metafunc ` argument to the `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. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 5ef1053e0..ec2397e59 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -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: diff --git a/doc/en/funcarg_compare.rst b/doc/en/funcarg_compare.rst index 0c4913edf..5e2a05006 100644 --- a/doc/en/funcarg_compare.rst +++ b/doc/en/funcarg_compare.rst @@ -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) ` calls. Of course it's perfectly fine to combine parametrization and scoping: diff --git a/doc/en/reference.rst b/doc/en/reference.rst index c8e8dca75..7f2ae0105 100644 --- a/doc/en/reference.rst +++ b/doc/en/reference.rst @@ -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 diff --git a/src/_pytest/python.py b/src/_pytest/python.py index b46050920..31d91853f 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -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 diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py index 74cf00ee2..f97b0ac2e 100644 --- a/src/pytest/__init__.py +++ b/src/pytest/__init__.py @@ -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", diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index c50ea53d2..58a902a3a 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -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():