pytest-dev/pytest · error · TypeError

object (type: ) must be callable

Error message

{func!r} object (type: {type(func)}) must be callable

What it means

Raised by pytest.warns in its function form when the second positional argument (func) is not callable. The function form pytest.warns(Warning, func, *args, **kwargs) wraps and calls func inside a WarningsChecker; a non-callable func cannot be invoked, so pytest rejects it with the offending repr and type.

Solutions

  1. Pass an actual callable: pytest.warns(UserWarning, my_function, arg1, arg2).
  2. If you meant the context-manager form, omit func entirely: with pytest.warns(UserWarning): my_function(arg1).
  3. Verify callable(func) is True before invoking the function form.

Example fix

// before
pytest.warns(UserWarning, 'emit_warning')
// after
pytest.warns(UserWarning, emit_warning)
// or context-manager form:
with pytest.warns(UserWarning):
    emit_warning()
Defensive patterns

Strategy: type-guard

Validate before calling

assert func is None or callable(func), f'pytest.warns function form requires a callable, got {func!r}'

Type guard

def warns_func_callable(func) -> bool:
    return func is None or callable(func)

Prevention

When it happens

Trigger: pytest.warns(UserWarning, 'some_function'); pytest.warns(UserWarning, None, 1, 2); pytest.warns(UserWarning, some_module) where some_module is a module object, not a function.

Common situations: Forgetting to call a decorator/wrapper that returns a non-callable; passing a module instead of its function; passing a string name instead of the function reference.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/174b1d16d5a601fc. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/recwarn.py:170

    such that some runs raise a warning and others do not.

    This could be achieved in the same way as with exceptions, see
    :ref:`parametrizing_conditional_raising` for an example.

    """
    __tracebackhide__ = True
    if func is None and not args:
        match: str | re.Pattern[str] | None = kwargs.pop("match", None)
        if kwargs:
            argnames = ", ".join(sorted(kwargs))
            raise TypeError(
                f"Unexpected keyword arguments passed to pytest.warns: {argnames}"
                "\nUse context-manager form instead?"
            )
        return WarningsChecker(expected_warning, match_expr=match, _ispytest=True)
    else:
        if not callable(func):
            raise TypeError(f"{func!r} object (type: {type(func)}) must be callable")
        with WarningsChecker(expected_warning, _ispytest=True):
            return func(*args, **kwargs)


class WarningsRecorder(warnings.catch_warnings):
    """A context manager to record raised warnings.

    Each recorded warning is an instance of :class:`warnings.WarningMessage`.

    Adapted from `warnings.catch_warnings`.

    .. note::
        ``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated
        differently; see :ref:`ensuring_function_triggers`.

    """

    def __init__(self, *, _ispytest: bool = False) -> None:

View on GitHub (pinned to 0d6fbdeffa)