https://github.com/python/cpython/commit/0ac40acec045c4ce780cf7d887fcbe4c661e82b7
commit: 0ac40acec045c4ce780cf7d887fcbe4c661e82b7
branch: main
author: Andrey Efremov <[email protected]>
committer: hugovk <[email protected]>
date: 2024-12-14T17:25:49+02:00
summary:

gh-127353: Allow to force color output on Windows V2 (#127926)

files:
A Misc/NEWS.d/next/Windows/2024-11-28-15-55-48.gh-issue-127353.i-XOXg.rst
M Lib/_colorize.py
M Lib/test/test__colorize.py

diff --git a/Lib/_colorize.py b/Lib/_colorize.py
index 845fb57a90abb8..709081e25ec59b 100644
--- a/Lib/_colorize.py
+++ b/Lib/_colorize.py
@@ -32,14 +32,6 @@ def get_colors(colorize: bool = False) -> ANSIColors:
 
 
 def can_colorize() -> bool:
-    if sys.platform == "win32":
-        try:
-            import nt
-
-            if not nt._supports_virtual_terminal():
-                return False
-        except (ImportError, AttributeError):
-            return False
     if not sys.flags.ignore_environment:
         if os.environ.get("PYTHON_COLORS") == "0":
             return False
@@ -58,6 +50,15 @@ def can_colorize() -> bool:
     if not hasattr(sys.stderr, "fileno"):
         return False
 
+    if sys.platform == "win32":
+        try:
+            import nt
+
+            if not nt._supports_virtual_terminal():
+                return False
+        except (ImportError, AttributeError):
+            return False
+
     try:
         return os.isatty(sys.stderr.fileno())
     except io.UnsupportedOperation:
diff --git a/Lib/test/test__colorize.py b/Lib/test/test__colorize.py
index d55b97ade68cef..1871775fa205a2 100644
--- a/Lib/test/test__colorize.py
+++ b/Lib/test/test__colorize.py
@@ -19,40 +19,50 @@ def tearDownModule():
 class TestColorizeFunction(unittest.TestCase):
     @force_not_colorized
     def test_colorized_detection_checks_for_environment_variables(self):
-        if sys.platform == "win32":
-            virtual_patching = 
unittest.mock.patch("nt._supports_virtual_terminal",
-                                                   return_value=True)
-        else:
-            virtual_patching = contextlib.nullcontext()
-        with virtual_patching:
-
-            flags = unittest.mock.MagicMock(ignore_environment=False)
-            with (unittest.mock.patch("os.isatty") as isatty_mock,
-                  unittest.mock.patch("sys.flags", flags),
-                  unittest.mock.patch("_colorize.can_colorize", 
ORIGINAL_CAN_COLORIZE)):
-                isatty_mock.return_value = True
-                with unittest.mock.patch("os.environ", {'TERM': 'dumb'}):
-                    self.assertEqual(_colorize.can_colorize(), False)
-                with unittest.mock.patch("os.environ", {'PYTHON_COLORS': '1'}):
-                    self.assertEqual(_colorize.can_colorize(), True)
-                with unittest.mock.patch("os.environ", {'PYTHON_COLORS': '0'}):
-                    self.assertEqual(_colorize.can_colorize(), False)
-                with unittest.mock.patch("os.environ", {'NO_COLOR': '1'}):
+        flags = unittest.mock.MagicMock(ignore_environment=False)
+        with (unittest.mock.patch("os.isatty") as isatty_mock,
+              unittest.mock.patch("sys.stderr") as stderr_mock,
+              unittest.mock.patch("sys.flags", flags),
+              unittest.mock.patch("_colorize.can_colorize", 
ORIGINAL_CAN_COLORIZE),
+              (unittest.mock.patch("nt._supports_virtual_terminal", 
return_value=False)
+               if sys.platform == "win32" else
+               contextlib.nullcontext()) as vt_mock):
+
+            isatty_mock.return_value = True
+            stderr_mock.fileno.return_value = 2
+            stderr_mock.isatty.return_value = True
+            with unittest.mock.patch("os.environ", {'TERM': 'dumb'}):
+                self.assertEqual(_colorize.can_colorize(), False)
+            with unittest.mock.patch("os.environ", {'PYTHON_COLORS': '1'}):
+                self.assertEqual(_colorize.can_colorize(), True)
+            with unittest.mock.patch("os.environ", {'PYTHON_COLORS': '0'}):
+                self.assertEqual(_colorize.can_colorize(), False)
+            with unittest.mock.patch("os.environ", {'NO_COLOR': '1'}):
+                self.assertEqual(_colorize.can_colorize(), False)
+            with unittest.mock.patch("os.environ",
+                                     {'NO_COLOR': '1', "PYTHON_COLORS": '1'}):
+                self.assertEqual(_colorize.can_colorize(), True)
+            with unittest.mock.patch("os.environ", {'FORCE_COLOR': '1'}):
+                self.assertEqual(_colorize.can_colorize(), True)
+            with unittest.mock.patch("os.environ",
+                                     {'FORCE_COLOR': '1', 'NO_COLOR': '1'}):
+                self.assertEqual(_colorize.can_colorize(), False)
+            with unittest.mock.patch("os.environ",
+                                     {'FORCE_COLOR': '1', "PYTHON_COLORS": 
'0'}):
+                self.assertEqual(_colorize.can_colorize(), False)
+
+            with unittest.mock.patch("os.environ", {}):
+                if sys.platform == "win32":
                     self.assertEqual(_colorize.can_colorize(), False)
-                with unittest.mock.patch("os.environ",
-                                         {'NO_COLOR': '1', "PYTHON_COLORS": 
'1'}):
+
+                    vt_mock.return_value = True
                     self.assertEqual(_colorize.can_colorize(), True)
-                with unittest.mock.patch("os.environ", {'FORCE_COLOR': '1'}):
+                else:
                     self.assertEqual(_colorize.can_colorize(), True)
-                with unittest.mock.patch("os.environ",
-                                         {'FORCE_COLOR': '1', 'NO_COLOR': 
'1'}):
-                    self.assertEqual(_colorize.can_colorize(), False)
-                with unittest.mock.patch("os.environ",
-                                         {'FORCE_COLOR': '1', "PYTHON_COLORS": 
'0'}):
-                    self.assertEqual(_colorize.can_colorize(), False)
+
                 isatty_mock.return_value = False
-                with unittest.mock.patch("os.environ", {}):
-                    self.assertEqual(_colorize.can_colorize(), False)
+                stderr_mock.isatty.return_value = False
+                self.assertEqual(_colorize.can_colorize(), False)
 
 
 if __name__ == "__main__":
diff --git 
a/Misc/NEWS.d/next/Windows/2024-11-28-15-55-48.gh-issue-127353.i-XOXg.rst 
b/Misc/NEWS.d/next/Windows/2024-11-28-15-55-48.gh-issue-127353.i-XOXg.rst
new file mode 100644
index 00000000000000..88661b9a611071
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2024-11-28-15-55-48.gh-issue-127353.i-XOXg.rst
@@ -0,0 +1,2 @@
+Allow to force color output on Windows using environment variables. Patch by
+Andrey Efremov.

_______________________________________________
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