{"id":"9f44d8cd77e6a82d","repo":"pypa/pip","slug":"no-valid-formattername-class-found-in-filename","errorCode":null,"errorMessage":"no valid {formattername} class found in {filename}","messagePattern":"no valid (.+?) class found in (.+?)","errorType":"exception","errorClass":"ClassNotFound","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pygments/formatters/__init__.py","lineNumber":106,"sourceCode":"\n    The file is expected to contain a Formatter class named ``formattername``\n    (by default, CustomFormatter). Users should be very careful with the input, because\n    this method is equivalent to running ``eval()`` on the input file. The formatter is\n    given the `options` at its instantiation.\n\n    :exc:`pygments.util.ClassNotFound` is raised if there are any errors loading\n    the formatter.\n\n    .. versionadded:: 2.2\n    \"\"\"\n    try:\n        # This empty dict will contain the namespace for the exec'd file\n        custom_namespace = {}\n        with open(filename, 'rb') as f:\n            exec(f.read(), custom_namespace)\n        # Retrieve the class `formattername` from that namespace\n        if formattername not in custom_namespace:\n            raise ClassNotFound(f'no valid {formattername} class found in {filename}')\n        formatter_class = custom_namespace[formattername]\n        # And finally instantiate it with the options\n        return formatter_class(**options)\n    except OSError as err:\n        raise ClassNotFound(f'cannot read {filename}: {err}')\n    except ClassNotFound:\n        raise\n    except Exception as err:\n        raise ClassNotFound(f'error when loading custom formatter: {err}')\n\n\ndef get_formatter_for_filename(fn, **options):\n    \"\"\"\n    Return a :class:`.Formatter` subclass instance that has a filename pattern\n    matching `fn`. The formatter is given the `options` at its instantiation.\n\n    Will raise :exc:`pygments.util.ClassNotFound` if no formatter for that filename\n    is found.","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/pygments/formatters/__init__.py#L88-L124","documentation":"Raised by load_formatter_from_file when the file was opened and exec'd successfully but the expected class name (formattername, default 'CustomFormatter') is absent from the resulting namespace. The file ran, but it didn't define the class you named.","triggerScenarios":"load_formatter_from_file('myfmt.py', 'MyFormatter') where myfmt.py defines a differently-named class, defines it inside a function/conditional, or defines none at all.","commonSituations":"Default class name mismatch (file defines ColorFormatter but you call without specifying, expecting CustomFormatter); class defined conditionally so it isn't in module namespace at exec time; copy-paste from another formatter without renaming the class.","solutions":["Open the file and confirm the exact class name, then pass it as formattername.","Name your class CustomFormatter to match the default.","Ensure the class is defined at module top level, not nested or guarded by a runtime condition."],"exampleFix":"# before\nload_formatter_from_file('myfmt.py')  # file defines ColorFormatter\n# after\nload_formatter_from_file('myfmt.py', 'ColorFormatter')","handlingStrategy":"validation","validationCode":"import inspect\ndef class_in_file(filename, cls_name):\n    ns = {}\n    with open(filename, 'rb') as f:\n        exec(f.read(), ns)\n    return cls_name in ns and inspect.isclass(ns[cls_name])","typeGuard":null,"tryCatchPattern":"from pygments.util import ClassNotFound\ntry:\n    fmt = load_formatter_from_file(fn, name)\nexcept ClassNotFound as e:\n    # inspect message, fall back to a builtin formatter\n    fmt = get_formatter_by_name('html')","preventionTips":["Keep the custom class at module scope.","Use the default name CustomFormatter to avoid mismatches."],"tags":["pygments","formatter","custom","dynamic-load"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}