Fixed colorized output on Windows with Python 3.

Closes #87.
This commit is contained in:
Jakub Roztocil 2012-08-17 06:35:18 +02:00
parent 86256af1df
commit 4660da949f
5 changed files with 56 additions and 20 deletions

View File

@ -957,6 +957,8 @@ Changelog
*You can click a version name to see a diff with the previous one.*
* `0.2.8dev`_
* Fixed colorized output on Windows with Python 3.
* Fixed installation on Windows with Python 3.
* CRLF HTTP header field separation in the output.
* Added exit status code ``2`` for timed-out requests.
* Added ``--colors`` and ``--format`` in addition to ``--pretty``, to

View File

@ -10,7 +10,6 @@ Invocation flow:
5. Exit.
"""
from _socket import gaierror
import sys
import json
import errno
@ -18,14 +17,14 @@ from pprint import pformat
import requests
import requests.auth
from requests.compat import str
from requests.compat import str, is_py3
from httpie import __version__ as httpie_version
from requests import __version__ as requests_version
from pygments import __version__ as pygments_version
from .cli import parser
from .models import Environment
from .output import output_stream, write
from .output import output_stream, write, write_with_colors_win_p3k
from . import EXIT
@ -115,19 +114,20 @@ def main(args=sys.argv[1:], env=Environment()):
status = EXIT.OK
if debug:
sys.stderr.write('HTTPie version: %s\n' % httpie_version)
sys.stderr.write('Requests version: %s\n' % requests_version)
sys.stderr.write('Pygments version: %s\n' % pygments_version)
sys.stderr.write('HTTPie %s\n' % httpie_version)
sys.stderr.write('Requests %s\n' % requests_version)
sys.stderr.write('Pygments %s\n' % pygments_version)
sys.stderr.write('Python %s %s\n' % (sys.version, sys.platform))
try:
args = parser.parse_args(args=args, env=env)
kwargs = get_requests_kwargs(args)
requests_kwargs = get_requests_kwargs(args)
if args.debug:
sys.stderr.write(
'\n>>> requests.request(%s)\n\n' % pformat(kwargs))
'\n>>> requests.request(%s)\n\n' % pformat(requests_kwargs))
response = requests.request(**kwargs)
response = requests.request(**requests_kwargs)
if args.check_status:
status = get_exist_status(response.status_code,
@ -137,10 +137,16 @@ def main(args=sys.argv[1:], env=Environment()):
stream = output_stream(args, env, response.request, response)
write_kwargs = {
'stream': stream,
'outfile': env.stdout,
'flush': env.stdout_isatty or args.stream
}
try:
write(stream=stream,
outfile=env.stdout,
flush=env.stdout_isatty or args.stream)
if env.is_windows and is_py3 and 'colors' in args.prettify:
write_with_colors_win_p3k(**write_kwargs)
else:
write(**write_kwargs)
except IOError as e:
if not traceback and e.errno == errno.EPIPE:

View File

@ -18,13 +18,15 @@ class Environment(object):
if progname not in ['http', 'https']:
progname = 'http'
if is_windows:
import colorama.initialise
colorama.initialise.init()
stdin_isatty = sys.stdin.isatty()
stdin = sys.stdin
stdout_isatty = sys.stdout.isatty()
if stdout_isatty and is_windows:
from colorama.initialise import wrap_stream
stdout = wrap_stream(sys.stdout, convert=None,
strip=None, autoreset=True, wrap=True)
else:
stdout = sys.stdout
stderr = sys.stderr

View File

@ -61,6 +61,23 @@ def write(stream, outfile, flush):
outfile.flush()
def write_with_colors_win_p3k(stream, outfile, flush):
"""Like `write`, but colorized chunks are written as text
directly to `outfile` to ensure it gets processed by colorama.
Applies only to Windows with Python 3 and colorized terminal output.
"""
color = b'\x1b['
encoding = outfile.encoding
for chunk in stream:
if color in chunk:
outfile.write(chunk.decode(encoding))
else:
outfile.buffer.write(chunk)
if flush:
outfile.flush()
def output_stream(args, env, request, response):
"""Build and return a chain of iterators over the `request`-`response`
exchange each of which yields `bytes` chunks.

View File

@ -33,9 +33,9 @@ try:
except ImportError:
from urllib2 import urlopen
try:
from unittest import skipIf
from unittest import skipIf, skip
except ImportError:
skip = lambda msg: lambda self: None
def skipIf(cond, reason):
def decorator(test_method):
if cond:
@ -47,7 +47,6 @@ from requests import __version__ as requests_version
from requests.compat import is_windows, is_py26, bytes, str
#################################################################
# Utils/setup
#################################################################
@ -863,6 +862,7 @@ class ExitStatusTest(BaseTestCase):
self.assertEqual(r.exit_status, EXIT.OK)
self.assertTrue(not r.stderr)
@skip('httpbin.org always returns 500')
def test_timeout_exit_status(self):
r = http(
'--timeout=0.5',
@ -917,6 +917,15 @@ class ExitStatusTest(BaseTestCase):
self.assertEqual(r.exit_status, EXIT.ERROR_HTTP_5XX)
class WindowsOnlyTests(BaseTestCase):
@skip('FIXME: kills the runner')
#@skipIf(not is_windows, 'windows-only')
def test_windows_colorized_output(self):
# Spits out the colorized output.
http(httpbin('/get'), env=Environment())
class FakeWindowsTest(BaseTestCase):
def test_stdout_redirect_not_supported_on_windows(self):