python/cpython · error · TypeError

warnings.showwarning() must be set to a function or method

Error message

warnings.showwarning() must be set to a function or method

What it means

Raised by warnings._showwarnmsg when a warning is actually emitted and the hook machinery notices that warnings.showwarning has been replaced with something non-callable. The module deliberately validates user overrides before dispatching, so assigning a constant, string, or None to warnings.showwarning turns the next displayed warning into TypeError.

Source

Thrown at Lib/_py_warnings.py:227

                  f'allocation traceback\n')
    return s


# Keep a reference to check if the function was replaced
_showwarning_orig = showwarning


def _showwarnmsg(msg):
    """Hook to write a warning to a file; replace if you like."""
    try:
        sw = _wm.showwarning
    except AttributeError:
        pass
    else:
        if sw is not _showwarning_orig:
            # warnings.showwarning() was replaced
            if not callable(sw):
                raise TypeError("warnings.showwarning() must be set to a "
                                "function or method")

            sw(msg.message, msg.category, msg.filename, msg.lineno,
               msg.file, msg.line)
            return
    _wm._showwarnmsg_impl(msg)


# Keep a reference to check if the function was replaced
_formatwarning_orig = formatwarning


def _formatwarnmsg(msg):
    """Function to format a warning the standard way."""
    try:
        fw = _wm.formatwarning
    except AttributeError:
        pass

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. To silence warnings use the filter API instead: warnings.simplefilter('ignore') or filterwarnings
  2. If replacing the hook, assign a callable with the (message, category, filename, lineno, file=None, line=None) signature
  3. Restore the original by deleting your override or reassigning a proper function rather than None

Example fix

# before
import warnings
warnings.showwarning = None      # next warning -> TypeError

# after
warnings.simplefilter('ignore')   # correct way to silence
# or a real hook:
warnings.showwarning = lambda message, category, filename, lineno, file=None, line=None: print(f'{filename}:{lineno}: {message}')
Defensive patterns

Strategy: validation

Validate before calling

import warnings

def set_warning_hook(fn) -> None:
    if not callable(fn):
        raise TypeError(f'showwarning must be callable, got {fn!r}')
    warnings.showwarning = fn

Type guard

def is_valid_hook(fn) -> bool:
    import inspect
    return callable(fn) and len(inspect.signature(fn).parameters) >= 4

Try / catch

try:
    warnings.warn('something')
except TypeError as e:
    if 'showwarning() must be set' in str(e):
        import warnings
        del warnings.showwarning  # drop the bad override, restore default
        warnings.warn('something')
    else:
        raise

Prevention

When it happens

Trigger: Assigning a non-callable to warnings.showwarning (e.g. `warnings.showwarning = None` to 'silence' warnings, or assigning a string/template) and then any code path triggers a warning that reaches the display hook.

Common situations: Attempts to mute warnings by clobbering showwarning; copy/pasted snippets that assign a log-format string; libraries that save/restore the hook incorrectly and restore None; test teardowns that reset attributes indiscriminately.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/1ff0c00c5d4c2759. Report an issue: GitHub.