Skip to content

Commit 2b43423

Browse files
generatedunixname1734921407115435facebook-github-bot
authored andcommitted
Import upstream CPython branch '3.14'
Summary: Python `3.14.0rc2+` (`3.14`) was **published** on 2025-09-16 09:10:53+00:00. # Commit Info Base: (`3.14.0rc2+`) - `80e59a8d7e4c9506124e3457030efc20cb499423` (commit date: 2025-09-14 21:20:32+00:00) Imported: (`3.14.0rc2+`) - `3.14` (commit date: 2025-09-16 09:10:53+00:00) # Files added ``` Misc/NEWS.d/next/Library/2025-06-01-11-14-00.gh-issue-134953.ashdfs.rst Misc/NEWS.d/next/Library/2025-09-10-10-02-59.gh-issue-128636.ldRKGZ.rst ``` Reviewed By: itamaro Differential Revision: D82537304 fbshipit-source-id: 50f665c44cccac0803c2c08d461b3f915746580f
1 parent 8b12bc3 commit 2b43423

8 files changed

Lines changed: 43 additions & 17 deletions

File tree

Lib/_colorize.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ class Argparse(ThemeSection):
176176
class Syntax(ThemeSection):
177177
prompt: str = ANSIColors.BOLD_MAGENTA
178178
keyword: str = ANSIColors.BOLD_BLUE
179+
keyword_constant: str = ANSIColors.BOLD_BLUE
179180
builtin: str = ANSIColors.CYAN
180181
comment: str = ANSIColors.RED
181182
string: str = ANSIColors.GREEN
@@ -272,21 +273,29 @@ def decolor(text: str) -> str:
272273

273274

274275
def can_colorize(*, file: IO[str] | IO[bytes] | None = None) -> bool:
276+
277+
def _safe_getenv(k: str, fallback: str | None = None) -> str | None:
278+
"""Exception-safe environment retrieval. See gh-128636."""
279+
try:
280+
return os.environ.get(k, fallback)
281+
except Exception:
282+
return fallback
283+
275284
if file is None:
276285
file = sys.stdout
277286

278287
if not sys.flags.ignore_environment:
279-
if os.environ.get("PYTHON_COLORS") == "0":
288+
if _safe_getenv("PYTHON_COLORS") == "0":
280289
return False
281-
if os.environ.get("PYTHON_COLORS") == "1":
290+
if _safe_getenv("PYTHON_COLORS") == "1":
282291
return True
283-
if os.environ.get("NO_COLOR"):
292+
if _safe_getenv("NO_COLOR"):
284293
return False
285294
if not COLORIZE:
286295
return False
287-
if os.environ.get("FORCE_COLOR"):
296+
if _safe_getenv("FORCE_COLOR"):
288297
return True
289-
if os.environ.get("TERM") == "dumb":
298+
if _safe_getenv("TERM") == "dumb":
290299
return False
291300

292301
if not hasattr(file, "fileno"):
@@ -329,7 +338,8 @@ def get_theme(
329338
environment (including environment variable state and console configuration
330339
on Windows) can also change in the course of the application life cycle.
331340
"""
332-
if force_color or (not force_no_color and can_colorize(file=tty_file)):
341+
if force_color or (not force_no_color and
342+
can_colorize(file=tty_file)):
333343
return _theme
334344
return theme_no_color
335345

Lib/_pyrepl/unix_console.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ def __init__(
159159
self.pollob.register(self.input_fd, select.POLLIN)
160160
self.terminfo = terminfo.TermInfo(term or None)
161161
self.term = term
162+
self.is_apple_terminal = (
163+
platform.system() == "Darwin"
164+
and os.getenv("TERM_PROGRAM") == "Apple_Terminal"
165+
)
162166

163167
@overload
164168
def _my_getstr(cap: str, optional: Literal[False] = False) -> bytes: ...
@@ -339,7 +343,7 @@ def prepare(self):
339343
tcsetattr(self.input_fd, termios.TCSADRAIN, raw)
340344

341345
# In macOS terminal we need to deactivate line wrap via ANSI escape code
342-
if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
346+
if self.is_apple_terminal:
343347
os.write(self.output_fd, b"\033[?7l")
344348

345349
self.screen = []
@@ -370,7 +374,7 @@ def restore(self):
370374
self.flushoutput()
371375
tcsetattr(self.input_fd, termios.TCSADRAIN, self.__svtermstate)
372376

373-
if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
377+
if self.is_apple_terminal:
374378
os.write(self.output_fd, b"\033[?7h")
375379

376380
if hasattr(self, "old_sigwinch"):

Lib/_pyrepl/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ def gen_colors_from_token_stream(
196196
is_def_name = False
197197
span = Span.from_token(token, line_lengths)
198198
yield ColorSpan(span, "definition")
199+
elif token.string in ("True", "False", "None"):
200+
span = Span.from_token(token, line_lengths)
201+
yield ColorSpan(span, "keyword_constant")
199202
elif keyword.iskeyword(token.string):
200203
span = Span.from_token(token, line_lengths)
201204
yield ColorSpan(span, "keyword")

Lib/test/support/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2899,7 +2899,7 @@ def force_color(color: bool):
28992899
from .os_helper import EnvironmentVarGuard
29002900

29012901
with (
2902-
swap_attr(_colorize, "can_colorize", lambda file=None: color),
2902+
swap_attr(_colorize, "can_colorize", lambda *, file=None: color),
29032903
EnvironmentVarGuard() as env,
29042904
):
29052905
env.unset("FORCE_COLOR", "NO_COLOR", "PYTHON_COLORS")

Lib/test/test_pyrepl/__init__.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import os
2-
from test.support import load_package_tests
3-
import unittest
2+
import sys
3+
from test.support import import_helper, load_package_tests
44

55

6-
try:
7-
import termios
8-
except ImportError:
9-
raise unittest.SkipTest("termios required")
10-
else:
11-
del termios
6+
if sys.platform != "win32":
7+
import_helper.import_module("termios")
128

139

1410
def load_tests(*args):

Lib/test/test_pyrepl/test_unix_console.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,12 @@ def test_getheightwidth_with_invalid_environ(self, _os_write):
303303
self.assertIsInstance(console.getheightwidth(), tuple)
304304
os.environ = []
305305
self.assertIsInstance(console.getheightwidth(), tuple)
306+
307+
@unittest.skipUnless(sys.platform == "darwin", "requires macOS")
308+
def test_restore_with_invalid_environ_on_macos(self, _os_write):
309+
# gh-128636 for macOS
310+
console = UnixConsole(term="xterm")
311+
with os_helper.EnvironmentVarGuard():
312+
os.environ = []
313+
console.prepare() # needed to call restore()
314+
console.restore() # this should succeed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Expand ``_colorize`` theme with ``keyword_constant`` and implement in
2+
:term:`repl`.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash in PyREPL when os.environ is overwritten with an invalid value for
2+
mac

0 commit comments

Comments
 (0)