nghung270192 / colorama

Automatically exported from code.google.com/p/colorama
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Colorama doesn't play nicely with other stdout/stderr wrappers #41

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Take a look at the wrapper provided at 
http://stackoverflow.com/a/3259271/247623 --it reliably enables Unicode output 
on cmd.exe; unquestionably useful. However, it turns out that colorama does not 
work out of the box in combination with that wrapper.

The reasons for this are:
* first of all, colorama needs to be activated after that wrapper because the 
other wrapper is more low level/fundamental
* colorama remembers the `orig_stdout` and `orig_stderr` references in its 
`initialise.py` at import time, thus, by the time `init()` is called, any 
wrappings that have taken place before `import colorama` and `init()` are 
effectively cancelled/ignored
* colorama does not convert ANSI codes for streams who are not `.isatty() == 
True`; I'm not sure why such check was implemented in the first place, but it 
looks to me that colorama works perfectly well with streams that do not have 
such property.

The current workaround is to manually update `orig_stdout` and `orig_stderr` 
with fresh values from `sys.stdout` and `sys.stderr` respectively, and also do 
`sys.stdout.isatty = sys.stderr.isatty = lambda: True` to satisfy the 
`is_a_tty` check in `ansitowin32.py`. However, it would be nice if colorama did 
not require such workaround to compose nicely with other wrappers.

Original issue reported on code.google.com by eallik on 21 Jan 2013 at 11:05

GoogleCodeExporter commented 9 years ago
Thanks for the report.

The reason I added the 'isatty()' check is that I thought this was the correct 
way to behave if, for example, the output is going to somewhere other than a 
terminal, e.g. is running as a GUI process without a terminal, or stdout is 
piped to a file. Calling the Windows console functions doesn't seem necessary 
in these cases, can't possibly work, and I was afraid might even raise errors 
in some situations.

I've become a new Dad this year, so have very little time to maintain projects 
like Colorama. If you can assure me that the above concerns are not an issue, 
and if you wanted to submit a patch, then I'd be happy to merge it and make a 
new release.

Best regards.

Original comment by Jonat...@rangespan.com on 22 Jan 2013 at 6:42

GoogleCodeExporter commented 9 years ago
First of all, congratulations on becoming a dad! Definitely more of a timeless 
value than colored output on Windows :)

The purpose of isatty you've described is obviously completely valid, and it's 
thus hard to argue against having measures in colorama for proper dealing with 
redirected standard streams. However, thinking of it from a different angle, 
perhaps the interface to activating colorama should be slightly different to 
start with. Currently it's implemented as some sort of a "compilation flag" in 
the "header" of the program, figuratively speaking, which means it has to be (a 
bit) overly smart about its behavior and take decisions based on what it can 
tell about the environment it's running in. If we were to approach this from a 
somewhat more functional programming point of view, perhaps the side effects 
introduced by colorama.init should somehow be more explicit, thus putting the 
responsibility for making sure it's activated only when needed on the shoulders 
of the caller. So, even though it wouldn't probably make sense to have 
something like colorama.patch(streams=[sys.stdout, sys.stderr]) but explicitly 
stating that colorama.init should be called if and only if sys.stdout/stderr in 
fact are the real stdout and stderr. I guess the principle of side-effects and 
composability not playing nicely together is fully applicable here.

Also, regarding `isatty`—it really is just a heuristic approach to avoiding 
unwanted wrapping. Composing with other wrappers is a good example of this. So 
perhaps this check should simply be eliminated in future versions of colorama 
and an explicit note added to the documentation about colorama.init not being 
meant to be called fully unconditionally.

Regardless of this though, the `orig_stdout` and `orig_stderr` globals should 
not be initialised prematurely as they are now and should instead be set to the 
current values of sys.stderr and sys.stdout at the time when colorama.init is 
called.

Original comment by eallik on 22 Jan 2013 at 10:07

GoogleCodeExporter commented 9 years ago
Alright, makes sense. Thanks for all that info, it's very much appreciated.

At the very least I'll change the 'orig_stdxxx' initialisation as you suggest 
at the end, and issue a new release.

If I can figure a better way to handle the other stuff too, then I'll do that. 
More as it happens.

Original comment by Jonat...@rangespan.com on 23 Jan 2013 at 9:16

GoogleCodeExporter commented 9 years ago
Also reported by Dave B:

On Windows, there are tons of problems with unicode output on Python
2.7, which I've heard are fixed in Python 3.0 (related to cp65001 not
mapping to utf-8 properly).  Anyway, to fix this, I have a bunch of
code that manually wraps the stdout/stderr to encode as utf-8 properly
at all times, no matter what the code page is.  However, colorama
overrides this with its own wrapper, due to the fact that the
orig_stdout/orig_stderr are saved as globals during IMPORT (colorama
global scope vars).

The fix is for Colorama to save these orig_xxx variables during
init().  This allows my own main to override stdout, and I can *then*
call colorama.init, which then wraps *my* stdout, and not the system's
original stdout.  This allows both the correctness of unicode, and the
colored goodness of colorama.

Dave.

Original comment by tart...@gmail.com on 14 Oct 2013 at 7:49

GoogleCodeExporter commented 9 years ago
I think you should keep the isatty check, as it protects against trying to add 
color to stdout piped to a file, for example.  The above reference unicode 
wrapper has a bug where it always returns False for isatty.  The fix for that 
is to return False only if the UnicodeStream.hConsole is None, in which case it 
is not a true terminal.

Original comment by dbrac...@gmail.com on 14 Oct 2013 at 5:27

GoogleCodeExporter commented 9 years ago
Migrated to https://github.com/tartley/colorama/issues/39
Closing as duplicate.

Original comment by tart...@gmail.com on 16 Feb 2015 at 12:09