pytest-dev/pytest · error · TypeError
Error evaluating {scope_callable} while defining fixture '{f
Error message
Error evaluating {scope_callable} while defining fixture '{fixture_name}'.
Expected a function with the signature (*, fixture_name, config) What it means
Raised by `_eval_scope_callable` when the dynamic scope callable passed to `@pytest.fixture(scope=callable)` either raises or does not accept the required keyword-only signature `(*, fixture_name, config)`. pytest calls the callable at collection time to compute the scope string; any exception is wrapped in this TypeError pointing at the offending callable.
Source
Thrown at src/_pytest/fixtures.py:1098
fail(
f"fixture function has more than one 'yield':\n\n"
f"{Source(fixturefunc).indent()}\n"
f"{fs}:{lineno + 1}",
pytrace=False,
)
def _eval_scope_callable(
scope_callable: Callable[[str, Config], ScopeName],
fixture_name: str,
config: Config,
) -> ScopeName:
try:
# Type ignored because there is no typing mechanism to specify
# keyword arguments, currently.
result = scope_callable(fixture_name=fixture_name, config=config) # type: ignore[call-arg]
except Exception as e:
raise TypeError(
f"Error evaluating {scope_callable} while defining fixture '{fixture_name}'.\n"
"Expected a function with the signature (*, fixture_name, config)"
) from e
if not isinstance(result, str):
fail(
f"Expected {scope_callable} to return a 'str' while defining fixture '{fixture_name}', but it returned:\n"
f"{result!r}",
pytrace=False,
)
return result
class FixtureDef(Generic[FixtureValue]):
"""A container for a fixture definition.
Note: At this time, only explicitly documented fields and methods are
considered public stable API.
"""View on GitHub (pinned to 98b357f69e)
Solutions
- Define the callable as `def my_scope(*, fixture_name, config): ...` and return one of "function","class","module","package","session".
- Make sure any config option you read inside the callable is registered via `pytest_addoption`/`addini`.
- Catch/avoid exceptions inside the callable; return a safe default scope on edge cases.
Example fix
// before
def scope(fixture_name): # wrong signature
return "session"
@pytest.fixture(scope=scope)
def x(): yield
// after
def scope(*, fixture_name, config):
return "session" if config.getoption("--ci") else "function"
@pytest.fixture(scope=scope)
def x(): yield Defensive patterns
Strategy: validation
Validate before calling
import inspect
def check_scope_callable(fn):
sig = inspect.signature(fn)
params = [p for p in sig.parameters.values()]
has_var_kw = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in params)
names = {p.name for p in params}
if not ("fixture_name" in names and "config" in names) and not has_var_kw:
raise TypeError("scope callable must accept (*, fixture_name, config)") Type guard
def is_valid_scope_callable(fn) -> bool:
import inspect
try:
sig = inspect.signature(fn)
except (TypeError, ValueError):
return False
names = set(sig.parameters)
return {"fixture_name", "config"}.issubset(names) or any(
p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()
) Prevention
- Define dynamic scope callables as `def scope(*, fixture_name, config):`.
- Register any config option the callable reads via pytest_addoption.
- Return a valid scope string on every path.
When it happens
Trigger: Passing a scope function with the wrong signature, e.g. `def scope(fixture_name)` (missing `config`), or a function that raises (returns based on a missing config option). pytest invokes `scope(fixture_name=..., config=...)` with keyword args.
Common situations: Writing a dynamic-scope fixture that reads `config.getini("...")` for an option that is not registered, or copying a signature from outdated docs. Using positional-only params.
Related errors
- function not available in {self.scope}-scoped context
- cls not available in {self.scope}-scoped context
- module not available in {self.scope}-scoped context
- path not available in {self.scope}-scoped context
- The fixture value for "{argname}" is not available during te
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/43eeafbc3e46c3fe.json.
Report an issue: GitHub.