pytest-dev/pytest · error · AttributeError

function not available in {self.scope}-scoped context

Error message

function not available in {self.scope}-scoped context

What it means

Raised by the `request.function` property on a FixtureRequest/SubRequest when the request's scope is not "function". pytest only knows the underlying test function object during a function-scoped setup, so accessing `request.function` from a session/module/class/package-scoped fixture is undefined and is rejected with an AttributeError. The scope is fixed when the fixture is declared via `@pytest.fixture(scope=...)`.

Source

Thrown at src/_pytest/fixtures.py:582

        result.extend(set(self._fixture_defs).difference(result))
        return result

    @property
    @abc.abstractmethod
    def node(self):
        """Underlying collection node (depends on current request scope)."""
        raise NotImplementedError()

    @property
    def config(self) -> Config:
        """The pytest config object associated with this request."""
        return self._pyfuncitem.config

    @property
    def function(self):
        """Test function object if the request has a per-function scope."""
        if self.scope != "function":
            raise AttributeError(
                f"function not available in {self.scope}-scoped context"
            )
        return self._pyfuncitem.obj

    @property
    def cls(self):
        """Class (can be None) where the test function was collected."""
        if self.scope not in ("class", "function"):
            raise AttributeError(f"cls not available in {self.scope}-scoped context")
        clscol = self._pyfuncitem.getparent(_pytest.python.Class)
        if clscol:
            return clscol.obj

    @property
    def instance(self):
        """Instance (can be None) on which test function was collected."""
        if self.scope != "function":
            return None

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Move the `request.function` access into a separate function-scoped fixture that depends on the wider-scoped one.
  2. Use `request.node` (available at all scopes) and read attributes off the node, e.g. `request.node.name` or `request.node.obj`.
  3. If you need per-test data in a session fixture, pass it via a function-scoped fixture param or `request.getfixturevalue(...)` before yield.
  4. Reconsider the scope: if the fixture genuinely needs the test function, it must be function-scoped.

Example fix

// before
@pytest.fixture(scope="session")
def db(request):
    name = request.function.__name__  # AttributeError
// after
@pytest.fixture(scope="session")
def db(request):
    node = request.node  # always available
    print(node.nodeid)
Defensive patterns

Strategy: validation

Validate before calling

if request.scope == "function":
    fn = request.function
else:
    fn = None  # or use request.node

Type guard

def has_function(request) -> bool:
    return getattr(request, "scope", None) == "function"

Try / catch

try:
    fn = request.function
except AttributeError:
    fn = None

Prevention

When it happens

Trigger: Accessing `request.function` inside a fixture declared with `scope="session"`, `"module"`, `"class"`, or `"package"`. For example `@pytest.fixture(scope="session")\ndef db(request):\n test_name = request.function.__name__` raises this because session scope has no single function bound to the request.

Common situations: Promoting a function-scoped helper fixture to a wider scope (session/module) to share state, while leaving `request.function`/`request.instance` accesses in place. Copy-pasting fixture code that worked at function scope into a session-scoped conftest.py fixture. Plugins that introspect the running test.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/e2cb6adfc430c2c5.json. Report an issue: GitHub.