Skip to content

Commit

Permalink
Prevent file stream from being incorrectly wrapped on Pycharm
Browse files Browse the repository at this point in the history
  • Loading branch information
Delgan committed Sep 8, 2018
1 parent 2b7f7a7 commit 3579cde
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 7 deletions.
5 changes: 4 additions & 1 deletion colorama/ansitowin32.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def is_stream_closed(stream):

def is_a_tty(stream):
if 'PYCHARM_HOSTED' in os.environ:
return True
if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__):
return True
return (hasattr(stream, 'isatty') and stream.isatty())


Expand All @@ -41,6 +42,8 @@ def __getattr__(self, name):
def write(self, text):
self.__convertor.write(text)

def isatty(self):
return is_a_tty(self.__wrapped)

class AnsiToWin32(object):
'''
Expand Down
6 changes: 3 additions & 3 deletions colorama/tests/initialise_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from ..ansitowin32 import StreamWrapper
from ..initialise import init
from .utils import osname, redirected_output, replace_by_none
from .utils import osname, redirected_output, replace_by

orig_stdout = sys.stdout
orig_stderr = sys.stderr
Expand Down Expand Up @@ -55,9 +55,9 @@ def testInitDoesntWrapOnNonWindows(self):
self.assertNotWrapped()

def testInitDoesntWrapIfNone(self):
with replace_by_none():
with replace_by(None):
init()
# We can't use assertNotWrapped here because replace_by_none
# We can't use assertNotWrapped here because replace_by(None)
# changes stdout/stderr already.
self.assertIsNone(sys.stdout)
self.assertIsNone(sys.stderr)
Expand Down
54 changes: 54 additions & 0 deletions colorama/tests/isatty_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
import sys
from unittest import TestCase, main

from ..ansitowin32 import is_a_tty, AnsiToWin32
from .utils import pycharm, replace_by, replace_original_by, StreamTTY, StreamNonTTY


class IsattyTest(TestCase):

def test_TTY(self):
tty = StreamTTY()
self.assertTrue(is_a_tty(tty))
with pycharm():
self.assertTrue(is_a_tty(tty))

def test_nonTTY(self):
non_tty = StreamNonTTY()
self.assertFalse(is_a_tty(non_tty))
with pycharm():
self.assertFalse(is_a_tty(non_tty))

def test_withPycharm(self):
with pycharm():
self.assertTrue(is_a_tty(sys.stderr))
self.assertTrue(is_a_tty(sys.stdout))

def test_withPycharmTTYOverride(self):
tty = StreamTTY()
with pycharm(), replace_by(tty):
self.assertTrue(is_a_tty(tty))

def test_withPycharmNonTTYOverride(self):
non_tty = StreamNonTTY()
with pycharm(), replace_by(non_tty):
self.assertFalse(is_a_tty(non_tty))

def test_withPycharmNoneOverride(self):
with pycharm():
with replace_by(None), replace_original_by(None):
self.assertFalse(is_a_tty(None))
self.assertFalse(is_a_tty(StreamNonTTY()))
self.assertTrue(is_a_tty(StreamTTY()))

def test_withPycharmStreamWrapped(self):
with pycharm():
self.assertTrue(is_a_tty(AnsiToWin32(StreamTTY()).stream))
self.assertFalse(is_a_tty(AnsiToWin32(StreamNonTTY()).stream))
self.assertTrue(is_a_tty(AnsiToWin32(sys.stdout).stream))
self.assertTrue(is_a_tty(AnsiToWin32(sys.stderr).stream))


if __name__ == '__main__':
main()
33 changes: 30 additions & 3 deletions colorama/tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
from contextlib import contextmanager
from io import StringIO
import sys
import os

from mock import Mock

class StreamTTY(StringIO):
def isatty(self):
return True

class StreamNonTTY(StringIO):
def isatty(self):
return False

@contextmanager
def osname(name):
orig = os.name
Expand All @@ -21,11 +30,29 @@ def redirected_output():
sys.stdout = orig

@contextmanager
def replace_by_none():
def replace_by(stream):
orig_stdout = sys.stdout
orig_stderr = sys.stderr
sys.stdout = None
sys.stderr = None
sys.stdout = stream
sys.stderr = stream
yield
sys.stdout = orig_stdout
sys.stderr = orig_stderr

@contextmanager
def replace_original_by(stream):
orig_stdout = sys.__stdout__
orig_stderr = sys.__stderr__
sys.__stdout__ = stream
sys.__stderr__ = stream
yield
sys.__stdout__ = orig_stdout
sys.__stderr__ = orig_stderr

@contextmanager
def pycharm():
os.environ["PYCHARM_HOSTED"] = "1"
non_tty = StreamNonTTY()
with replace_by(non_tty), replace_original_by(non_tty):
yield
del os.environ["PYCHARM_HOSTED"]

0 comments on commit 3579cde

Please sign in to comment.