diff --git a/colorama/ansitowin32.py b/colorama/ansitowin32.py index 19291a0..3db248b 100644 --- a/colorama/ansitowin32.py +++ b/colorama/ansitowin32.py @@ -63,7 +63,9 @@ def closed(self): stream = self.__wrapped try: return stream.closed - except AttributeError: + # AttributeError in the case that the stream doesn't support being closed + # ValueError for the case that the stream has already been detached when atexit runs + except (AttributeError, ValueError): return True diff --git a/colorama/tests/ansitowin32_test.py b/colorama/tests/ansitowin32_test.py index bbe99f4..bbc647b 100644 --- a/colorama/tests/ansitowin32_test.py +++ b/colorama/tests/ansitowin32_test.py @@ -1,5 +1,5 @@ # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -from io import StringIO +from io import StringIO, TextIOWrapper from unittest import TestCase, main try: @@ -40,6 +40,17 @@ def testProxyNoContextManager(self): with StreamWrapper(mockStream, mockConverter) as wrapper: wrapper.write('hello') + def test_closed_shouldnt_raise_on_closed_stream(self): + stream = StringIO() + stream.close() + wrapper = StreamWrapper(stream, None) + self.assertEqual(wrapper.closed, True) + + def test_closed_shouldnt_raise_on_detached_stream(self): + stream = TextIOWrapper(StringIO()) + stream.detach() + wrapper = StreamWrapper(stream, None) + self.assertEqual(wrapper.closed, True) class AnsiToWin32Test(TestCase):