Repository: pytest-dev/pytest
File: src/_pytest/fixtures.py (Python)

Code before:
            raise ValueError("class fixtures not supported (maybe in the future)")

        if isinstance(function, FixtureFunctionDefinition):
            raise ValueError(
                f"@pytest.fixture is being applied more than once to the same function {function.__name__!r}"
            )

        if hasattr(function, "pytestmark"):
            warnings.warn(MARKED_FIXTURE, stacklevel=2)

        fixture_definition = FixtureFunctionDefinition(function, self)

        name = self.name or function.__name__
        if name == "request":
            location = getlocation(function)
            fail(
                f"'request' is a reserved word for fixtures, use another name:\n  {location}",
                pytrace=False,
            )

        return fixture_definition


# TODO: paramspec/return type annotation tracking and storing
class FixtureFunctionDefinition:
    def __init__(
        self,
        function: Callable[..., Any],
        fixture_function_marker: FixtureFunctionMarker,
        instance: type | None = None,
    ):
        self.name = fixture_function_marker.name or function.__name__
        self.__name__ = self.name
        self._fixture_function_marker = fixture_function_marker
        self._fixture_function = function
        self._instance = instance

    def __repr__(self) -> str:
        return f"<pytest_fixture({self._fixture_function})>"

    def __get__(self, instance, owner=None):
        return FixtureFunctionDefinition(
            self._fixture_function, self._fixture_function_marker, instance
        )

    def __call__(self, *args: Any, **kwds: Any) -> Any:
        message = (
            f'Fixture "{self.name}" called directly. Fixtures are not meant to be called directly,\n'
            "but are created automatically when test functions request them as parameters.\n"
            "See https://docs.pytest.org/en/stable/explanation/fixtures.html for more information about fixtures, and\n"
            "https://docs.pytest.org/en/stable/deprecations.html#calling-fixtures-directly"

Review comment (suggestion):
These days I prefer to force keyword arguments in such cases:

```suggestion
        self,
        *,
```

Code after:
            raise ValueError(
                f"@pytest.fixture is being applied more than once to the same function {function.__name__!r}"
            )

        if hasattr(function, "pytestmark"):
            warnings.warn(MARKED_FIXTURE, stacklevel=2)

        fixture_definition = FixtureFunctionDefinition(
            function=function, fixture_function_marker=self, _ispytest=True
        )

        name = self.name or function.__name__
        if name == "request":
            location = getlocation(function)
            fail(
                f"'request' is a reserved word for fixtures, use another name:\n  {location}",
                pytrace=False,
            )

        return fixture_definition


# TODO: paramspec/return type annotation tracking and storing
class FixtureFunctionDefinition:
    def __init__(
        self,
        *,
        function: Callable[..., Any],
        fixture_function_marker: FixtureFunctionMarker,
        instance: object | None = None,
        _ispytest: bool = False,
    ) -> None:
        check_ispytest(_ispytest)
        self.name = fixture_function_marker.name or function.__name__
        # In order to show the function that this fixture contains in messages.
        # Set the __name__ to be same as the function __name__ or the given fixture name.
        self.__name__ = self.name
        self._fixture_function_marker = fixture_function_marker
        if instance is not None:
            self._fixture_function = cast(
                Callable[..., Any], function.__get__(instance)
            )
        else:
            self._fixture_function = function
        functools.update_wrapper(self, function)

    def __repr__(self) -> str:
        return f"<pytest_fixture({self._fixture_function})>"

    def __get__(self, instance, owner=None):
        """Behave like a method if the function it was applied to was a method."""