mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			134 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import contextlib
 | 
						|
import io
 | 
						|
import sys
 | 
						|
import unittest
 | 
						|
import unittest.mock
 | 
						|
import _colorize
 | 
						|
from test.support.os_helper import EnvironmentVarGuard
 | 
						|
 | 
						|
 | 
						|
@contextlib.contextmanager
 | 
						|
def clear_env():
 | 
						|
    with EnvironmentVarGuard() as mock_env:
 | 
						|
        mock_env.unset("FORCE_COLOR", "NO_COLOR", "PYTHON_COLORS", "TERM")
 | 
						|
        yield mock_env
 | 
						|
 | 
						|
 | 
						|
def supports_virtual_terminal():
 | 
						|
    if sys.platform == "win32":
 | 
						|
        return unittest.mock.patch("nt._supports_virtual_terminal", return_value=True)
 | 
						|
    else:
 | 
						|
        return contextlib.nullcontext()
 | 
						|
 | 
						|
 | 
						|
class TestColorizeFunction(unittest.TestCase):
 | 
						|
    def test_colorized_detection_checks_for_environment_variables(self):
 | 
						|
        def check(env, fallback, expected):
 | 
						|
            with (self.subTest(env=env, fallback=fallback),
 | 
						|
                  clear_env() as mock_env):
 | 
						|
                mock_env.update(env)
 | 
						|
                isatty_mock.return_value = fallback
 | 
						|
                stdout_mock.isatty.return_value = fallback
 | 
						|
                self.assertEqual(_colorize.can_colorize(), expected)
 | 
						|
 | 
						|
        with (unittest.mock.patch("os.isatty") as isatty_mock,
 | 
						|
              unittest.mock.patch("sys.stdout") as stdout_mock,
 | 
						|
              supports_virtual_terminal()):
 | 
						|
            stdout_mock.fileno.return_value = 1
 | 
						|
 | 
						|
            for fallback in False, True:
 | 
						|
                check({}, fallback, fallback)
 | 
						|
                check({'TERM': 'dumb'}, fallback, False)
 | 
						|
                check({'TERM': 'xterm'}, fallback, fallback)
 | 
						|
                check({'TERM': ''}, fallback, fallback)
 | 
						|
                check({'FORCE_COLOR': '1'}, fallback, True)
 | 
						|
                check({'FORCE_COLOR': '0'}, fallback, True)
 | 
						|
                check({'FORCE_COLOR': ''}, fallback, fallback)
 | 
						|
                check({'NO_COLOR': '1'}, fallback, False)
 | 
						|
                check({'NO_COLOR': '0'}, fallback, False)
 | 
						|
                check({'NO_COLOR': ''}, fallback, fallback)
 | 
						|
 | 
						|
            check({'TERM': 'dumb', 'FORCE_COLOR': '1'}, False, True)
 | 
						|
            check({'FORCE_COLOR': '1', 'NO_COLOR': '1'}, True, False)
 | 
						|
 | 
						|
            for ignore_environment in False, True:
 | 
						|
                # Simulate running with or without `-E`.
 | 
						|
                flags = unittest.mock.MagicMock(ignore_environment=ignore_environment)
 | 
						|
                with unittest.mock.patch("sys.flags", flags):
 | 
						|
                    check({'PYTHON_COLORS': '1'}, True, True)
 | 
						|
                    check({'PYTHON_COLORS': '1'}, False, not ignore_environment)
 | 
						|
                    check({'PYTHON_COLORS': '0'}, True, ignore_environment)
 | 
						|
                    check({'PYTHON_COLORS': '0'}, False, False)
 | 
						|
                    for fallback in False, True:
 | 
						|
                        check({'PYTHON_COLORS': 'x'}, fallback, fallback)
 | 
						|
                        check({'PYTHON_COLORS': ''}, fallback, fallback)
 | 
						|
 | 
						|
                    check({'TERM': 'dumb', 'PYTHON_COLORS': '1'}, False, not ignore_environment)
 | 
						|
                    check({'NO_COLOR': '1', 'PYTHON_COLORS': '1'}, False, not ignore_environment)
 | 
						|
                    check({'FORCE_COLOR': '1', 'PYTHON_COLORS': '0'}, True, ignore_environment)
 | 
						|
 | 
						|
    @unittest.skipUnless(sys.platform == "win32", "requires Windows")
 | 
						|
    def test_colorized_detection_checks_on_windows(self):
 | 
						|
        with (clear_env(),
 | 
						|
              unittest.mock.patch("os.isatty") as isatty_mock,
 | 
						|
              unittest.mock.patch("sys.stdout") as stdout_mock,
 | 
						|
              supports_virtual_terminal() as vt_mock):
 | 
						|
            stdout_mock.fileno.return_value = 1
 | 
						|
            isatty_mock.return_value = True
 | 
						|
            stdout_mock.isatty.return_value = True
 | 
						|
 | 
						|
            vt_mock.return_value = True
 | 
						|
            self.assertEqual(_colorize.can_colorize(), True)
 | 
						|
            vt_mock.return_value = False
 | 
						|
            self.assertEqual(_colorize.can_colorize(), False)
 | 
						|
            import nt
 | 
						|
            del nt._supports_virtual_terminal
 | 
						|
            self.assertEqual(_colorize.can_colorize(), False)
 | 
						|
 | 
						|
    def test_colorized_detection_checks_for_std_streams(self):
 | 
						|
        with (clear_env(),
 | 
						|
              unittest.mock.patch("os.isatty") as isatty_mock,
 | 
						|
              unittest.mock.patch("sys.stdout") as stdout_mock,
 | 
						|
              unittest.mock.patch("sys.stderr") as stderr_mock,
 | 
						|
              supports_virtual_terminal()):
 | 
						|
            stdout_mock.fileno.return_value = 1
 | 
						|
            stderr_mock.fileno.side_effect = ZeroDivisionError
 | 
						|
            stderr_mock.isatty.side_effect = ZeroDivisionError
 | 
						|
 | 
						|
            isatty_mock.return_value = True
 | 
						|
            stdout_mock.isatty.return_value = True
 | 
						|
            self.assertEqual(_colorize.can_colorize(), True)
 | 
						|
 | 
						|
            isatty_mock.return_value = False
 | 
						|
            stdout_mock.isatty.return_value = False
 | 
						|
            self.assertEqual(_colorize.can_colorize(), False)
 | 
						|
 | 
						|
    def test_colorized_detection_checks_for_file(self):
 | 
						|
        with clear_env(), supports_virtual_terminal():
 | 
						|
 | 
						|
            with unittest.mock.patch("os.isatty") as isatty_mock:
 | 
						|
                file = unittest.mock.MagicMock()
 | 
						|
                file.fileno.return_value = 1
 | 
						|
                isatty_mock.return_value = True
 | 
						|
                self.assertEqual(_colorize.can_colorize(file=file), True)
 | 
						|
                isatty_mock.return_value = False
 | 
						|
                self.assertEqual(_colorize.can_colorize(file=file), False)
 | 
						|
 | 
						|
            # No file.fileno.
 | 
						|
            with unittest.mock.patch("os.isatty", side_effect=ZeroDivisionError):
 | 
						|
                file = unittest.mock.MagicMock(spec=['isatty'])
 | 
						|
                file.isatty.return_value = True
 | 
						|
                self.assertEqual(_colorize.can_colorize(file=file), False)
 | 
						|
 | 
						|
            # file.fileno() raises io.UnsupportedOperation.
 | 
						|
            with unittest.mock.patch("os.isatty", side_effect=ZeroDivisionError):
 | 
						|
                file = unittest.mock.MagicMock()
 | 
						|
                file.fileno.side_effect = io.UnsupportedOperation
 | 
						|
                file.isatty.return_value = True
 | 
						|
                self.assertEqual(_colorize.can_colorize(file=file), True)
 | 
						|
                file.isatty.return_value = False
 | 
						|
                self.assertEqual(_colorize.can_colorize(file=file), False)
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    unittest.main()
 |