python/cpython · error · TypeError

lineno must be an int

Error message

lineno must be an int

What it means

Raised by warnings.filterwarnings when lineno is not an int. The filter tuple stores a plain integer line number (0 matches all lines); strings like '42', floats, or None are rejected with TypeError('lineno must be an int'). Note bool passes isinstance(x, int) but 0/False and True/1 mean lines all and 1 respectively.

Source

Thrown at Lib/_py_warnings.py:275

    'action' -- one of "error", "ignore", "always", "all", "default", "module",
                or "once"
    'message' -- a regex that the warning message must match
    'category' -- a class that the warning must be a subclass of
    'module' -- a regex that the module name must match
    'lineno' -- an integer line number, 0 matches all warnings
    'append' -- if true, append to the list of filters
    """
    if action not in {"error", "ignore", "always", "all", "default", "module", "once"}:
        raise ValueError(f"invalid action: {action!r}")
    if not isinstance(message, str):
        raise TypeError("message must be a string")
    if not isinstance(category, type) or not issubclass(category, Warning):
        raise TypeError("category must be a Warning subclass")
    if not isinstance(module, str):
        raise TypeError("module must be a string")
    if not isinstance(lineno, int):
        raise TypeError("lineno must be an int")
    if lineno < 0:
        raise ValueError("lineno must be an int >= 0")

    if message or module:
        import re

    if message:
        message = re.compile(message, re.I)
    else:
        message = None
    if module:
        module = re.compile(module)
    else:
        module = None

    _wm._add_filter(action, message, category, module, lineno, append=append)

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Pass an int: lineno=3, or 0 to match all lines
  2. Coerce config values: lineno=int(raw) at parse time
  3. Use 0 (the default) instead of None for 'any line'

Example fix

# before
warnings.filterwarnings('ignore', lineno=config['line'])  # '3' from JSON -> TypeError

# after
warnings.filterwarnings('ignore', lineno=int(config['line']))
Defensive patterns

Strategy: type-guard

Validate before calling

def as_lineno(value) -> int:
    if value is None:
        return 0
    if isinstance(value, bool) or not isinstance(value, int):
        raise TypeError(f'lineno must be int, got {type(value).__name__}')
    return value

import warnings
warnings.filterwarnings('ignore', lineno=as_lineno(raw))

Type guard

def is_plain_int(v) -> bool:
    return isinstance(v, int) and not isinstance(v, bool)

Prevention

When it happens

Trigger: warnings.filterwarnings('ignore', lineno='3'); lineno=None; lineno=3.0; lineno read from a config file as a string and forwarded unconverted.

Common situations: Config/CLI-driven warning filters where values arrive as strings; JSON/YAML settings parsed into strings; None used to mean 'any line' instead of 0.

Related errors


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