#13476 closed New feature (fixed)
Enable colors on Windows if pyreadline is installed.
Reported by: | Yuri Baburov | Owned by: | Yuri Baburov |
---|---|---|---|
Component: | Core (Management commands) | Version: | dev |
Severity: | Normal | Keywords: | windows console colors |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | yes |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
Python module pyreadline makes possible ansi color handling for windows.
Attachments (2)
Change History (16)
by , 15 years ago
Attachment: | 13476-concept.patch added |
---|
comment:1 by , 15 years ago
Needs documentation: | set |
---|---|
Patch needs improvement: | set |
Summary: | Enable colors in win32 if pyreadline is installed. → Enable colors on Windows if pyreadline is installed. |
Patch clearly needs improvement.
Also ticket needs documentation note(s) to mention that users need to install pyreadline to enable console colors.
follow-up: 3 comment:2 by , 15 years ago
Triage Stage: | Unreviewed → Accepted |
---|
No problem with the broader idea of allowing color terminal support for Windows. However, it's going to need to be a clean implementation. If Windows has a problem with ANSI color codes, I'm more inclined to accept this as a limitation of the platform than I am to accept a messy munging of stdout/stderr handling.
comment:3 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
I fixed a bug that pipeline redirection didn't work on Windows after applying patch. Now it's 100% good patch.
Replying to russellm:
No problem with the broader idea of allowing color terminal support for Windows. However, it's going to need to be a clean implementation. If Windows has a problem with ANSI color codes, I'm more inclined to accept this as a limitation of the platform than I am to accept a messy munging of stdout/stderr handling.
I thought a bit more. Regarding a "clean implementation".
ANSI colors were never a part of Windows, and IPython use PyReadline for this -- and IMHO we can't do anything better than use PyReadline.
PyReadline use ctypes and creates windows Console using native function calls.
So we have 5 ways:
- Substitute stdout with one from PyReadline and use ANSI colors.
- Use windows console output commands for Windows, not ANSI. We won't be able to use strings with color information at all.
- Use not sys.stdout but our own console, accessible from some get_console() or BaseCommand.console property.
This would work, but amount of changes would be large, and backwards compatibility for user commands is not guaranteed.
In fact, IPython does exactly this: it stores its own console handler, since "import sys; sys.stdout" gives you unpatched version.
- Both (3) and reimplement the pyreadline code.
- Screw that Windows. If you use Windows, you're loser, Django will never be that perfect on Windows. (This is my brain translation of "accept this as a limitation of a platform")
The code itself is quite large to be included in Django: http://bazaar.launchpad.net/~pyreadline/pyreadline/1.5/files/head:/pyreadline/console/ ,
so IMHO (3) is better than (4).
But I think the approach (1) is better than (3):
- Django plugins creators can use colors, and be sure colors will work on windows platform (not sure for PocketPC, it has to work since console works the same there, but I was unable to google any proof).
- It doesn't require to use console variable, so one can continue to use print ... and sys.stdout.write calls.
- Only windows users' console will be replaced, so they'll get an "ANSI console" emulation.
- Console is patched only when color_style() is called.
- Old sys.stdout is saved at console_stdout, and sys.stderr in console_stderr,
- Console is patched only once, determined by "type(sys.stdout) is file and sys.stdout.isatty()" line.
- The only check that won't work is type(sys.stdout) is not a 'file' any more, but pyreadline.console.Console. I don't know why they did so. But a) this was not a part of Django public contract, and b) nobody should check this -- file contract is that it has .write() method
However someone should write in a documentation, that in attempt to make console work in Windows, we replace it with pyreadline.console.Console, and so one can use full ANSI output, and if they don't want -- one can just replace console with their class before us or after us, we patch console once and only if it's not patched yet.
Maybe it is also a good idea to ask people to patch their console manually if they want colors.
They just need to insert 20 lines of code in their settings.py (or maybe .pythonrc ? -- i'm not sure on this), and it will work.
Or I can pack those 20 lines into a library that will do that hack on import.
Call it "ansi-colors-on-windows" and add to pypi. Django will stay clean then. Probably docs proposing usage of this package should be written anyway -- colors are valuable addition for runserver, different sql outputs -- well, you know.
comment:4 by , 14 years ago
FWIW there's no need to backup sys.stdout
and sys.stderr
is that way, they're made available as sys.__stdout__
and sys.__stderr__
comment:5 by , 14 years ago
Component: | django-admin.py runserver → Core (Management commands) |
---|
comment:6 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
follow-up: 14 comment:13 by , 11 years ago
IMHO we should try hard to not keep adding code to Django that deals with platforms limitations/particularities.
Contributor buriy has done a good work enumerating the options in comment:3. Other options available are:
- Use the colorama lib (https://pypi.python.org/pypi/colorama)
- Rely on the user having installed the ANSICON external app (http://adoxa.hostmyway.net/ansicon/). The code modification is essentially a one-liner:
diff --git a/django/core/management/color.py b/django/core/management/color.py index 20e31ff..4276c7d 100644 --- a/django/core/management/color.py +++ b/django/core/management/color.py @@ -13,10 +13,11 @@ def supports_color(): Returns True if the running system's terminal supports color, and False otherwise. """ - unsupported_platform = (sys.platform in ('win32', 'Pocket PC')) + plat = sys.platform + supported_platform = plat != 'Pocket PC' and (plat != 'win32' or 'ANSICON' in os.environ) # isatty is not always implemented, #6223. is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() - if unsupported_platform or not is_a_tty: + if not supported_platform or not is_a_tty: return False return True
Googling shows there are other open source projects that have chosen this path (Cucumber, RSpec).
6, just like the options that involve dependency on pyreadline, imply adding a soft third party Python module dependency and/or code to deal with the issue.
I'm ready to either simply close this ticket or to commit the above patch.
comment:14 by , 11 years ago
Replying to ramiro:
IMHO we should try hard to not keep adding code to Django that deals with platforms limitations/particularities.
I meant: Try hard to not keep adding code to Django that deals with platforms limitations/particularities for non essential functionality like e.g. the dev server and its reloading mechanism and this one: management commands color output.
comment:16 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:17 by , 4 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
I attached a patch to prove it's working. Though, accurate patch should not attempt to mangle sys.stdout and sys.stderr but add everywhere a variable pointing to the right console handle instead.