{"record":{"id":"0495c6e2ebe75acf","repo":"pypa/pip","slug":"self-class-name-r-used-without-bound-fun","errorCode":null,"errorMessage":"{self.__class__.__name__!r} used without bound function","messagePattern":"(.+?) used without bound function","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pygments/filter.py","lineNumber":65,"sourceCode":"    def __init__(self, **options):\n        self.options = options\n\n    def filter(self, lexer, stream):\n        raise NotImplementedError()\n\n\nclass FunctionFilter(Filter):\n    \"\"\"\n    Abstract class used by `simplefilter` to create simple\n    function filters on the fly. The `simplefilter` decorator\n    automatically creates subclasses of this class for\n    functions passed to it.\n    \"\"\"\n    function = None\n\n    def __init__(self, **options):\n        if not hasattr(self, 'function'):\n            raise TypeError(f'{self.__class__.__name__!r} used without bound function')\n        Filter.__init__(self, **options)\n\n    def filter(self, lexer, stream):\n        # pylint: disable=not-callable\n        yield from self.function(lexer, stream, self.options)\n","sourceCodeStart":47,"sourceCodeEnd":71,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/pygments/filter.py#L47-L71","documentation":"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.","triggerScenarios":"Subclassing FunctionFilter without assigning a 'function' class attribute, or instantiating FunctionFilter() directly. The check hasattr(self, 'function') returns False.","commonSituations":"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.","solutions":["Use the @simplefilter decorator on your function so 'function' is bound automatically.","If subclassing FunctionFilter, set a 'function' class attribute explicitly.","Subclass the base Filter class directly and override filter() instead of using FunctionFilter."],"exampleFix":"# before\nclass MyFilter(FunctionFilter):\n    def my_fn(self, lexer, stream, options):\n        ...\n# after\nfrom pip._vendor.pygments.filter import simplefilter\n@simplefilter\ndef my_filter(self, lexer, stream, options):\n    for ttype, value in stream:\n        yield ttype, value.upper()","handlingStrategy":"validation","validationCode":"from pip._vendor.pygments.filter import FunctionFilter\nif isinstance(f, FunctionFilter) and not hasattr(f, 'function'):\n    raise TypeError('FunctionFilter missing bound function')","typeGuard":"def is_bound_filter(obj) -> bool:\n    return not (type(obj).__name__ == 'FunctionFilter' and getattr(obj, 'function', None) is None)","tryCatchPattern":"try:\n    f = MyFilter()\nexcept TypeError as e:\n    if 'bound function' in str(e):\n        f = MyFilter(function=my_fn)\n    else:\n        raise","preventionTips":["Use @simplefilter instead of subclassing FunctionFilter.","If subclassing, set the 'function' attribute explicitly."],"tags":["python","pygments","filter","validation","vendored"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}