diff --git a/pytest_factoryboy/compat.py b/pytest_factoryboy/compat.py index 5512f7e..01d7320 100644 --- a/pytest_factoryboy/compat.py +++ b/pytest_factoryboy/compat.py @@ -2,6 +2,7 @@ from collections.abc import Sequence from importlib.metadata import version +from typing import TypeAlias from _pytest.fixtures import FixtureDef, FixtureManager from _pytest.nodes import Node @@ -9,7 +10,7 @@ pytest_version = parse_version(version("pytest")) -__all__ = ("PostGenerationContext", "getfixturedefs") +__all__ = ("PostGenerationContext", "getfixturedefs", "PytestFixtureT") try: from factory.declarations import PostGenerationContext @@ -25,3 +26,13 @@ def getfixturedefs(fixturemanager: FixtureManager, fixturename: str, node: Node) def getfixturedefs(fixturemanager: FixtureManager, fixturename: str, node: Node) -> Sequence[FixtureDef] | None: return fixturemanager.getfixturedefs(fixturename, node.nodeid) + + +if pytest_version.release >= (8, 4): + from _pytest.fixtures import FixtureFunctionDefinition + + PytestFixtureT: TypeAlias = FixtureFunctionDefinition +else: + from _pytest.fixtures import FixtureFunction + + PytestFixtureT: TypeAlias = FixtureFunction diff --git a/pytest_factoryboy/fixture.py b/pytest_factoryboy/fixture.py index 8ef280c..e94b039 100644 --- a/pytest_factoryboy/fixture.py +++ b/pytest_factoryboy/fixture.py @@ -182,12 +182,12 @@ def create_fixture_with_related( ) -> Callable[P, T]: if related is None: related = [] - f = create_fixture(name=name, function=function, fixtures=fixtures) + fixture, fn = create_fixture(name=name, function=function, fixtures=fixtures) # We have to set the `_factoryboy_related` attribute to the original function, since # FixtureDef.func will provide that one later when we discover the related fixtures. - f.__pytest_wrapped__.obj._factoryboy_related = related # type: ignore[attr-defined] - return f + fn._factoryboy_related = related # type: ignore[attr-defined] + return fixture def make_declaration_fixturedef( diff --git a/pytest_factoryboy/fixturegen.py b/pytest_factoryboy/fixturegen.py index 55e9cca..cd9379b 100644 --- a/pytest_factoryboy/fixturegen.py +++ b/pytest_factoryboy/fixturegen.py @@ -8,6 +8,8 @@ import pytest from typing_extensions import ParamSpec +from .compat import PytestFixtureT + T = TypeVar("T") P = ParamSpec("P") @@ -16,13 +18,13 @@ def create_fixture( name: str, function: Callable[P, T], fixtures: Collection[str] | None = None, -) -> Callable[P, T]: +) -> tuple[PytestFixtureT, Callable[P, T]]: """Dynamically create a pytest fixture. :param name: Name of the fixture. :param function: Function to be called. :param fixtures: List of fixtures dependencies, but that will not be passed to ``function``. - :return: The created fixture function. + :return: The created fixture function and the actual function. Example: @@ -41,13 +43,14 @@ def book(name, db): if fixtures is None: fixtures = [] - @pytest.fixture(name=name) @usefixtures(*fixtures) @functools.wraps(function) def fn(*args: P.args, **kwargs: P.kwargs) -> T: return function(*args, **kwargs) - return fn + fixture = pytest.fixture(name=name, fixture_function=fn) + + return fixture, fn def usefixtures(*fixtures: str) -> Callable[[Callable[P, T]], Callable[P, T]]: