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 when the `excclass` option is not a subclass of Exception (or not a class at all). The constructor runs issubclass(self.exception, Exception); if that raises TypeError (non-class or wrong hierarchy) the filter re-raises it as OptionError. The filter uses this class to raise when the lexer emits an Error token.

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

Solutions

  1. Pass an actual Exception subclass object, e.g. excclass=ValueError, not its name.
  2. Omit excclass entirely to use the default pygments.filters.ErrorToken.
  3. Validate the value with issubclass(x, Exception) before passing it.

Example fix

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

Strategy: validation

Validate before calling

from pygments.util import OptionError
def valid_excclass(x):
    return x is None or (isinstance(x, type) and issubclass(x, Exception))
# before constructing the filter:
if not valid_excclass(opts.get('excclass')):
    raise ValueError('excclass must be an Exception subclass')

Type guard

import inspect
def is_exception_class(x):
    return inspect.isclass(x) and issubclass(x, Exception)

Try / catch

from pygments.util import OptionError
try:
    f = get_filter_by_name('raiseonerror', excclass=value)
except OptionError as e:
    # fall back to default error token behaviour
    f = get_filter_by_name('raiseonerror')

Prevention

When it happens

Trigger: Constructing RaiseOnErrorTokenFilter(excclass=<not-a-class>) directly, or via get_filter_by_name('raiseonerror', excclass='MyError') (a string), or passing a class that does not inherit Exception such as excclass=int.

Common situations: Passing a string class name instead of the class object (common when deserializing options from config/CLI); passing a custom error class that forgets to subclass Exception; typos in the option key.

Related errors


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