{"id":"b13b0f02c775d7b6","repo":"pypa/pip","slug":"no-lexer-for-filename-fn-r-found-b13b0f","errorCode":null,"errorMessage":"no lexer for filename {fn!r} found","messagePattern":"no lexer for filename (.+?) found","errorType":"exception","errorClass":"ClassNotFound","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pygments/lexers/__init__.py","lineNumber":282,"sourceCode":"    or `alias_filenames` that matches `filename` are taken into consideration.\n\n    :exc:`pygments.util.ClassNotFound` is raised if no lexer thinks it can\n    handle the content.\n    \"\"\"\n    fn = basename(_fn)\n    primary = {}\n    matching_lexers = set()\n    for lexer in _iter_lexerclasses():\n        for filename in lexer.filenames:\n            if _fn_matches(fn, filename):\n                matching_lexers.add(lexer)\n                primary[lexer] = True\n        for filename in lexer.alias_filenames:\n            if _fn_matches(fn, filename):\n                matching_lexers.add(lexer)\n                primary[lexer] = False\n    if not matching_lexers:\n        raise ClassNotFound(f'no lexer for filename {fn!r} found')\n    if len(matching_lexers) == 1:\n        return matching_lexers.pop()(**options)\n    result = []\n    for lexer in matching_lexers:\n        rv = lexer.analyse_text(_text)\n        if rv == 1.0:\n            return lexer(**options)\n        result.append((rv, lexer))\n\n    def type_sort(t):\n        # sort by:\n        # - analyse score\n        # - is primary filename pattern?\n        # - priority\n        # - last resort: class name\n        return (t[0], primary[t[1]], t[1].priority, t[1].__name__)\n    result.sort(key=type_sort)\n","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/pygments/lexers/__init__.py#L264-L300","documentation":"Raised by guess_lexer_for_filename when no lexer's filename glob (in filenames or alias_filenames) matches the basename, so there are zero candidate lexers to score with analyse_text. Distinct from get_lexer_for_filename because it also checks alias_filenames.","triggerScenarios":"guess_lexer_for_filename('archive.xyz', text) where no lexer pattern covers .xyz.","commonSituations":"Editor/preview tool guessing a lexer from an unknown extension; custom build artifact extension; extension removed from a plugin.","solutions":["Use guess_lexer(text) for pure content-based detection (ignores filename).","Use get_lexer_by_name with an explicit alias.","Register a plugin lexer covering the extension."],"exampleFix":"# before\nlex = guess_lexer_for_filename('file.xyz', text)\n# after\nlex = guess_lexer(text)","handlingStrategy":"fallback","validationCode":"from pygments.lexers import guess_lexer_for_filename, guess_lexer, TextLexer\nfrom pygments.util import ClassNotFound\ndef guess_lex(fn, text):\n    try:\n        return guess_lexer_for_filename(fn, text)\n    except ClassNotFound:\n        try:\n            return guess_lexer(text)\n        except ClassNotFound:\n            return TextLexer()","typeGuard":null,"tryCatchPattern":"from pygments.util import ClassNotFound\nfrom pygments.lexers import guess_lexer, TextLexer\ntry:\n    lex = guess_lexer_for_filename(fn, text)\nexcept ClassNotFound:\n    try:\n        lex = guess_lexer(text)\n    except ClassNotFound:\n        lex = TextLexer()","preventionTips":["Cascade: filename guess -> content guess -> TextLexer.","Register plugins for your project's extensions."],"tags":["pygments","lexer","filename","lookup"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}