pytest-dev/pytest · error · UsageError
{cat} is not a Warning subclass
Error message
{cat} is not a Warning subclass What it means
Pytest raises this UsageError when the category field of a warning filter resolves via import/getattr to an object that is not a subclass of the built-in Warning class. Warning filters require the category to be an actual Warning subclass (or the empty string, which defaults to Warning).
Source
Thrown at src/_pytest/config/__init__.py:2344
def _resolve_warning_category(category: str) -> type[Warning]:
"""
Copied from warnings._getcategory, but changed so it lets exceptions (specially ImportErrors)
propagate so we can get access to their tracebacks (#9218).
"""
__tracebackhide__ = True
if not category:
return Warning
if "." not in category:
import builtins as m
klass = category
else:
module, _, klass = category.rpartition(".")
m = importlib.import_module(module)
cat = getattr(m, klass)
if not issubclass(cat, Warning):
raise UsageError(f"{cat} is not a Warning subclass")
return cast(type[Warning], cat)
def apply_warning_filters(
config_filters: Iterable[str], cmdline_filters: Iterable[str]
) -> None:
"""Applies pytest-configured filters to the warnings module"""
# Filters should have this precedence: cmdline options, config.
# Filters should be applied in the inverse order of precedence.
for arg in config_filters:
try:
warnings.filterwarnings(*parse_warning_filter(arg, escape=False))
except ImportError as e:
warnings.warn(
f"Failed to import filter module '{e.name}': {arg}", PytestConfigWarning
)
continue
View on GitHub (pinned to 98b357f69e)
Solutions
- Ensure the referenced class subclasses Warning (e.g. class MyWarning(Warning): ...).
- Use a stdlib warning like DeprecationWarning, UserWarning, ResourceWarning, or bare Warning.
- Double-check field order: the 3rd field is the category, not the module.
Example fix
# before [pytest] filterwarnings = ["ignore::builtins.ValueError"] # after [pytest] filterwarnings = ["ignore::builtins.DeprecationWarning"]
Defensive patterns
Strategy: type-guard
Validate before calling
import importlib, warnings
def resolve_and_check_category(category: str) -> type:
if not category:
return Warning
if '.' not in category:
import builtins
cat = getattr(builtins, category)
else:
module, _, klass = category.rpartition('.')
cat = getattr(importlib.import_module(module), klass)
if not (isinstance(cat, type) and issubclass(cat, warnings.Warning)):
raise TypeError(f'{cat} is not a Warning subclass')
return cat Type guard
import warnings
def is_warning_subclass(obj: object) -> bool:
return isinstance(obj, type) and issubclass(obj, warnings.Warning) Prevention
- Define custom warnings as subclasses of Warning (or a stdlib warning).
- Add a unit test asserting issubclass(MyWarning, Warning).
- Prefer stdlib categories when a custom subclass isn't required.
When it happens
Trigger: A filter like 'ignore::os.path' where os.path is not a Warning subclass, or 'ignore::collections.OrderedDict'. _resolve_warning_category successfully imports and gets the attribute, but issubclass(cat, warning) is False.
Common situations: Pointing the category at a regular exception or arbitrary class by mistake; referring to a class that was renamed from a Warning to a non-Warning; copy-paste errors swapping the category and module fields.
Related errors
- while parsing the following warning configuration: {arg}
- number is negative
- invalid lineno {lineno_!r}: {e}
- Invalid regex {e.pattern!r}: {e}
- invalid type for ini option {name!r}: {type_!r} (expected on
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/fc099e9a229a78aa.json.
Report an issue: GitHub.