pypa/pip · error · OptionError

excclass option is not an exception class

Error message

excclass option is not an exception class

What it means

Raised by RaiseOnErrorTokenFilter.__init__ when the 'excclass' option is not a subclass of Exception. The filter validates via issubclass(exception, Exception); if the value is not a class at all, issubclass raises TypeError which is caught and converted to OptionError. This ensures only valid exception classes are wired up to fire on error tokens.

Solutions

  1. Pass an actual Exception subclass class object: excclass=RuntimeError.
  2. Omit excclass to use the default ErrorToken class.
  3. Ensure the value is a class (type) and a subclass of Exception before passing.

Example fix

# before
get_filter_by_name('raiseonerror', excclass='RuntimeError')
# after
get_filter_by_name('raiseonerror', excclass=RuntimeError)
Defensive patterns

Strategy: validation

Validate before calling

import inspect
if excclass is not None and not (inspect.isclass(excclass) and issubclass(excclass, Exception)):
    raise ValueError('excclass must be an Exception subclass')

Type guard

def is_exception_class(obj) -> bool:
    import inspect
    return inspect.isclass(obj) and issubclass(obj, Exception)

Try / catch

from pip._vendor.pygments.util import OptionError
try:
    f = get_filter_by_name('raiseonerror', excclass=cls)
except OptionError:
    f = get_filter_by_name('raiseonerror')  # default excclass

Prevention

When it happens

Trigger: Passing get_filter_by_name('raiseonerror', excclass=SomeNonExceptionClass) or excclass='RuntimeError' (a string instead of the class), or excclass=1234. Any value that is not an Exception subclass trips the check at filters/__init__.py:778-783.

Common situations: Passing the exception name as a string instead of the class object; passing a BaseException subclass (not Exception); passing a non-class value; typos in the option key.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/0917b63a7c93c5a7. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_vendor/pygments/filters/__init__.py:783

    Options accepted:

    `excclass` : Exception class
      The exception class to raise.
      The default is `pygments.filters.ErrorToken`.

    .. versionadded:: 0.8
    """

    def __init__(self, **options):
        Filter.__init__(self, **options)
        self.exception = options.get('excclass', ErrorToken)
        try:
            # issubclass() will raise TypeError if first argument is not a class
            if not issubclass(self.exception, Exception):
                raise TypeError
        except TypeError:
            raise OptionError('excclass option is not an exception class')

    def filter(self, lexer, stream):
        for ttype, value in stream:
            if ttype is Error:
                raise self.exception(value)
            yield ttype, value


class VisibleWhitespaceFilter(Filter):
    """Convert tabs, newlines and/or spaces to visible characters.

    Options accepted:

    `spaces` : string or bool
      If this is a one-character string, spaces will be replaces by this string.
      If it is another true value, spaces will be replaced by ``·`` (unicode
      MIDDLE DOT).  If it is a false value, spaces will not be replaced.  The
      default is ``False``.

View on GitHub (pinned to f399c37189)