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

  1. Ensure the referenced class subclasses Warning (e.g. class MyWarning(Warning): ...).
  2. Use a stdlib warning like DeprecationWarning, UserWarning, ResourceWarning, or bare Warning.
  3. 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

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


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/fc099e9a229a78aa.json. Report an issue: GitHub.