[BUG] rich.traceback: no lexer for filename X found
See original GitHub issueDescribe the bug
The rich.traceback doesnโt know how to render tracebacks originating from inside jinja2 templates.
The issue is twofold: (1) rich doesnโt recognize the .yaml.j2
extension as jinja2+yaml
, and (2) the fallback isnโt to print the file contents without highlighting but instead to simply not print it at all.
As such this bug likely also affects other languages to compile to python bytecode, such as dg, Hylang and hissp/hebigo.
Repro:
test.py:
import jinja2, os
from rich.traceback import install
install()
def raiser():
raise Exception
env = jinja2.Environment(
loader = jinja2.FileSystemLoader([os.getcwd(), "/"], followlinks=True),
)
env.globals["raiser"] = raiser
template = env.get_template("test.yaml.j2")
print(template.render())
test.yaml.j2:
foobar:
something: {{ raiser() }}
else: {{ 5 + 5 }}
Vanilla traceback:
Traceback (most recent call last):
File "/home/pbsds/tmp/repro/test.py", line 13, in <module>
print(template.render())
File "/usr/lib/python3.10/site-packages/jinja2/environment.py", line 1291, in render
self.environment.handle_exception()
File "/usr/lib/python3.10/site-packages/jinja2/environment.py", line 925, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/home/pbsds/tmp/repro/test.yaml.j2", line 2, in top-level template code
something: {{ raiser() }}
File "/home/pbsds/tmp/repro/test.py", line 4, in raiser
raise Exception
Exception
rich.traceback:
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Traceback (most recent call last) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ /home/pbsds/tmp/repro/test.py:15 in <module> โ
โ โ
โ 12 โ
โ 13 template = env.get_template("test.yaml.j2") โ
โ 14 โ
โ โฑ 15 print(template.render()) โ
โ 16 โ
โ /usr/lib/python3.10/site-packages/jinja2/environment.py:1291 in render โ
โ โ
โ 1288 โ โ try: โ
โ 1289 โ โ โ return concat(self.root_render_func(ctx)) # type: ignore โ
โ 1290 โ โ except Exception: โ
โ โฑ 1291 โ โ โ self.environment.handle_exception() โ
โ 1292 โ โ
โ 1293 โ async def render_async(self, *args: t.Any, **kwargs: t.Any) -> str: โ
โ 1294 โ โ """This works similar to :meth:`render` but returns a coroutine โ
โ โ
โ /usr/lib/python3.10/site-packages/jinja2/environment.py:925 in handle_exception โ
โ โ
โ 922 โ โ """ โ
โ 923 โ โ from .debug import rewrite_traceback_stack โ
โ 924 โ โ โ
โ โฑ 925 โ โ raise rewrite_traceback_stack(source=source) โ
โ 926 โ โ
โ 927 โ def join_path(self, template: str, parent: str) -> str: โ
โ 928 โ โ """Join a template with the parent. By default all the lookups are โ
โ โ
โ /home/pbsds/tmp/repro/test.yaml.j2:2 in top-level template code โ
โ โ
โ no lexer for filename 'test.yaml.j2' found โ
โ โ
โ /home/pbsds/tmp/repro/test.py:6 in raiser โ
โ โ
โ 3 install() โ
โ 4 โ
โ 5 def raiser(): โ
โ โฑ 6 โ raise Exception โ
โ 7 โ
โ 8 env = jinja2.Environment( โ
โ 9 โ loader = jinja2.FileSystemLoader([os.getcwd(), "/"], followlinks=True), โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Platform
Click to expand
What platform (Win/Linux/Mac) are you running on? What terminal software are you using?
Manjaro GNOME, python 3.10.2, lxterminal
I may ask you to copy and paste the output of the following commands. It may save some time if you do it now.
If youโre using Rich in a terminal:
โญโโโโโโโโโโโโโโโโโโโโโโโ <class 'rich.console.Console'> โโโโโโโโโโโโโโโโโโโโโโโโฎ
โ A high level console interface. โ
โ โ
โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ
โ โ <console width=80 ColorSystem.TRUECOLOR> โ โ
โ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ โ
โ โ
โ color_system = 'truecolor' โ
โ encoding = 'utf-8' โ
โ file = <_io.TextIOWrapper name='<stdout>' mode='w' โ
โ encoding='utf-8'> โ
โ height = 24 โ
โ is_alt_screen = False โ
โ is_dumb_terminal = False โ
โ is_interactive = True โ
โ is_jupyter = False โ
โ is_terminal = True โ
โ legacy_windows = False โ
โ no_color = False โ
โ options = ConsoleOptions( โ
โ size=ConsoleDimensions(width=80, height=24), โ
โ legacy_windows=False, โ
โ min_width=1, โ
โ max_width=80, โ
โ is_terminal=True, โ
โ encoding='utf-8', โ
โ max_height=24, โ
โ justify=None, โ
โ overflow=None, โ
โ no_wrap=False, โ
โ highlight=None, โ
โ markup=None, โ
โ height=None โ
โ ) โ
โ quiet = False โ
โ record = False โ
โ safe_box = True โ
โ size = ConsoleDimensions(width=80, height=24) โ
โ soft_wrap = False โ
โ stderr = False โ
โ style = None โ
โ tab_size = 8 โ
โ width = 80 โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
rich==11.0.0
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Iโve found the cause of this problem, the
guess_lexer_for_filename
method from thepygments.lexers
module raises aClassNotFound
upon not being able to find a suitable lexer. And that function is used in the richTraceback._guess_lexer
function:https://github.com/Textualize/rich/blob/master/rich/traceback.py#L513-L527
Upon getting a error, the traceback printer just prints the error gotten as a string which most of the times prints the error message:
https://github.com/Textualize/rich/blob/master/rich/traceback.py#L625-L627
The error gotten in this case is pygmentsโ
ClassNotFound
error with the messageno lexer for filename '...' found
.This can be fixed by adding another except statement for handling ClassNotFound and using the text lexer as a fallback
This would create some duplicate code, Iโm sure the brilliant minds at @Textualize can figure something out
Applying these changes fixes the issue
cc: @willmcgugan @darrenburns
Rich delegates a lot of this stuff to Pygments, which itself doesnโt recognise
.yaml.j2
as an extension. If your files have the.sls
extension, Pygments will use theYAML+Jinja
lexer. Hereโs the code from Pygments that does this: https://github.com/pygments/pygments/blob/64e8e05307689fe726ce9df2d5907e9c2fb67405/pygments/lexers/templates.py#L1861It may be worth opening an issue/PR with Pygments, requesting to add this extension if itโs one that is commonly used - weโd rather not start adding workarounds/logic for this sort of thing on our side.
On the Rich side, we can certainly fix the bug where no text was being output.