pypa/pip · error · ClassNotFound
error when loading custom lexer
Error message
error when loading custom lexer: {err} What it means
Raised by load_lexer_from_file() as a ClassNotFound when exec(f.read(), custom_namespace) at line 154, or the subsequent instantiation at line 160, raises any exception that is not OSError or ClassNotFound — caught by the generic `except Exception as err` at line 165-166. The inner error is stringified into the message.
Solutions
- Open and inspect the inner error in the message — it includes the original exception text (e.g., ImportError: No module named 'foo').
- Import and exec the file yourself in a REPL to reproduce the underlying exception with a full traceback before the ClassNotFound wrapper hides it.
- Ensure all dependencies the custom lexer file imports are installed and that the file is syntactically valid (python -m py_compile yourfile.py).
Example fix
// before
lexer = load_lexer_from_file('mylexer.py') # raises "error when loading custom lexer: ImportError ..."
// after
# reproduce raw error first to see full traceback
import ast; ast.parse(open('mylexer.py','rb').read())
# then fix the missing dependency / syntax in mylexer.py
lexer = load_lexer_from_file('mylexer.py') Defensive patterns
Strategy: try-catch
Validate before calling
import ast
def file_parses(filename):
try:
ast.parse(open(filename, 'rb').read(), filename=filename)
return True
except SyntaxError:
return False Try / catch
from pygments.util import ClassNotFound
try:
lexer = load_lexer_from_file(path, lexername=name)
except ClassNotFound as e:
# 'error when loading custom lexer: <inner>' — surface inner cause
raise RuntimeError(f'custom lexer load failed: {e}') from e Prevention
- Run python -m py_compile on the lexer file before loading to catch syntax errors early.
- Ensure every import inside the custom lexer file is satisfiable in the target environment.
- Reproduce the exec() in a REPL to see the unwrapped traceback before relying on the wrapped message.
When it happens
Trigger: The loaded file contains a Python SyntaxError, ImportError, or NameError; the file defines the class but the class's __init__ or a module-level statement raises during exec; the retrieved class is not callable or fails at lexer_class(**options).
Common situations: The custom lexer file imports another module that is not installed in the environment; the file has an unguarded import that fails at exec time; the lexer class constructor requires arguments not supplied via options; a typo/indentation error in the file.
Related errors
- cannot read
- 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/30661ffcce68335b.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/pygments/lexers/__init__.py:166
.. 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:
if _fn_matches(fn, filename):
if name not in _lexer_cache:
_load_lexers(modname)
matches.append((_lexer_cache[name], filename))View on GitHub (pinned to f399c37189)