pytest-dev/pytest · error · TypeError
object (type: ) must be callable
Error message
{func!r} object (type: {type(func)}) must be callable What it means
Thrown by pytest.raises() in the function-call form when `func` (the second positional argument) is not callable. pytest raises expects a callable to invoke; passing a value, instance, or non-callable object is a misuse.
Solutions
- Pass the callable itself, not its result: pytest.raises(ValueError, myfunc) (no parens).
- If you need args, use pytest.raises(ValueError, myfunc, arg1, arg2).
- Prefer the context-manager form to avoid this footgun: with pytest.raises(ValueError): myfunc(arg1).
Example fix
// before
pytest.raises(ValueError, myfunc()) # calls myfunc first
// after - function form
pytest.raises(ValueError, myfunc, arg1)
// or context-manager form
with pytest.raises(ValueError):
myfunc(arg1) Defensive patterns
Strategy: type-guard
Validate before calling
if not callable(func):
raise TypeError(f'{func!r} is not callable; pass the function, not its result')
pytest.raises(ValueError, func) Type guard
from collections.abc import Callable
def is_callable_for_raises(func: object) -> bool:
return callable(func) Prevention
- Pass the callable itself, not its invocation result.
- Prefer the context-manager form to sidestep the footgun.
- Use pytest.raises(Exc, func, *args) to pass arguments.
When it happens
Trigger: Calling pytest.raises(ValueError, 'not a function'); pytest.raises(ValueError, some_object); passing the result of calling a function instead of the function itself: pytest.raises(ValueError, myfunc()).
Common situations: Forgetting to pass the callable (passing its return value); passing a string instead of a function; passing an instance of a non-callable class; copy-paste errors.
Related errors
- Expected an exception type or a tuple of exception types…
- object (type: ) must be callable
- Unexpected keyword arguments passed to pytest.raises
- use setattr(target, name, value) or setattr(target, value)…
- `allow_unwrapped=True` bypasses the `match` and `check`…
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/85f37b89487a62e0.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/raises.py:275
if func is None and not args:
if set(kwargs) - {"match", "check", "expected_exception"}:
msg = "Unexpected keyword arguments passed to pytest.raises: "
msg += ", ".join(sorted(kwargs))
msg += "\nUse context-manager form instead?"
raise TypeError(msg)
if expected_exception is None:
return RaisesExc(**kwargs)
return RaisesExc(expected_exception, **kwargs)
if not expected_exception:
raise ValueError(
f"Expected an exception type or a tuple of exception types, but got `{expected_exception!r}`. "
f"Raising exceptions is already understood as failing the test, so you don't need "
f"any special code to say 'this should never raise an exception'."
)
if not callable(func):
raise TypeError(f"{func!r} object (type: {type(func)}) must be callable")
with RaisesExc(expected_exception) as excinfo:
func(*args, **kwargs)
try:
return excinfo
finally:
del excinfo
# note: RaisesExc/RaisesGroup uses fail() internally, so this alias
# indicates (to [internal] plugins?) that `pytest.raises` will
# raise `_pytest.outcomes.Failed`, where
# `outcomes.Failed is outcomes.fail.Exception is raises.Exception`
# note: this is *not* the same as `_pytest.main.Failed`
# note: mypy does not recognize this attribute, and it's not possible
# to use a protocol/decorator like the others in outcomes due to
# https://github.com/python/mypy/issues/18715
raises.Exception = fail.Exception # type: ignore[attr-defined]
View on GitHub (pinned to 0d6fbdeffa)