Skip to content

Commit

Permalink
on Windows try the API before enabling conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnon Yaari committed Sep 19, 2015
1 parent b5748dd commit 55f063d
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 9 deletions.
12 changes: 8 additions & 4 deletions colorama/ansitowin32.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style
from .winterm import WinTerm, WinColor, WinStyle
from .win32 import windll
from .win32 import windll, winapi_test


winterm = None
Expand Down Expand Up @@ -56,16 +56,20 @@ def __init__(self, wrapped, convert=None, strip=None, autoreset=False):
self.stream = StreamWrapper(wrapped, self)

on_windows = os.name == 'nt'
on_emulated_windows = on_windows and 'TERM' in os.environ
# We test if the WinAPI works, because even if we are on Windows
# we may be using a terminal that doesn't support the WinAPI
# (e.g. Cygwin Terminal). In this case it's up to the terminal
# to support the ANSI codes.
conversion_supported = on_windows and winapi_test()

# should we strip ANSI sequences from our output?
if strip is None:
strip = on_windows and not on_emulated_windows
strip = conversion_supported
self.strip = strip

# should we should convert ANSI sequences into win32 calls?
if convert is None:
convert = on_windows and not wrapped.closed and not on_emulated_windows and is_a_tty(wrapped)
convert = conversion_supported and not wrapped.closed and is_a_tty(wrapped)
self.convert = convert

# dict of ansi codes to win32 functions and parameters
Expand Down
2 changes: 1 addition & 1 deletion colorama/tests/ansitowin32_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def testInit(self):
self.assertEqual(stream.autoreset, auto)

@patch('colorama.ansitowin32.winterm', None)
@patch('os.environ', dict())
@patch('colorama.ansitowin32.winapi_test', lambda *_: True)
def testStripIsTrueOnWindows(self):
with osname('nt'):
mockStdout = Mock()
Expand Down
7 changes: 3 additions & 4 deletions colorama/tests/initialise_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,16 @@ def assertNotWrapped(self):
self.assertIs(sys.stderr, orig_stderr, 'stderr should not be wrapped')

@patch('colorama.initialise.reset_all')
@patch('os.environ', dict())
@patch('colorama.ansitowin32.winapi_test', lambda *_: True)
def testInitWrapsOnWindows(self, _):
with osname("nt"):
init()
self.assertWrapped()

@patch('colorama.initialise.reset_all')
@patch('os.environ', dict(TERM=''))
@patch('colorama.ansitowin32.winapi_test', lambda *_: False)
def testInitDoesntWrapOnEmulatedWindows(self, _):
with osname("nt"):
os.environ['TERM']
init()
self.assertNotWrapped()

Expand Down Expand Up @@ -87,7 +86,7 @@ def testInitWrapOffIncompatibleWithAutoresetOn(self):
self.assertRaises(ValueError, lambda: init(autoreset=True, wrap=False))

@patch('colorama.ansitowin32.winterm', None)
@patch('os.environ', dict())
@patch('colorama.ansitowin32.winapi_test', lambda *_: True)
def testInitOnlyWrapsOnce(self):
with osname("nt"):
init()
Expand Down
8 changes: 8 additions & 0 deletions colorama/win32.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
except (AttributeError, ImportError):
windll = None
SetConsoleTextAttribute = lambda *_: None
winapi_test = lambda *_: None
else:
from ctypes import byref, Structure, c_char, POINTER

Expand Down Expand Up @@ -93,6 +94,13 @@ def __str__(self):
STDERR: _GetStdHandle(STDERR),
}

def winapi_test():
handle = handles[STDOUT]
csbi = CONSOLE_SCREEN_BUFFER_INFO()
success = _GetConsoleScreenBufferInfo(
handle, byref(csbi))
return bool(success)

def GetConsoleScreenBufferInfo(stream_id=STDOUT):
handle = handles[stream_id]
csbi = CONSOLE_SCREEN_BUFFER_INFO()
Expand Down

0 comments on commit 55f063d

Please sign in to comment.