{"record":{"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/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/pygments/formatters/__init__.py#L88-L124","documentation":"Raised by load_formatter_from_file when the exec'd file does not define the expected class name (default 'CustomFormatter') in its namespace. The file was read and executed successfully, but no attribute with formattername exists, so ClassNotFound is raised at __init__.py:105-106. This is a content mismatch, not an I/O or syntax error.","triggerScenarios":"Calling load_formatter_from_file('myfmt.py') when the file defines class MyFormatter but the function looks for CustomFormatter; or passing a wrong formattername argument.","commonSituations":"Forgot to name the class CustomFormatter; mismatched class name between the file and the formattername argument; class defined under a conditional that was False so it never entered the namespace.","solutions":["Name the formatter class CustomFormatter in the file, or pass the correct name: load_formatter_from_file('myfmt.py', 'MyFormatter').","Ensure the class is defined at module top level (not inside an if/try that doesn't run).","Verify the file's contents actually define the class with no import errors."],"exampleFix":"# before\n# myfmt.py defines class MyFormatter(Formatter)\nload_formatter_from_file('myfmt.py')\n# after\nload_formatter_from_file('myfmt.py', 'MyFormatter')","handlingStrategy":"validation","validationCode":"import os\nns = {}\nwith open(path, 'rb') as fh:\n    exec(fh.read(), ns)\nif class_name not in ns:\n    raise ValueError(f'{class_name} not defined in {path}')","typeGuard":"def file_defines_class(path: str, class_name: str) -> bool:\n    import os\n    if not os.path.isfile(path):\n        return False\n    ns = {}\n    with open(path, 'rb') as fh:\n        exec(fh.read(), ns)\n    return class_name in ns","tryCatchPattern":"from pip._vendor.pygments.util import ClassNotFound\ntry:\n    fmt = load_formatter_from_file(path, name)\nexcept ClassNotFound as e:\n    if 'no valid' in str(e):\n        name = 'CustomFormatter'\n        fmt = load_formatter_from_file(path, name)\n    else:\n        raise","preventionTips":["Name custom formatters CustomFormatter or pass the exact name.","Define the class at module top level."],"tags":["python","pygments","formatter","validation","vendored"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}