Opened 15 years ago

Closed 11 years ago

Last modified 4 years ago

#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)

13476-concept.patch (1.1 KB ) - added by Yuri Baburov 15 years ago.
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.
13476-better.patch (1.6 KB ) - added by Yuri Baburov 14 years ago.
Better patch

Download all attachments as: .zip

Change History (16)

by Yuri Baburov, 15 years ago

Attachment: 13476-concept.patch added

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.

comment:1 by Yuri Baburov, 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.

comment:2 by Russell Keith-Magee, 15 years ago

Triage Stage: UnreviewedAccepted

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.

by Yuri Baburov, 14 years ago

Attachment: 13476-better.patch added

Better patch

in reply to:  2 comment:3 by Yuri Baburov, 14 years ago

Owner: changed from nobody to Yuri Baburov
Status: newassigned

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:

  1. Substitute stdout with one from PyReadline and use ANSI colors.
  2. Use windows console output commands for Windows, not ANSI. We won't be able to use strings with color information at all.
  3. 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.

  1. Both (3) and reimplement the pyreadline code.
  2. 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 Alex Gaynor, 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 Gabriel Hurley, 14 years ago

Component: django-admin.py runserverCore (Management commands)

comment:6 by Julien Phalip, 14 years ago

Severity: Normal
Type: New feature

comment:7 by Jacob, 13 years ago

milestone: 1.3

Milestone 1.3 deleted

comment:11 by Aymeric Augustin, 13 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:12 by Aymeric Augustin, 13 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:13 by Ramiro Morales, 11 years ago

IMHO we should try hard no 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:

  1. Use the colorama lib (https://pypi.python.org/pypi/colorama)
  2. 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 c322614..4276c7d 100644
--- a/django/core/management/color.py
+++ b/django/core/management/color.py
@@ -14,10 +14,10 @@ def supports_color():
     otherwise.
     """
     plat = sys.platform
-    unsupported_platform = plat == 'Pocket PC' or plat == 'win32' and 'ANSICON' not in os.environ
+    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.

Version 0, edited 11 years ago by Ramiro Morales (next)

in reply to:  13 comment:14 by Ramiro Morales, 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.

Last edited 11 years ago by Ramiro Morales (previous) (diff)

comment:15 by Claude Paroz, 11 years ago

+1 for your proposal (7), with docs of course.

Last edited 11 years ago by Claude Paroz (previous) (diff)

comment:16 by Ramiro Morales <cramm0@…>, 11 years ago

Resolution: fixed
Status: assignedclosed

In 12615dab78cb6fc7d8c74b7b65a4136b0feeb33f:

Fixed #13476 -- Added support for color in console output under Windows.

Detect and use the services of the ANSICON third-party tool if it's
available.

comment:17 by Carlton Gibson, 4 years ago

Triage Stage: AcceptedReady for checkin
Note: See TracTickets for help on using tickets.
Back to Top