pypa/pip · error · TypeError

used without bound function

Error message

{self.__class__.__name__!r} used without bound function

What it means

Raised by FunctionFilter.__init__ when the subclass has no 'function' attribute bound. FunctionFilter is meant to be created via the @simplefilter decorator, which injects the wrapped function as a class attribute. Subclassing FunctionFilter directly (or using it without the decorator) leaves 'function' unbound, so the guard at filter.py:64-65 fires.

Solutions

  1. Use the @simplefilter decorator on your function so 'function' is bound automatically.
  2. If subclassing FunctionFilter, set a 'function' class attribute explicitly.
  3. Subclass the base Filter class directly and override filter() instead of using FunctionFilter.

Example fix

# before
class MyFilter(FunctionFilter):
    def my_fn(self, lexer, stream, options):
        ...
# after
from pip._vendor.pygments.filter import simplefilter
@simplefilter
def my_filter(self, lexer, stream, options):
    for ttype, value in stream:
        yield ttype, value.upper()
Defensive patterns

Strategy: validation

Validate before calling

from pip._vendor.pygments.filter import FunctionFilter
if isinstance(f, FunctionFilter) and not hasattr(f, 'function'):
    raise TypeError('FunctionFilter missing bound function')

Type guard

def is_bound_filter(obj) -> bool:
    return not (type(obj).__name__ == 'FunctionFilter' and getattr(obj, 'function', None) is None)

Try / catch

try:
    f = MyFilter()
except TypeError as e:
    if 'bound function' in str(e):
        f = MyFilter(function=my_fn)
    else:
        raise

Prevention

When it happens

Trigger: Subclassing FunctionFilter without assigning a 'function' class attribute, or instantiating FunctionFilter() directly. The check hasattr(self, 'function') returns False.

Common situations: Writing a custom filter by subclassing FunctionFilter instead of Filter; forgetting the @simplefilter decorator on a function intended as a filter; copying the FunctionFilter pattern incorrectly.

Related errors


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

Appendix: source

Thrown at src/pip/_vendor/pygments/filter.py:65

    def __init__(self, **options):
        self.options = options

    def filter(self, lexer, stream):
        raise NotImplementedError()


class FunctionFilter(Filter):
    """
    Abstract class used by `simplefilter` to create simple
    function filters on the fly. The `simplefilter` decorator
    automatically creates subclasses of this class for
    functions passed to it.
    """
    function = None

    def __init__(self, **options):
        if not hasattr(self, 'function'):
            raise TypeError(f'{self.__class__.__name__!r} used without bound function')
        Filter.__init__(self, **options)

    def filter(self, lexer, stream):
        # pylint: disable=not-callable
        yield from self.function(lexer, stream, self.options)

View on GitHub (pinned to f399c37189)