Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions ipython_pygments_lexers.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,11 @@ class IPythonPartialTracebackLexer(RegexLexer):
),
# (Exception Identifier)(Message)
(r"(?u)(^[^\d\W]\w*)(:.*?\n)", bygroups(Name.Exception, Text)),
# Tag everything else as Other, will be handled later.
(r".*\n", Other),
# Tag everything else as text. Using Other here would make the
# delegating IPythonTracebackLexer hand these lines to the Python
# lexer, which emits Error tokens for text that is not valid Python
# (e.g. exception messages containing backticks).
(r".*\n", Text),
],
}

Expand Down
25 changes: 25 additions & 0 deletions test_ipython_pygments_lexers.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,28 @@ def test_cell_magics():
(Token.Text, "\n$foo\n"),
]
assert tokens_2 == list(lexer.get_tokens(fragment_2))


def test_traceback_multiline_message_backticks():
"""A multiline exception message must not produce Error tokens.

Continuation lines of an exception message are plain text, not Python.
If they were emitted as Other, the delegating IPythonTracebackLexer would
re-lex them as Python, and backticks in the message would become Error
tokens (see ipython/ipython#14142).
"""
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.filters import RaiseOnErrorTokenFilter
from pygments.token import Error

from ipython_pygments_lexers import IPythonTracebackLexer

code = "TypeError: `foo` is deprecated.\nUse `bar` instead.\n"
lexer = IPythonTracebackLexer()

assert Error not in {t for t, _ in lexer.get_tokens(code)}

# RaiseOnErrorTokenFilter would raise if any Error token is produced.
filtered = IPythonTracebackLexer(filters=[RaiseOnErrorTokenFilter()])
highlight(code, filtered, HtmlFormatter())