{"id":"30661ffcce68335b","repo":"pypa/pip","slug":"error-when-loading-custom-lexer-err","errorCode":null,"errorMessage":"error when loading custom lexer: {err}","messagePattern":"error when loading custom lexer: (.+?)","errorType":"exception","errorClass":"ClassNotFound","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pygments/lexers/__init__.py","lineNumber":166,"sourceCode":"    .. 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 `lexername` from that namespace\n        if lexername not in custom_namespace:\n            raise ClassNotFound(f'no valid {lexername} class found in {filename}')\n        lexer_class = custom_namespace[lexername]\n        # And finally instantiate it with the options\n        return lexer_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 lexer: {err}')\n\n\ndef find_lexer_class_for_filename(_fn, code=None):\n    \"\"\"Get a lexer for a filename.\n\n    If multiple lexers match the filename pattern, use ``analyse_text()`` to\n    figure out which one is more appropriate.\n\n    Returns None if not found.\n    \"\"\"\n    matches = []\n    fn = basename(_fn)\n    for modname, name, _, filenames, _ in LEXERS.values():\n        for filename in filenames:\n            if _fn_matches(fn, filename):\n                if name not in _lexer_cache:\n                    _load_lexers(modname)\n                matches.append((_lexer_cache[name], filename))","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/pygments/lexers/__init__.py#L148-L184","documentation":"Raised by load_lexer_from_file as a catch-all when exec() of the file raises any exception other than OSError or ClassNotFound (SyntaxError, ImportError, NameError, etc.). The original exception text is embedded in the message.","triggerScenarios":"The custom lexer file has a syntax error, an unresolved import, or any runtime error during module execution.","commonSituations":"Typo introduced while editing the lexer file; depending on a package not installed in the env; Python-version-incompatible syntax in the file.","solutions":["Byte-compile the file (python -m py_compile mylex.py) to find syntax errors.","Run the file directly to see the real traceback.","Install missing imports reported in the embedded message."],"exampleFix":"# before: mylex.py has `from missing_pkg import X`\n# diagnose:\n#   python mylex.py -> ModuleNotFoundError\n# after: install missing_pkg or remove the import","handlingStrategy":"try-catch","validationCode":"import py_compile\ndef compiles_clean(filename):\n    try:\n        py_compile.compile(filename, doraise=True)\n        return True\n    except py_compile.PyCompileError:\n        return False","typeGuard":null,"tryCatchPattern":"from pygments.util import ClassNotFound\nfrom pygments.lexers import TextLexer\ntry:\n    lex = load_lexer_from_file(fn, name)\nexcept ClassNotFound as e:\n    if 'error when loading' in str(e):\n        log.error('custom lexer failed: %s', e)\n        lex = TextLexer()\n    else:\n        raise","preventionTips":["Byte-compile custom lexer files before loading.","Keep custom lexer dependencies installed."],"tags":["pygments","lexer","custom","dynamic-load"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}