def can_colorize(*, file: IO[str] | IO[bytes] | None = None) -> bool:
+
+ def _safe_getenv(k: str, fallback: str | None = None) -> str | None:
+ """Exception-safe environment retrieval. See gh-128636."""
+ try:
+ return os.environ.get(k, fallback)
+ except Exception:
+ return fallback
+
if file is None:
file = sys.stdout
if not sys.flags.ignore_environment:
- if os.environ.get("PYTHON_COLORS") == "0":
+ if _safe_getenv("PYTHON_COLORS") == "0":
return False
- if os.environ.get("PYTHON_COLORS") == "1":
+ if _safe_getenv("PYTHON_COLORS") == "1":
return True
- if os.environ.get("NO_COLOR"):
+ if _safe_getenv("NO_COLOR"):
return False
if not COLORIZE:
return False
- if os.environ.get("FORCE_COLOR"):
+ if _safe_getenv("FORCE_COLOR"):
return True
- if os.environ.get("TERM") == "dumb":
+ if _safe_getenv("TERM") == "dumb":
return False
if not hasattr(file, "fileno"):
environment (including environment variable state and console configuration
on Windows) can also change in the course of the application life cycle.
"""
- if force_color or (not force_no_color and can_colorize(file=tty_file)):
+ if force_color or (not force_no_color and
+ can_colorize(file=tty_file)):
return _theme
return theme_no_color
self.pollob.register(self.input_fd, select.POLLIN)
self.terminfo = terminfo.TermInfo(term or None)
self.term = term
+ self.is_apple_terminal = (
+ platform.system() == "Darwin"
+ and os.getenv("TERM_PROGRAM") == "Apple_Terminal"
+ )
@overload
def _my_getstr(cap: str, optional: Literal[False] = False) -> bytes: ...
tcsetattr(self.input_fd, termios.TCSADRAIN, raw)
# In macOS terminal we need to deactivate line wrap via ANSI escape code
- if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
+ if self.is_apple_terminal:
os.write(self.output_fd, b"\033[?7l")
self.screen = []
self.flushoutput()
tcsetattr(self.input_fd, termios.TCSADRAIN, self.__svtermstate)
- if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
+ if self.is_apple_terminal:
os.write(self.output_fd, b"\033[?7h")
if hasattr(self, "old_sigwinch"):
from .os_helper import EnvironmentVarGuard
with (
- swap_attr(_colorize, "can_colorize", lambda file=None: color),
+ swap_attr(_colorize, "can_colorize", lambda *, file=None: color),
EnvironmentVarGuard() as env,
):
env.unset("FORCE_COLOR", "NO_COLOR", "PYTHON_COLORS")
self.assertIsInstance(console.getheightwidth(), tuple)
os.environ = []
self.assertIsInstance(console.getheightwidth(), tuple)
+
+ @unittest.skipUnless(sys.platform == "darwin", "requires macOS")
+ def test_restore_with_invalid_environ_on_macos(self, _os_write):
+ # gh-128636 for macOS
+ console = UnixConsole(term="xterm")
+ with os_helper.EnvironmentVarGuard():
+ os.environ = []
+ console.prepare() # needed to call restore()
+ console.restore() # this should succeed
--- /dev/null
+Fix crash in PyREPL when os.environ is overwritten with an invalid value for
+mac