From e5559c2b67ff7a22906c03ac76d44345335da0c4 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 2 May 2026 22:14:02 +0300 Subject: [PATCH 1/7] Lazy import _colorize in traceback with shutdown fallback --- Lib/traceback.py | 49 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/Lib/traceback.py b/Lib/traceback.py index 343d0e5f108c35..7a9c3ede59cb81 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -16,10 +16,39 @@ import io import importlib.util import pathlib -import _colorize +lazy import _colorize from contextlib import suppress + +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 + try: from _missing_stdlib_info import _MISSING_STDLIB_MODULE_MESSAGES except ImportError: @@ -151,7 +180,7 @@ def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ 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) @@ -199,9 +228,9 @@ def _format_final_exc_line(etype, value, *, insert_final_newline=True, 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: @@ -555,9 +584,9 @@ def format_frame_summary(self, frame_summary, **kwargs): if frame_summary.filename.startswith("'): filename = "" 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, @@ -1336,9 +1365,9 @@ def format_exception_only(self, *, show_group=False, _depth=0, **kwargs): """ 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: @@ -1486,9 +1515,9 @@ def _format_syntax_error(self, stype, **kwargs): # 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( From 5d16d313b98bb7c13044639da8443ec94fe75e8b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 May 2026 13:38:45 +0300 Subject: [PATCH 2/7] Lazy import _colorize --- Lib/_pyrepl/console.py | 2 +- Lib/_pyrepl/fancycompleter.py | 2 +- Lib/_pyrepl/reader.py | 2 +- Lib/_pyrepl/utils.py | 2 +- Lib/difflib.py | 2 +- Lib/doctest.py | 4 ++-- Lib/json/tool.py | 2 +- Lib/pdb.py | 2 +- Lib/profiling/sampling/live_collector/collector.py | 2 +- Lib/profiling/sampling/pstats_collector.py | 2 +- Lib/profiling/sampling/sample.py | 2 +- Lib/sqlite3/__main__.py | 2 +- Lib/unittest/runner.py | 3 +-- 13 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py index 2a53d5ff581fa2..e71f25072a0d3b 100644 --- a/Lib/_pyrepl/console.py +++ b/Lib/_pyrepl/console.py @@ -20,7 +20,7 @@ from __future__ import annotations import os -import _colorize +lazy import _colorize from abc import ABC, abstractmethod import ast diff --git a/Lib/_pyrepl/fancycompleter.py b/Lib/_pyrepl/fancycompleter.py index 7a639afd74ef3c..1dd6a1f9aad990 100644 --- a/Lib/_pyrepl/fancycompleter.py +++ b/Lib/_pyrepl/fancycompleter.py @@ -3,7 +3,7 @@ # # All Rights Reserved """Colorful tab completion for Python prompt""" -from _colorize import ANSIColors, get_colors, get_theme +lazy from _colorize import ANSIColors, get_colors, get_theme import rlcompleter import keyword import types diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py index 7e4dd801c84d5c..2e25a1f9518d5b 100644 --- a/Lib/_pyrepl/reader.py +++ b/Lib/_pyrepl/reader.py @@ -22,7 +22,7 @@ from __future__ import annotations import sys -import _colorize +lazy import _colorize from contextlib import contextmanager from dataclasses import dataclass, field, fields, replace diff --git a/Lib/_pyrepl/utils.py b/Lib/_pyrepl/utils.py index b50426c31ead53..3e69f5d0e4ea18 100644 --- a/Lib/_pyrepl/utils.py +++ b/Lib/_pyrepl/utils.py @@ -6,7 +6,7 @@ import token as T import tokenize import unicodedata -import _colorize +lazy import _colorize from collections import deque from dataclasses import dataclass diff --git a/Lib/difflib.py b/Lib/difflib.py index 8f3cdaed9564d8..ae8b284b4d3647 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -30,10 +30,10 @@ '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') diff --git a/Lib/doctest.py b/Lib/doctest.py index 0fcfa1e3e97144..320a654f9270b2 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -106,8 +106,8 @@ def _test(): import unittest from io import StringIO, TextIOWrapper, BytesIO from collections import namedtuple -import _colorize # Used in doctests -from _colorize import ANSIColors, can_colorize +lazy import _colorize # Used in doctests +lazy from _colorize import ANSIColors, can_colorize class TestResults(namedtuple('TestResults', 'failed attempted')): diff --git a/Lib/json/tool.py b/Lib/json/tool.py index e56a601c581ae5..f7f702cab6fec1 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -7,7 +7,7 @@ import json import re import sys -from _colorize import get_theme, can_colorize +lazy from _colorize import get_theme, can_colorize # The string we are colorizing is valid JSON, diff --git a/Lib/pdb.py b/Lib/pdb.py index 4dd974b375c259..c5244e25562f6d 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -96,7 +96,7 @@ import linecache import selectors import threading -import _colorize +lazy import _colorize from contextlib import ExitStack, closing, contextmanager from types import CodeType diff --git a/Lib/profiling/sampling/live_collector/collector.py b/Lib/profiling/sampling/live_collector/collector.py index c03df4075277cd..a53cfc6b719a10 100644 --- a/Lib/profiling/sampling/live_collector/collector.py +++ b/Lib/profiling/sampling/live_collector/collector.py @@ -9,7 +9,7 @@ import sys import sysconfig import time -import _colorize +lazy import _colorize from ..collector import Collector, extract_lineno from ..constants import ( diff --git a/Lib/profiling/sampling/pstats_collector.py b/Lib/profiling/sampling/pstats_collector.py index 6be1d698ffaa9a..1f8ebe6ccbe40b 100644 --- a/Lib/profiling/sampling/pstats_collector.py +++ b/Lib/profiling/sampling/pstats_collector.py @@ -2,7 +2,7 @@ import marshal import pstats -from _colorize import ANSIColors +lazy from _colorize import ANSIColors from .collector import Collector, extract_lineno from .constants import MICROSECONDS_PER_SECOND, PROFILING_MODE_CPU diff --git a/Lib/profiling/sampling/sample.py b/Lib/profiling/sampling/sample.py index 9195f5ee6dd390..3b9146ac6f8661 100644 --- a/Lib/profiling/sampling/sample.py +++ b/Lib/profiling/sampling/sample.py @@ -6,7 +6,7 @@ import sysconfig import time from collections import deque -from _colorize import ANSIColors +lazy from _colorize import ANSIColors from .pstats_collector import PstatsCollector from .stack_collector import CollapsedStackCollector, FlamegraphCollector diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py index 8805442b69e080..9ecb590add6032 100644 --- a/Lib/sqlite3/__main__.py +++ b/Lib/sqlite3/__main__.py @@ -10,7 +10,7 @@ from argparse import ArgumentParser from code import InteractiveConsole from textwrap import dedent -from _colorize import get_theme, theme_no_color +lazy from _colorize import get_theme, theme_no_color from ._completer import completer diff --git a/Lib/unittest/runner.py b/Lib/unittest/runner.py index 5f22d91aebd05f..893fcba968c3ef 100644 --- a/Lib/unittest/runner.py +++ b/Lib/unittest/runner.py @@ -4,11 +4,10 @@ import time import warnings -from _colorize import get_theme - from . import result from .case import _SubTest from .signals import registerResult +lazy from _colorize import get_theme __unittest = True From c31b1a54f46d3bd622ad7dd33c273604dcad661e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 May 2026 16:59:49 +0300 Subject: [PATCH 3/7] Add tests to ensure lazy imports are lazy and fix sqlite3's main --- Lib/sqlite3/__main__.py | 4 +++- Lib/test/test_difflib.py | 8 ++++++++ Lib/test/test_json/test_tool.py | 7 +++++++ Lib/test/test_pdb.py | 8 +++++++- Lib/test/test_sqlite3/test_cli.py | 8 +++++++- Lib/test/test_traceback.py | 8 +++++++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py index 9ecb590add6032..074347ce3ce8a0 100644 --- a/Lib/sqlite3/__main__.py +++ b/Lib/sqlite3/__main__.py @@ -15,7 +15,7 @@ from ._completer import completer -def execute(c, sql, suppress_errors=True, theme=theme_no_color): +def execute(c, sql, suppress_errors=True, theme=None): """Helper that wraps execution of SQL code. This is used both by the REPL and by direct execution from the CLI. @@ -23,6 +23,8 @@ def execute(c, sql, suppress_errors=True, theme=theme_no_color): 'c' may be a cursor or a connection. 'sql' is the SQL string to execute. """ + if theme is None: + theme = theme_no_color try: for row in c.execute(sql): diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py index 771fd46e042a41..46c9b2c1d8c9fc 100644 --- a/Lib/test/test_difflib.py +++ b/Lib/test/test_difflib.py @@ -1,5 +1,7 @@ import difflib +from test import support from test.support import findfile, force_colorized +from test.support.import_helper import ensure_lazy_imports import unittest import doctest import sys @@ -644,6 +646,12 @@ def setUpModule(): difflib.HtmlDiff._default_prefix = 0 +class LazyImportTest(unittest.TestCase): + @support.cpython_only + def test_lazy_import(self): + ensure_lazy_imports("difflib", {"_colorize"}) + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(difflib)) return tests diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py index 0a96b318b15b1c..487a750eb8b544 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -8,6 +8,7 @@ from test import support from test.support import force_colorized, force_not_colorized, os_helper +from test.support.import_helper import ensure_lazy_imports from test.support.script_helper import assert_python_ok from _colorize import get_theme @@ -334,5 +335,11 @@ class TestTool(TestMain): module = 'json.tool' +class LazyImportTest(unittest.TestCase): + @support.cpython_only + def test_lazy_import(self): + ensure_lazy_imports("json.tool", {"_colorize"}) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index db90019975521e..e4904aca2ddd11 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -22,7 +22,7 @@ from io import StringIO from test import support from test.support import has_socket_support, os_helper -from test.support.import_helper import import_module +from test.support.import_helper import ensure_lazy_imports, import_module from test.support.pty_helper import run_pty, FakeInput from test.support.script_helper import kill_python from unittest.mock import patch @@ -5306,5 +5306,11 @@ def tearDown(test): return tests +class LazyImportTest(unittest.TestCase): + @support.cpython_only + def test_lazy_import(self): + ensure_lazy_imports("pdb", {"_colorize"}) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_sqlite3/test_cli.py b/Lib/test/test_sqlite3/test_cli.py index 1fc0236780fa8b..b78e76d9a75127 100644 --- a/Lib/test/test_sqlite3/test_cli.py +++ b/Lib/test/test_sqlite3/test_cli.py @@ -7,13 +7,14 @@ import os from sqlite3.__main__ import main as cli -from test.support.import_helper import import_module +from test.support.import_helper import ensure_lazy_imports, import_module from test.support.os_helper import TESTFN, unlink from test.support.pty_helper import run_pty from test.support import ( captured_stdout, captured_stderr, captured_stdin, + cpython_only, force_not_colorized_test_class, requires_subprocess, verbose, @@ -437,6 +438,11 @@ def test_complete_no_input(self): raise +class LazyImportTest(unittest.TestCase): + @cpython_only + def test_lazy_import(self): + ensure_lazy_imports("sqlite3.__main__", {"_colorize"}) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 909808825f055e..60584bf3969e93 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -23,7 +23,7 @@ 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 @@ -5543,5 +5543,11 @@ def test_suggestion_still_works_for_non_lazy_attributes(self): 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() From 6a88c2deeb30e58d4b17f12e2593b6567521d739 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 May 2026 17:32:35 +0300 Subject: [PATCH 4/7] Add news --- .../next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst diff --git a/Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst b/Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst new file mode 100644 index 00000000000000..c8667472492575 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst @@ -0,0 +1 @@ +Lazily import :mod:`_colorize`. Patch by Hugo van Kemenade. From 1d36600f6c19278c6cf119581e280bb4129fecd0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 May 2026 17:54:03 +0300 Subject: [PATCH 5/7] Use mypy on 3.15 to support lazy keyword --- .github/workflows/mypy.yml | 3 ++- .../Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 7f6571ef954576..490c32ecfc9a62 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -71,7 +71,8 @@ jobs: persist-credentials: false - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: - python-version: "3.13" + python-version: "3.15" + allow-prereleases: true cache: pip cache-dependency-path: Tools/requirements-dev.txt - run: pip install -r Tools/requirements-dev.txt diff --git a/Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst b/Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst index c8667472492575..aad4b716e05372 100644 --- a/Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst +++ b/Misc/NEWS.d/next/Library/2026-05-03-17-32-24.gh-issue-144384.q-8jSr.rst @@ -1 +1 @@ -Lazily import :mod:`_colorize`. Patch by Hugo van Kemenade. +Lazily import :mod:`!_colorize`. Patch by Hugo van Kemenade. From 9fc265e000fb6818317efb4a1539468b93b427eb Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 May 2026 18:19:09 +0300 Subject: [PATCH 6/7] List lazy later --- Lib/_pyrepl/console.py | 2 +- Lib/_pyrepl/fancycompleter.py | 3 ++- Lib/_pyrepl/reader.py | 2 +- Lib/_pyrepl/utils.py | 2 +- Lib/pdb.py | 2 +- Lib/profiling/sampling/pstats_collector.py | 2 +- Lib/traceback.py | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py index e71f25072a0d3b..74d364725fb129 100644 --- a/Lib/_pyrepl/console.py +++ b/Lib/_pyrepl/console.py @@ -20,7 +20,6 @@ from __future__ import annotations import os -lazy import _colorize from abc import ABC, abstractmethod import ast @@ -30,6 +29,7 @@ import re import sys from typing import TYPE_CHECKING +lazy import _colorize from .render import RenderedScreen from .trace import trace diff --git a/Lib/_pyrepl/fancycompleter.py b/Lib/_pyrepl/fancycompleter.py index 1dd6a1f9aad990..969b257e88aa6a 100644 --- a/Lib/_pyrepl/fancycompleter.py +++ b/Lib/_pyrepl/fancycompleter.py @@ -3,10 +3,11 @@ # # All Rights Reserved """Colorful tab completion for Python prompt""" -lazy from _colorize import ANSIColors, get_colors, get_theme import rlcompleter import keyword import types +lazy from _colorize import ANSIColors, get_colors, get_theme + class Completer(rlcompleter.Completer): """ diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py index 2e25a1f9518d5b..405b95682ec5bc 100644 --- a/Lib/_pyrepl/reader.py +++ b/Lib/_pyrepl/reader.py @@ -22,11 +22,11 @@ from __future__ import annotations import sys -lazy import _colorize from contextlib import contextmanager from dataclasses import dataclass, field, fields, replace from typing import Self +lazy import _colorize from . import commands, console, input from .content import ( diff --git a/Lib/_pyrepl/utils.py b/Lib/_pyrepl/utils.py index 3e69f5d0e4ea18..66e6c5c7c8e3ca 100644 --- a/Lib/_pyrepl/utils.py +++ b/Lib/_pyrepl/utils.py @@ -6,13 +6,13 @@ import token as T import tokenize import unicodedata -lazy import _colorize from collections import deque from dataclasses import dataclass from io import StringIO from tokenize import TokenInfo as TI from typing import Iterable, Iterator, Match, NamedTuple, Self +lazy import _colorize from .types import CharBuffer, CharWidths from .trace import trace diff --git a/Lib/pdb.py b/Lib/pdb.py index c5244e25562f6d..00df2229ebe8d6 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -96,11 +96,11 @@ import linecache import selectors import threading -lazy import _colorize from contextlib import ExitStack, closing, contextmanager from types import CodeType from warnings import deprecated +lazy import _colorize try: import _pyrepl.utils diff --git a/Lib/profiling/sampling/pstats_collector.py b/Lib/profiling/sampling/pstats_collector.py index 1f8ebe6ccbe40b..50500296c15acc 100644 --- a/Lib/profiling/sampling/pstats_collector.py +++ b/Lib/profiling/sampling/pstats_collector.py @@ -1,8 +1,8 @@ import collections import marshal import pstats - lazy from _colorize import ANSIColors + from .collector import Collector, extract_lineno from .constants import MICROSECONDS_PER_SECOND, PROFILING_MODE_CPU diff --git a/Lib/traceback.py b/Lib/traceback.py index 7a9c3ede59cb81..327d3a3adba9a9 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -16,9 +16,9 @@ import io import importlib.util import pathlib -lazy import _colorize from contextlib import suppress +lazy import _colorize class _ShutdownTheme: From 59907556db7aae6b93ccb3b06e180edd38dfb3d7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 May 2026 18:48:30 +0300 Subject: [PATCH 7/7] Move shutdown theme below __all__ --- Lib/traceback.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Lib/traceback.py b/Lib/traceback.py index 327d3a3adba9a9..84547bab08dc87 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -20,6 +20,18 @@ from contextlib import suppress lazy import _colorize +try: + from _missing_stdlib_info import _MISSING_STDLIB_MODULE_MESSAGES +except ImportError: + _MISSING_STDLIB_MODULE_MESSAGES = {} + +__all__ = ['extract_stack', 'extract_tb', 'format_exception', + 'format_exception_only', 'format_list', 'format_stack', + 'format_tb', 'print_exc', 'format_exc', 'print_exception', + 'print_last', 'print_stack', 'print_tb', 'clear_frames', + 'FrameSummary', 'StackSummary', 'TracebackException', + 'walk_stack', 'walk_tb', 'print_list'] + class _ShutdownTheme: """Empty stand-in if `_colorize` cannot be imported during late shutdown.""" @@ -49,17 +61,6 @@ def _safe_can_colorize(*, file=None): except ImportError: return False -try: - from _missing_stdlib_info import _MISSING_STDLIB_MODULE_MESSAGES -except ImportError: - _MISSING_STDLIB_MODULE_MESSAGES = {} - -__all__ = ['extract_stack', 'extract_tb', 'format_exception', - 'format_exception_only', 'format_list', 'format_stack', - 'format_tb', 'print_exc', 'format_exc', 'print_exception', - 'print_last', 'print_stack', 'print_tb', 'clear_frames', - 'FrameSummary', 'StackSummary', 'TracebackException', - 'walk_stack', 'walk_tb', 'print_list'] # # Formatting and printing lists of traceback lines.