'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff',
'unified_diff', 'diff_bytes', 'HtmlDiff', 'Match']
-from _colorize import can_colorize, get_theme
from heapq import nlargest as _nlargest
from collections import namedtuple as _namedtuple
from types import GenericAlias
+lazy from _colorize import can_colorize, get_theme
Match = _namedtuple('Match', 'a b size')
requires_subprocess, os_helper)
from test.support.os_helper import TESTFN, temp_dir, unlink
from test.support.script_helper import assert_python_ok, assert_python_failure, make_script
-from test.support.import_helper import forget
+from test.support.import_helper import ensure_lazy_imports, forget
from test.support import force_not_colorized, force_not_colorized_test_class
import json
self.assertNotIn(b"BAR_MODULE_LOADED", stdout)
+class LazyImportTest(unittest.TestCase):
+ @support.cpython_only
+ def test_lazy_import(self):
+ ensure_lazy_imports("traceback", {"_colorize"})
+
+
if __name__ == "__main__":
unittest.main()
import io
import importlib.util
import pathlib
-import _colorize
from contextlib import suppress
+lazy import _colorize
try:
from _missing_stdlib_info import _MISSING_STDLIB_MODULE_MESSAGES
'FrameSummary', 'StackSummary', 'TracebackException',
'walk_stack', 'walk_tb', 'print_list']
+
+class _ShutdownTheme:
+ """Empty stand-in if `_colorize` cannot be imported during late shutdown."""
+ def __getattr__(self, _): return self
+ def __getitem__(self, _): return ""
+ def __format__(self, _): return ""
+ def __str__(self): return ""
+ def __add__(self, other): return other
+ __radd__ = __add__
+
+
+_shutdown_theme = _ShutdownTheme()
+
+
+def _safe_get_theme(*, force_color=False, force_no_color=False):
+ try:
+ return _colorize.get_theme(
+ force_color=force_color, force_no_color=force_no_color
+ )
+ except ImportError:
+ return _shutdown_theme
+
+
+def _safe_can_colorize(*, file=None):
+ try:
+ return _colorize.can_colorize(file=file)
+ except ImportError:
+ return False
+
+
#
# Formatting and printing lists of traceback lines.
#
def _print_exception_bltin(exc, file=None, /):
if file is None:
file = sys.stderr if sys.stderr is not None else sys.__stderr__
- colorize = _colorize.can_colorize(file=file)
+ colorize = _safe_can_colorize(file=file)
return print_exception(exc, limit=BUILTIN_EXCEPTION_LIMIT, file=file, colorize=colorize)
valuestr = _safe_string(value, 'exception')
end_char = "\n" if insert_final_newline else ""
if colorize:
- theme = _colorize.get_theme(force_color=True).traceback
+ theme = _safe_get_theme(force_color=True).traceback
else:
- theme = _colorize.get_theme(force_no_color=True).traceback
+ theme = _safe_get_theme(force_no_color=True).traceback
if value is None or not valuestr:
line = f"{theme.type}{etype}{theme.reset}{end_char}"
else:
if frame_summary.filename.startswith("<stdin-") and frame_summary.filename.endswith('>'):
filename = "<stdin>"
if colorize:
- theme = _colorize.get_theme(force_color=True).traceback
+ theme = _safe_get_theme(force_color=True).traceback
else:
- theme = _colorize.get_theme(force_no_color=True).traceback
+ theme = _safe_get_theme(force_no_color=True).traceback
row.append(
' File {}"{}"{}, line {}{}{}, in {}{}{}\n'.format(
theme.filename,
"""
colorize = kwargs.get("colorize", False)
if colorize:
- theme = _colorize.get_theme(force_color=True).traceback
+ theme = _safe_get_theme(force_color=True).traceback
else:
- theme = _colorize.get_theme(force_no_color=True).traceback
+ theme = _safe_get_theme(force_no_color=True).traceback
indent = 3 * _depth * ' '
if not self._have_exc_type:
# Show exactly where the problem was found.
colorize = kwargs.get("colorize", False)
if colorize:
- theme = _colorize.get_theme(force_color=True).traceback
+ theme = _safe_get_theme(force_color=True).traceback
else:
- theme = _colorize.get_theme(force_no_color=True).traceback
+ theme = _safe_get_theme(force_no_color=True).traceback
filename_suffix = ''
if self.lineno is not None:
yield ' File {}"{}"{}, line {}{}{}\n'.format(