{"id":"5c47650158d733b1","repo":"pypa/pip","slug":"cannot-read-filename-err-5c4765","errorCode":null,"errorMessage":"cannot read {filename}: {err}","messagePattern":"cannot read (.+?): (.+?)","errorType":"exception","errorClass":"ClassNotFound","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pygments/lexers/__init__.py","lineNumber":162,"sourceCode":"    is equivalent to running eval on the input file.\n\n    Raises ClassNotFound if there are any problems importing the Lexer.\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 `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:","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/pygments/lexers/__init__.py#L144-L180","documentation":"Raised by load_lexer_from_file when open(filename) raises OSError (file missing, permission denied, is a directory). The path is relative to the current working directory.","triggerScenarios":"load_lexer_from_file('missing.py'), passing a directory, or running from a different cwd so a relative path doesn't resolve.","commonSituations":"Wrong cwd; path typo; permission denied; file present in dev env but absent in deployed env.","solutions":["Check os.path.isfile before calling.","Use an absolute path built from a known base.","Fix permissions or correct the path."],"exampleFix":"# before\nload_lexer_from_file('lexers/mylex.py')  # wrong cwd\n# after\nimport os\nbase = os.path.dirname(os.path.abspath(__file__))\nload_lexer_from_file(os.path.join(base, 'lexers', 'mylex.py'))","handlingStrategy":"validation","validationCode":"import os\ndef readable_file(p):\n    return os.path.isfile(p) and os.access(p, os.R_OK)\nif not readable_file(filename):\n    raise FileNotFoundError(filename)","typeGuard":null,"tryCatchPattern":"from pygments.util import ClassNotFound\nfrom pygments.lexers import TextLexer\ntry:\n    lex = load_lexer_from_file(fn)\nexcept ClassNotFound as e:\n    if 'cannot read' in str(e):\n        lex = TextLexer()\n    else:\n        raise","preventionTips":["Use absolute paths.","Validate with os.path.isfile before loading."],"tags":["pygments","lexer","filesystem","custom"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}