Commit 6046196a authored by Lucas Felix's avatar Lucas Felix
Browse files

Use pygments for last_error color to adapt to theme

parent 9c221f8f
......@@ -9,6 +9,8 @@
import asyncio
from typing import Optional
from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import FormattedText
from prompt_toolkit.styles.pygments import style_from_pygments_cls
from pygments.styles import get_style_by_name
from pygments.util import ClassNotFound
......@@ -26,7 +28,6 @@ import logging
import platform
import importlib
from collections import deque
from colorama import Fore, Style
from datetime import datetime
......@@ -110,45 +111,61 @@ class PrettyTraceback:
return True
return False
def format_color(self, raw=True):
fmt_error = f"{Fore.YELLOW}--- {self._timestamp.strftime('%d/%m/%Y %H:%M:%S')} ---{Style.RESET_ALL}\n"
def print_formatted(self, disable_blacklist=False):
header = [
(
"class:pygments.generic.heading",
self._timestamp.strftime("--- %d/%m/%Y %H:%M:%S ---\n"),
)
]
# Stack trace formatting
fmt_stack = ""
stack = []
for f in self._stack_summary:
if not raw and self._is_blacklisted(f.filename):
if not disable_blacklist and self._is_blacklisted(f.filename):
continue
# skip bottom calls from ptpython by resetting fmt_stack
# skip bottom calls from ptpython
if f.filename == "<stdin>":
fmt_stack = ""
stack.clear()
fmt_stack += f"{Fore.CYAN}{f.filename}{Fore.GREEN}:{f.lineno} "
fmt_stack += f"{Fore.BLUE}{f.name}{Style.RESET_ALL}\n"
stack += [
("class:pygments.literal", f.filename),
("class:pygments.punctuation", ":"),
("class:pygments.literal.number", str(f.lineno) + " "),
("class:pygments.name.function", f.name + "\n"),
]
if f._line:
fmt_stack += f"{Fore.RED} > {Style.RESET_ALL}{f._line}\n\n"
stack += [
("class:pygments.generic.error", " > "),
("class:pygments.text", f._line + "\n\n"),
]
# locals are not printed when f._line is empty, this happens with traces coming from
# the interpreter or compiled files and locals dict is full of obscure symbols.
if f.locals is not None:
for key, val in f.locals.items():
fmt_stack += f"{Fore.MAGENTA}{key}: "
fmt_stack += (
f"{Style.BRIGHT}{Fore.WHITE}{val}{Style.RESET_ALL}\n"
)
fmt_stack += "\n"
stack += [
("class:pygments.name.attribute", key),
("class:pygments.punctuation", ": "),
("class:pygments.text", val + "\n"),
]
stack += [("class:pygments.text", "\n")]
else:
fmt_stack += "\n"
fmt_error += fmt_stack
stack += [("class:pygments.text", "\n")]
# Exception formatting
fmt_error += f"{Style.BRIGHT}{Fore.RED}{self._exc_type.__name__}:\n"
fmt_error += Style.BRIGHT + Fore.YELLOW
footer = []
footer.append(
("class:pygments.generic.strong", self._exc_type.__name__ + ":\n")
)
for arg in self._exc_value.args:
fmt_error += f"{arg}\n"
fmt_error += Style.RESET_ALL
footer.append(("class:pygments.name.exception", str(arg) + "\n"))
return fmt_error
fmt_text = FormattedText(header + stack + footer)
print_formatted_text(
fmt_text, style=BlissRepl()._current_style, file=sys.stderr
)
class ErrorReport(ErrorReportInterface):
......@@ -194,7 +211,6 @@ def install_excepthook():
if exc_value is None:
# filter exceptions from aiogevent(?) with no traceback, no value
return
err_file = sys.stderr
error_report.history.append(PrettyTraceback(exc_type, exc_value, tb))
......@@ -204,14 +220,14 @@ def install_excepthook():
# Adapt the error message depending on the expert_mode
if error_report._expert_mode:
print(error_report.history[-1].format_color(True), file=err_file)
error_report.history[-1].print_formatted(disable_blacklist=True)
elif current_session:
if current_session.is_loading_config:
print(f"{exc_type.__name__}: {exc_value}", file=err_file)
print(f"{exc_type.__name__}: {exc_value}", file=sys.stderr)
else:
print(
f"!!! === {exc_type.__name__}: {exc_value} === !!! ( for more details type cmd 'last_error()' )",
file=err_file,
file=sys.stderr,
)
if _with_elogbook:
......@@ -752,7 +768,9 @@ def cli(
hist = user_ns["ERROR_REPORT"].history
try:
idx = -1 if index is None else index
print(hist[idx].format_color(user_ns["ERROR_REPORT"].expert_mode))
hist[idx].print_formatted(
disable_blacklist=user_ns["ERROR_REPORT"].expert_mode
)
except IndexError:
if index is None:
print("None")
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment