pytest-dev/pytest · error · TypeError
Error evaluating while defining fixture ' '. Expected a…
Error message
Error evaluating {scope_callable} while defining fixture '{fixture_name}'.
Expected a function with the signature (*, fixture_name, config) What it means
_eval_scope_callable (fixtures.py:1098) invokes a dynamic scope function passed via @pytest.fixture(scope=callable). If calling it raises ANY Exception, pytest wraps that as TypeError with guidance that the callable must accept keyword-only 'fixture_name' and 'config'. This is strictly a signature/implementation problem in the user-supplied scope function.
Solutions
- Define the scope callable exactly as def my_scope(*, fixture_name, config): ... returning a scope string.
- Ensure the function returns one of 'function','class','module','package','session'.
- Catch/handle any internal errors inside the callable so it does not propagate.
- Verify config option names exist (config.getoption) before accessing them inside the callable.
Example fix
// before
@pytest.fixture(scope=lambda name: 'session' if name == 'db' else 'function')
def db(): ...
// after
def _scope(*, fixture_name, config):
return 'session' if fixture_name == 'db' else 'function'
@pytest.fixture(scope=_scope)
def db(): ... Defensive patterns
Strategy: type-guard
Validate before calling
import inspect
def assert_scope_callable(fn):
sig = inspect.signature(fn)
params = {p.name: p.kind for p in sig.parameters.values()}
assert {'fixture_name','config'} <= set(params), 'scope callable must take fixture_name and config'
assert all(k == inspect.Parameter.KEYWORD_ONLY for k in params.values()), 'use keyword-only params' Type guard
import inspect
from typing import Callable
def is_valid_scope_callable(fn) -> bool:
try:
sig = inspect.signature(fn)
except (TypeError, ValueError):
return False
names = set(sig.parameters)
return {'fixture_name','config'} <= names Prevention
- Always define dynamic scope as def fn(*, fixture_name, config): ...
- Unit-test the scope callable directly before wiring it to @pytest.fixture.
- Validate return is one of the allowed scope strings.
When it happens
Trigger: Passing scope=<function> whose signature is not (*, fixture_name, config), e.g. def scope(name): ...; the callable raising internally (e.g. config.getoption on a missing option); a lambda that ignores required kwargs.
Common situations: Trying to make scope depend on configuration but writing the wrong parameter names; using positional params instead of keyword-only; raising inside the scope function due to a typo or missing config option; copying a scope callable from an older pytest version with a different signature contract.
Related errors
- parsefactories() requires holder or node_or_obj
- class fixtures not supported (maybe in the future)
- cls not available in
- errors during test teardown
- errors while tearing down fixture
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/43eeafbc3e46c3fe.
Report an issue: GitHub.
Appendix: 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 0d6fbdeffa)