pytest-dev/pytest · error · UsageError

invalid lineno {lineno_!r}: {e}

Error message

invalid lineno {lineno_!r}: {e}

What it means

Pytest raises this UsageError when the line-number (5th) field of a warning filter spec is not a valid non-negative integer. The offending lineno string and the underlying ValueError (including the 'number is negative' inner message) are shown. This is the user-facing wrapper around the ValueError from int() parsing or the negativity check.

Source

Thrown at src/_pytest/config/__init__.py:2311

    try:
        category: type[Warning] = _resolve_warning_category(category_)
    except ImportError:
        raise
    except Exception:
        exc_info = ExceptionInfo.from_current()
        exception_text = exc_info.getrepr(style="native")
        raise UsageError(error_template.format(error=exception_text)) from None
    if message and escape:
        message = re.escape(message)
    if module and escape:
        module = re.escape(module) + r"\Z"
    if lineno_:
        try:
            lineno = int(lineno_)
            if lineno < 0:
                raise ValueError("number is negative")
        except ValueError as e:
            raise UsageError(
                error_template.format(error=f"invalid lineno {lineno_!r}: {e}")
            ) from None
    else:
        lineno = 0
    try:
        re.compile(message)
        re.compile(module)
    except re.error as e:
        raise UsageError(
            error_template.format(error=f"Invalid regex {e.pattern!r}: {e}")
        ) from None
    return action, message, category, module, lineno


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).

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Remove the lineno field entirely if you don't need line-scoped filtering (leave it empty).
  2. Provide a valid non-negative integer (0 means any line).
  3. Count your colons — exactly 4 separators for 5 fields: action:message:category:module:lineno.

Example fix

# before (non-numeric lineno)
pytest -W 'ignore::DeprecationWarning::mymod:line42'

# after
pytest -W 'ignore::DeprecationWarning::mymod:42'
Defensive patterns

Strategy: validation

Validate before calling

def parse_lineno(field: str) -> int:
    field = field.strip()
    if not field:
        return 0
    try:
        n = int(field)
    except ValueError:
        raise ValueError(f'invalid lineno {field!r}: not an integer')
    if n < 0:
        raise ValueError(f'invalid lineno {field!r}: negative')
    return n

Type guard

def is_valid_lineno_str(value: str) -> bool:
    try:
        n = int(value)
    except ValueError:
        return False
    return n >= 0

Prevention

When it happens

Trigger: A filter like 'ignore::DeprecationWarning::mymod:abc' (non-numeric lineno) or 'ignore::DeprecationWarning::mymod:-3' (negative). The int(lineno_) call raises ValueError, which is caught and reformatted as this UsageError.

Common situations: Typos in the lineno field; accidentally placing a module name or message in the lineno slot due to mis-counted colons; copied filter strings from a source that used a different field delimiter.

Related errors


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