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:
passView on GitHub (pinned to bc6749cc3b)
Solutions
- To silence warnings use the filter API instead: warnings.simplefilter('ignore') or filterwarnings
- If replacing the hook, assign a callable with the (message, category, filename, lineno, file=None, line=None) signature
- 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
- Never silence warnings by assigning to warnings.showwarning; use simplefilter('ignore')
- If you replace the hook, replace it with a function and restore it in a finally block
- Use warnings.catch_warnings() to scope hook changes instead of global assignment
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
- invalid action: {action!r}
- Unrecognized action (%r) in warnings.filters: %s
- message must be a string
- category must be a Warning subclass
- module must be a string
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/1ff0c00c5d4c2759.
Report an issue: GitHub.