{"record":{"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/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/pygments/lexers/__init__.py#L264-L300","documentation":"Raised by guess_lexer_for_filename() as a ClassNotFound when the set matching_lexers is empty (line 281-282): no lexer class returned by _iter_lexerclasses() has a filenames or alias_filenames glob matching basename(fn). Unlike get_lexer_for_filename it also feeds text to analyse_text, but it short-circuits before that if no filename pattern matches at all.","triggerScenarios":"Calling guess_lexer_for_filename('data.unknown', text) where no lexer declares a glob for '*.unknown'; the filename has no extension; the filename's extension is registered only as an alias_filename in a plugin that is not installed.","commonSituations":"Processing user-uploaded files with arbitrary or missing extensions; relying on filename matching for a language that only identifies itself by content (no extension convention); vendored Pygments missing a plugin that a standalone Pygments install would provide.","solutions":["Fall back to guess_lexer(text) which ignores the filename and scores purely on content analyse_text().","Pre-register a filename glob for the extension via a custom plugin lexer entry point.","Normalize/normalize the filename (strip query strings, lower-case the extension) before passing it."],"exampleFix":"// before\nlexer = guess_lexer_for_filename('snippet.unknownext', text)\n\n// after\nfrom pygments.lexers import guess_lexer_for_filename, guess_lexer\ntry:\n    lexer = guess_lexer_for_filename('snippet.unknownext', text)\nexcept ClassNotFound:\n    lexer = guess_lexer(text)","handlingStrategy":"fallback","validationCode":"from pygments.lexers import _iter_lexerclasses\nfrom os.path import basename\nimport fnmatch\ndef filename_has_match(fn):\n    b = basename(fn)\n    return any(fnmatch.fnmatch(b, pat) for lx in _iter_lexerclasses() for pat in lx.filenames)","typeGuard":null,"tryCatchPattern":"from pygments.lexers import guess_lexer_for_filename, guess_lexer\nfrom pygments.util import ClassNotFound\ntry:\n    lexer = guess_lexer_for_filename(fn, text)\nexcept ClassNotFound:\n    lexer = guess_lexer(text)","preventionTips":["Always pair guess_lexer_for_filename with a guess_lexer(text) fallback for unknown extensions.","Register plugin lexers with filename globs for custom extensions."],"tags":["pygments","lexer","filename","guess","class-not-found"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}