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

Code before:

        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"
        )
        fail(message, pytrace=False)

    def _get_wrapped_function(self) -> Callable[..., Any]:
        if self._instance is None:
            return self._fixture_function

        return cast(Callable[..., Any], self._fixture_function.__get__(self._instance))


@overload

Review comment (suggestion):
Can you add a comment on this line, explaining what it does? IIUC, it's to match the `__name__` attribute of function objects, but it's not obvious.

Code after:
        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."""
        return FixtureFunctionDefinition(
            function=self._fixture_function,
            fixture_function_marker=self._fixture_function_marker,
            instance=instance,
            _ispytest=True,
        )

    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"