https://github.com/python/cpython/commit/e2118b0ac21191bfeecdc97758a87d88ffdda154
commit: e2118b0ac21191bfeecdc97758a87d88ffdda154
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2026-08-25T16:48:54-07:00
summary:

gh-149985: Remove future annotations and if TYPE_CHECKING in pyrepl (#149992)

`from __future__ import annotations` is soft-deprecated now that evaluation
of annotations is always deferred. `if TYPE_CHECKING` can often be replaced
with lazy imports.

files:
M Lib/_pyrepl/_module_completer.py
M Lib/_pyrepl/_threading_handler.py
M Lib/_pyrepl/base_eventqueue.py
M Lib/_pyrepl/commands.py
M Lib/_pyrepl/completing_reader.py
M Lib/_pyrepl/console.py
M Lib/_pyrepl/content.py
M Lib/_pyrepl/fancy_termios.py
M Lib/_pyrepl/fancycompleter.py
M Lib/_pyrepl/historical_reader.py
M Lib/_pyrepl/input.py
M Lib/_pyrepl/layout.py
M Lib/_pyrepl/mypy.ini
M Lib/_pyrepl/pager.py
M Lib/_pyrepl/reader.py
M Lib/_pyrepl/readline.py
M Lib/_pyrepl/render.py
M Lib/_pyrepl/simple_interact.py
M Lib/_pyrepl/trace.py
M Lib/_pyrepl/unix_console.py
M Lib/_pyrepl/utils.py
M Lib/_pyrepl/windows_console.py

diff --git a/Lib/_pyrepl/_module_completer.py b/Lib/_pyrepl/_module_completer.py
index 17bf5cdc819542d..280a666e0c78f37 100644
--- a/Lib/_pyrepl/_module_completer.py
+++ b/Lib/_pyrepl/_module_completer.py
@@ -1,5 +1,3 @@
-from __future__ import annotations
-
 import importlib
 import os
 import pkgutil
@@ -15,12 +13,9 @@
 from tokenize import TokenInfo
 from .fancycompleter import safe_getattr
 
-TYPE_CHECKING = False
-
-if TYPE_CHECKING:
-    from types import ModuleType
-    from typing import Any, Iterable, Iterator, Mapping
-    from .types import CompletionAction
+lazy from types import ModuleType
+lazy from typing import Any, Iterable, Iterator, Mapping
+lazy from .types import CompletionAction
 
 
 HARDCODED_SUBMODULES = {
diff --git a/Lib/_pyrepl/_threading_handler.py 
b/Lib/_pyrepl/_threading_handler.py
index 82f5e8650a20728..040c49724d0b54a 100644
--- a/Lib/_pyrepl/_threading_handler.py
+++ b/Lib/_pyrepl/_threading_handler.py
@@ -1,30 +1,9 @@
-from __future__ import annotations
-
 from dataclasses import dataclass, field
 import traceback
 
 
-TYPE_CHECKING = False
-if TYPE_CHECKING:
-    from threading import Thread
-    from types import TracebackType
-    from typing import Protocol
-
-    class ExceptHookArgs(Protocol):
-        @property
-        def exc_type(self) -> type[BaseException]: ...
-        @property
-        def exc_value(self) -> BaseException | None: ...
-        @property
-        def exc_traceback(self) -> TracebackType | None: ...
-        @property
-        def thread(self) -> Thread | None: ...
-
-    class ShowExceptions(Protocol):
-        def __call__(self) -> int: ...
-        def add(self, s: str) -> None: ...
-
-    from .reader import Reader
+lazy from threading import ExceptHookArgs
+lazy from .reader import Reader
 
 
 def install_threading_hook(reader: Reader) -> None:
diff --git a/Lib/_pyrepl/base_eventqueue.py b/Lib/_pyrepl/base_eventqueue.py
index f520ffd7d8ad11d..e30ca0d26217fb8 100644
--- a/Lib/_pyrepl/base_eventqueue.py
+++ b/Lib/_pyrepl/base_eventqueue.py
@@ -79,7 +79,7 @@ def push(self, char: int | bytes) -> None:
             if isinstance(k, dict):
                 self.keymap = k
             else:
-                self.insert(Event('key', k, self.buf.take_bytes()))  # type: 
ignore[attr-defined]
+                self.insert(Event('key', k, self.buf.take_bytes()))
                 self.keymap = self.compiled_keymap
 
         elif self.buf and self.buf[0] == 27:  # escape
@@ -89,7 +89,7 @@ def push(self, char: int | bytes) -> None:
             trace('unrecognized escape sequence, propagating...')
             self.keymap = self.compiled_keymap
             self.insert(Event('key', '\033', b'\033'))
-            for _c in self.buf.take_bytes()[1:]:  # type: ignore[attr-defined]
+            for _c in self.buf.take_bytes()[1:]:
                 self.push(_c)
 
         else:
@@ -98,5 +98,5 @@ def push(self, char: int | bytes) -> None:
             except UnicodeError:
                 return
             else:
-                self.insert(Event('key', decoded, self.buf.take_bytes()))  # 
type: ignore[attr-defined]
+                self.insert(Event('key', decoded, self.buf.take_bytes()))
             self.keymap = self.compiled_keymap
diff --git a/Lib/_pyrepl/commands.py b/Lib/_pyrepl/commands.py
index e79fbfa6bb0b386..cf8b1a6c1e4ec4d 100644
--- a/Lib/_pyrepl/commands.py
+++ b/Lib/_pyrepl/commands.py
@@ -19,10 +19,8 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from __future__ import annotations
 import os
 import time
-from typing import TYPE_CHECKING
 
 # Categories of actions:
 #  killing
@@ -37,8 +35,7 @@
 from .trace import trace
 
 # types
-if TYPE_CHECKING:
-    from .historical_reader import HistoricalReader
+lazy from .historical_reader import HistoricalReader
 
 
 class Command:
diff --git a/Lib/_pyrepl/completing_reader.py b/Lib/_pyrepl/completing_reader.py
index 7eb3ebac84124b5..43f5159e20ab6a3 100644
--- a/Lib/_pyrepl/completing_reader.py
+++ b/Lib/_pyrepl/completing_reader.py
@@ -18,10 +18,7 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from __future__ import annotations
-
 from dataclasses import dataclass, field
-from typing import TYPE_CHECKING
 
 import re
 from . import commands, console, reader
@@ -30,9 +27,7 @@
 
 
 # types
-Command = commands.Command
-if TYPE_CHECKING:
-    from .types import CompletionAction, Keymap
+lazy from .types import CompletionAction, Keymap
 
 
 def prefix(wordlist: list[str], j: int = 0) -> str:
@@ -285,7 +280,7 @@ def collect_keymap(self) -> Keymap:
         return super().collect_keymap() + (
             (r'\t', 'complete'),)
 
-    def after_command(self, cmd: Command) -> None:
+    def after_command(self, cmd: commands.Command) -> None:
         super().after_command(cmd)
         if not isinstance(cmd, (complete, self_insert)):
             self.cmpltn_reset()
diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py
index 2a53d5ff581fa2c..dcf8ff9b083caa3 100644
--- a/Lib/_pyrepl/console.py
+++ b/Lib/_pyrepl/console.py
@@ -17,8 +17,6 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from __future__ import annotations
-
 import os
 import _colorize
 
@@ -29,15 +27,13 @@
 from dataclasses import dataclass
 import re
 import sys
-from typing import TYPE_CHECKING
 
 from .render import RenderedScreen
 from .trace import trace
 
-if TYPE_CHECKING:
-    from typing import Callable, IO
-
-    from .types import CursorXY
+lazy from collections.abc import Callable
+lazy from typing import IO
+lazy from .types import CursorXY
 
 
 @dataclass
diff --git a/Lib/_pyrepl/content.py b/Lib/_pyrepl/content.py
index 3cb22fee84b7406..2e759072662ba4d 100644
--- a/Lib/_pyrepl/content.py
+++ b/Lib/_pyrepl/content.py
@@ -1,5 +1,3 @@
-from __future__ import annotations
-
 from dataclasses import dataclass
 
 from .utils import ColorSpan, StyleRef, THEME, iter_display_chars, unbracket, 
wlen
diff --git a/Lib/_pyrepl/fancy_termios.py b/Lib/_pyrepl/fancy_termios.py
index 8d5bd183f213398..076a38ad06da178 100644
--- a/Lib/_pyrepl/fancy_termios.py
+++ b/Lib/_pyrepl/fancy_termios.py
@@ -19,13 +19,7 @@
 
 import termios
 
-
-TYPE_CHECKING = False
-
-if TYPE_CHECKING:
-    from typing import cast
-else:
-    cast = lambda typ, val: val
+from typing import cast
 
 
 class TermState:
diff --git a/Lib/_pyrepl/fancycompleter.py b/Lib/_pyrepl/fancycompleter.py
index ac4f0afdbc721c3..9b779d79a7ffcb4 100644
--- a/Lib/_pyrepl/fancycompleter.py
+++ b/Lib/_pyrepl/fancycompleter.py
@@ -3,21 +3,16 @@
 #
 #                        All Rights Reserved
 """Colorful tab completion for Python prompt"""
-from __future__ import annotations
-
 from _colorize import ANSIColors, get_colors, get_theme
 import rlcompleter
 import keyword
 import types
 
-TYPE_CHECKING = False
-
-if TYPE_CHECKING:
-    from typing import Any
-    from _colorize import Theme
+lazy from typing import Any
+lazy from _colorize import Theme
 
 
-def safe_getattr(obj, name):
+def safe_getattr(obj: object, name: str) -> object:
     # Mirror rlcompleter's safeguards so completion does not
     # call properties or reify lazy module attributes.
     if isinstance(getattr(type(obj), name, None), property):
@@ -35,7 +30,7 @@ def colorize_matches(names: list[str], values: list[Any], 
theme: Theme) -> list[
         for name, obj in zip(names, values)
     ]
 
-def _color_for_obj(name: str, value: Any, theme: Theme) -> str:
+def _color_for_obj(name: str, value: object, theme: Theme) -> str:
     t = type(value)
     color = _color_by_type(t, theme)
     return f"{color}{name}{ANSIColors.RESET}"
diff --git a/Lib/_pyrepl/historical_reader.py b/Lib/_pyrepl/historical_reader.py
index 77cd12e66e03c62..e0d315915987651 100644
--- a/Lib/_pyrepl/historical_reader.py
+++ b/Lib/_pyrepl/historical_reader.py
@@ -17,17 +17,13 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from __future__ import annotations
-
 from contextlib import contextmanager
 from dataclasses import dataclass, field
 
 from . import commands, input
 from .reader import Reader
 
-
-if False:
-    from .types import SimpleContextManager, KeySpec, CommandName
+lazy from .types import SimpleContextManager, KeySpec, CommandName
 
 
 isearch_keymap: tuple[tuple[KeySpec, CommandName], ...] = tuple(
diff --git a/Lib/_pyrepl/input.py b/Lib/_pyrepl/input.py
index 2d65246c700f274..56781662b4fda27 100644
--- a/Lib/_pyrepl/input.py
+++ b/Lib/_pyrepl/input.py
@@ -33,17 +33,12 @@
 # [meta-key] is identified with [esc key].  We demand that any console
 # class does quite a lot towards emulating a unix terminal.
 
-from __future__ import annotations
-
 from abc import ABC, abstractmethod
 import unicodedata
 from collections import deque
-from typing import TYPE_CHECKING
-
 
 # types
-if TYPE_CHECKING:
-    from .types import EventTuple
+lazy from .types import EventTuple
 
 
 class InputTranslator(ABC):
diff --git a/Lib/_pyrepl/layout.py b/Lib/_pyrepl/layout.py
index 6d854d1142dd9f1..cff0821cb95f72b 100644
--- a/Lib/_pyrepl/layout.py
+++ b/Lib/_pyrepl/layout.py
@@ -1,12 +1,11 @@
 """Wrap content lines to the terminal width before rendering."""
 
-from __future__ import annotations
-
 from dataclasses import dataclass
 from typing import Self
 
 from .content import ContentFragment, ContentLine
-from .types import CursorXY, ScreenInfoRow
+
+lazy from .types import CursorXY, ScreenInfoRow
 
 
 @dataclass(frozen=True, slots=True)
diff --git a/Lib/_pyrepl/mypy.ini b/Lib/_pyrepl/mypy.ini
index 9375a55b53ce8bc..2510ee8c2d3f5a1 100644
--- a/Lib/_pyrepl/mypy.ini
+++ b/Lib/_pyrepl/mypy.ini
@@ -6,7 +6,7 @@
 files = Lib/_pyrepl
 mypy_path = $MYPY_CONFIG_FILE_DIR/../../Misc/mypy
 explicit_package_bases = True
-python_version = 3.13
+python_version = 3.15
 platform = linux
 pretty = True
 
diff --git a/Lib/_pyrepl/pager.py b/Lib/_pyrepl/pager.py
index 92afaa5933a2250..d6f20fe7557e6b3 100644
--- a/Lib/_pyrepl/pager.py
+++ b/Lib/_pyrepl/pager.py
@@ -1,5 +1,3 @@
-from __future__ import annotations
-
 import io
 import os
 import re
diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py
index 832e67b534f2969..b5686409c37cdb8 100644
--- a/Lib/_pyrepl/reader.py
+++ b/Lib/_pyrepl/reader.py
@@ -19,8 +19,6 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from __future__ import annotations
-
 import sys
 import _colorize
 
diff --git a/Lib/_pyrepl/readline.py b/Lib/_pyrepl/readline.py
index e4370b0d1462eaf..1d00de3683db231 100644
--- a/Lib/_pyrepl/readline.py
+++ b/Lib/_pyrepl/readline.py
@@ -26,8 +26,6 @@
 extensions for multiline input.
 """
 
-from __future__ import annotations
-
 import warnings
 from dataclasses import dataclass, field
 
@@ -55,13 +53,10 @@
 
 # types
 Command = commands.Command
-from collections.abc import Callable, Collection
+from collections.abc import Callable, Collection, Mapping
 from .types import Callback, Completer, KeySpec, CommandName, CompletionAction
 
-TYPE_CHECKING = False
-
-if TYPE_CHECKING:
-    from typing import Any, Mapping
+lazy from typing import Any
 
 
 MoreLinesCallable = Callable[[str], bool]
diff --git a/Lib/_pyrepl/render.py b/Lib/_pyrepl/render.py
index b835778e366c539..06703885735e816 100644
--- a/Lib/_pyrepl/render.py
+++ b/Lib/_pyrepl/render.py
@@ -1,5 +1,3 @@
-from __future__ import annotations
-
 from collections.abc import Iterable, Sequence
 from dataclasses import dataclass, field
 from typing import Literal, Protocol, Self
diff --git a/Lib/_pyrepl/simple_interact.py b/Lib/_pyrepl/simple_interact.py
index da557b254e52c48..e6c355388a7c074 100644
--- a/Lib/_pyrepl/simple_interact.py
+++ b/Lib/_pyrepl/simple_interact.py
@@ -23,8 +23,6 @@
 allowing multiline input and multiline history entries.
 """
 
-from __future__ import annotations
-
 import _sitebuiltins
 import functools
 import os
diff --git a/Lib/_pyrepl/trace.py b/Lib/_pyrepl/trace.py
index 395867805196a5c..1c24ab479fcb635 100644
--- a/Lib/_pyrepl/trace.py
+++ b/Lib/_pyrepl/trace.py
@@ -1,11 +1,7 @@
-from __future__ import annotations
-
 import os
 import sys
 
-# types
-if False:
-    from typing import IO
+lazy from typing import IO
 
 
 trace_file: IO[str] | None = None
diff --git a/Lib/_pyrepl/unix_console.py b/Lib/_pyrepl/unix_console.py
index 8edd1c36a7232d7..0749a56d86fa4a6 100644
--- a/Lib/_pyrepl/unix_console.py
+++ b/Lib/_pyrepl/unix_console.py
@@ -19,8 +19,6 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from __future__ import annotations
-
 import errno
 import os
 import re
@@ -34,7 +32,7 @@
 from collections.abc import Callable
 from dataclasses import dataclass
 from fcntl import ioctl
-from typing import TYPE_CHECKING, overload
+from typing import AbstractSet, IO, Literal, overload
 
 from _colorize import ANSIColors
 
@@ -61,9 +59,6 @@
     posix = None
 
 # types
-if TYPE_CHECKING:
-    from typing import AbstractSet, IO, Literal
-
 type _MoveFunc = Callable[[int, int], None]
 type _PendingWrite = tuple[str | bytes, bool]
 
diff --git a/Lib/_pyrepl/utils.py b/Lib/_pyrepl/utils.py
index 8d68f4f66f2980e..e77001f6a1d10bb 100644
--- a/Lib/_pyrepl/utils.py
+++ b/Lib/_pyrepl/utils.py
@@ -1,4 +1,3 @@
-from __future__ import annotations
 import builtins
 import functools
 import keyword
@@ -9,10 +8,12 @@
 import _colorize
 
 from collections import deque
+from collections.abc import Iterable, Iterator
 from dataclasses import dataclass
 from io import StringIO
+from re import Match
 from tokenize import TokenInfo as TI
-from typing import Iterable, Iterator, Match, NamedTuple, Self
+from typing import NamedTuple, Self
 
 from .types import CharBuffer, CharWidths
 from .trace import trace
diff --git a/Lib/_pyrepl/windows_console.py b/Lib/_pyrepl/windows_console.py
index 3768a22ad16f7bb..65eacf90fde685d 100644
--- a/Lib/_pyrepl/windows_console.py
+++ b/Lib/_pyrepl/windows_console.py
@@ -17,8 +17,6 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from __future__ import annotations
-
 import io
 import os
 import sys
@@ -38,7 +36,6 @@
     SHORT,
 )
 from ctypes import Structure, POINTER, Union
-from typing import TYPE_CHECKING
 
 from _colorize import ANSIColors
 
@@ -76,8 +73,7 @@ def __init__(self, err: int | None, descr: str | None = None) 
-> None:
 except ImportError:
     nt = None
 
-if TYPE_CHECKING:
-    from typing import IO
+lazy from typing import IO
 
 # Virtual-Key Codes: 
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
 VK_MAP: dict[int, str] = {

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to