pypa/pip · error · ClassNotFound
cannot read
Error message
cannot read {filename}: {err} What it means
Raised by load_lexer_from_file() as a ClassNotFound (wrapping the OSError) when open(filename, 'rb') fails at line 153, caught by the `except OSError as err` branch at line 161-162. It indicates the file path itself could not be opened or read by the OS.
Solutions
- Verify the file exists with os.path.isfile(filename) before calling, and print os.path.abspath(filename) to confirm the resolved path.
- Use an absolute path instead of a relative one, since load_lexer_from_file resolves relative to cwd which may differ from what you expect.
- Check filesystem permissions on the target file (read bit must be set for the running user).
Example fix
// before
lexer = load_lexer_from_file('custom_lexer.py')
// after
import os
path = os.path.join(os.path.dirname(__file__), 'custom_lexer.py')
lexer = load_lexer_from_file(path) Defensive patterns
Strategy: validation
Validate before calling
import os
def path_readable(filename):
return os.path.isfile(filename) and os.access(filename, os.R_OK) Try / catch
from pygments.util import ClassNotFound
try:
lexer = load_lexer_from_file(path)
except ClassNotFound as e:
if 'cannot read' in str(e):
# missing/unreadable file — handle gracefully
lexer = None
raise Prevention
- Resolve the path to absolute before calling and log os.path.abspath to confirm location.
- Guard with os.path.isfile() and an os.access(..., os.R_OK) check.
When it happens
Trigger: Calling load_lexer_from_file() with a path to a nonexistent file, a directory instead of a file, or a file without read permissions. Any OSError from open() or f.read() lands here.
Common situations: Typo or wrong relative path (the function resolves relative to cwd, not sys.path or the package directory); pointing at a directory; file owned by another user with mode 000; path containing the right name but wrong case on case-sensitive filesystems.
Related errors
- error when loading custom lexer
- no valid class found in
- lex() argument must be a lexer instance, not a class
- no lexer for alias found
- no lexer for filename
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/5c47650158d733b1.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/pygments/lexers/__init__.py:162
is equivalent to running eval on the input file.
Raises ClassNotFound if there are any problems importing the Lexer.
.. versionadded:: 2.2
"""
try:
# This empty dict will contain the namespace for the exec'd file
custom_namespace = {}
with open(filename, 'rb') as f:
exec(f.read(), custom_namespace)
# Retrieve the class `lexername` from that namespace
if lexername not in custom_namespace:
raise ClassNotFound(f'no valid {lexername} class found in {filename}')
lexer_class = custom_namespace[lexername]
# And finally instantiate it with the options
return lexer_class(**options)
except OSError as err:
raise ClassNotFound(f'cannot read {filename}: {err}')
except ClassNotFound:
raise
except Exception as err:
raise ClassNotFound(f'error when loading custom lexer: {err}')
def find_lexer_class_for_filename(_fn, code=None):
"""Get a lexer for a filename.
If multiple lexers match the filename pattern, use ``analyse_text()`` to
figure out which one is more appropriate.
Returns None if not found.
"""
matches = []
fn = basename(_fn)
for modname, name, _, filenames, _ in LEXERS.values():
for filename in filenames:View on GitHub (pinned to f399c37189)