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