1
0
mirror of https://github.com/httpie/cli.git synced 2025-11-06 08:59:22 +02:00

Fixed several unicode-related issues

Closes #31 Python 3 & non-ascii arguments => UnicodeEncodeError
Closes #41 Unicode response error.
Closes #42 UnicodeEncodeError when piping Unicode output
This commit is contained in:
Jakub Roztocil
2012-04-25 00:08:40 +02:00
parent 29e594daaf
commit 67d6426360
3 changed files with 52 additions and 41 deletions

View File

@@ -6,7 +6,7 @@ try:
except ImportError: except ImportError:
OrderedDict = dict OrderedDict = dict
import requests import requests
from requests.compat import urlparse, str from requests.compat import urlparse, str, is_py3
from requests.structures import CaseInsensitiveDict from requests.structures import CaseInsensitiveDict
from . import cli from . import cli
from . import pretty from . import pretty
@@ -165,30 +165,35 @@ def main(args=None,
prettifier = pretty.PrettyHttp(args.style) if do_prettify else None prettifier = pretty.PrettyHttp(args.style) if do_prettify else None
output_request = (cli.OUT_REQUEST_HEADERS in args.output_options do_output_request = (cli.OUT_REQ_HEADERS in args.output_options
or cli.OUT_REQUEST_BODY in args.output_options) or cli.OUT_REQ_BODY in args.output_options)
output_response = (cli.OUT_RESPONSE_HEADERS in args.output_options do_output_response = (cli.OUT_RESP_HEADERS in args.output_options
or cli.OUT_RESPONSE_BODY in args.output_options) or cli.OUT_RESP_BODY in args.output_options)
if output_request: output = []
stdout.write(format_http_message( if do_output_request:
output.append(format_http_message(
message=make_request_message(response.request), message=make_request_message(response.request),
prettifier=prettifier, prettifier=prettifier,
with_headers=cli.OUT_REQUEST_HEADERS in args.output_options, with_headers=cli.OUT_REQ_HEADERS in args.output_options,
with_body=cli.OUT_REQUEST_BODY in args.output_options with_body=cli.OUT_REQ_BODY in args.output_options
)) ))
if output_response: if do_output_response:
stdout.write(NEW_LINE) output.append(NEW_LINE)
if output_response: if do_output_response:
stdout.write(format_http_message( output.append(format_http_message(
message=make_response_message(response), message=make_response_message(response),
prettifier=prettifier, prettifier=prettifier,
with_headers=cli.OUT_RESPONSE_HEADERS in args.output_options, with_headers=cli.OUT_RESP_HEADERS in args.output_options,
with_body=cli.OUT_RESPONSE_BODY in args.output_options with_body=cli.OUT_RESP_BODY in args.output_options
)) ))
stdout.write(NEW_LINE) output.append(NEW_LINE)
output_bytes = ''.join(output).encode('utf8')
f = (stdout.buffer if is_py3 and hasattr(stdout, 'buffer') else stdout)
f.write(output_bytes)
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -13,18 +13,20 @@ SEP_HEADERS = SEP_COMMON
SEP_DATA = '=' SEP_DATA = '='
SEP_DATA_RAW_JSON = ':=' SEP_DATA_RAW_JSON = ':='
SEP_FILES = '@' SEP_FILES = '@'
OUT_REQ_HEADERS = 'H'
OUT_REQ_BODY = 'B'
OUT_RESP_HEADERS = 'h'
OUT_RESP_BODY = 'b'
OUTPUT_OPTIONS = [OUT_REQ_HEADERS,
OUT_REQ_BODY,
OUT_RESP_HEADERS,
OUT_RESP_BODY]
PRETTIFY_STDOUT_TTY_ONLY = object() PRETTIFY_STDOUT_TTY_ONLY = object()
OUT_REQUEST_HEADERS = 'H'
OUT_REQUEST_BODY = 'B'
OUT_RESPONSE_HEADERS = 'h'
OUT_RESPONSE_BODY = 'b'
OUTPUT_OPTIONS = [OUT_REQUEST_HEADERS,
OUT_REQUEST_BODY,
OUT_RESPONSE_HEADERS,
OUT_RESPONSE_BODY]
class ParseError(Exception): class ParseError(Exception):
pass pass
@@ -34,6 +36,7 @@ KeyValue = namedtuple('KeyValue', ['key', 'value', 'sep', 'orig'])
class KeyValueType(object): class KeyValueType(object):
"""A type used with `argparse`.""" """A type used with `argparse`."""
def __init__(self, *separators): def __init__(self, *separators):
self.separators = separators self.separators = separators
self.escapes = ['\\\\' + sep for sep in separators] self.escapes = ['\\\\' + sep for sep in separators]
@@ -56,7 +59,6 @@ class KeyValueType(object):
found[start] = sep found[start] = sep
if not found: if not found:
#noinspection PyExceptionInherit
raise argparse.ArgumentTypeError( raise argparse.ArgumentTypeError(
'"%s" is not a valid value' % string) '"%s" is not a valid value' % string)
@@ -160,7 +162,7 @@ group_type.add_argument(
) )
# output_options options. # Output options.
############################################# #############################################
parser.add_argument( parser.add_argument(
@@ -189,7 +191,7 @@ prettify.add_argument(
output_options = parser.add_mutually_exclusive_group(required=False) output_options = parser.add_mutually_exclusive_group(required=False)
output_options.add_argument('--print', '-p', dest='output_options', output_options.add_argument('--print', '-p', dest='output_options',
default=OUT_RESPONSE_HEADERS + OUT_RESPONSE_BODY, default=OUT_RESP_HEADERS + OUT_RESP_BODY,
help=_(''' help=_('''
String specifying what should the output contain. String specifying what should the output contain.
"{request_headers}" stands for request headers and "{request_headers}" stands for request headers and
@@ -199,10 +201,10 @@ output_options.add_argument('--print', '-p', dest='output_options',
Defaults to "hb" which means that the whole response Defaults to "hb" which means that the whole response
(headers and body) is printed. (headers and body) is printed.
'''.format( '''.format(
request_headers=OUT_REQUEST_HEADERS, request_headers=OUT_REQ_HEADERS,
request_body=OUT_REQUEST_BODY, request_body=OUT_REQ_BODY,
response_headers=OUT_RESPONSE_HEADERS, response_headers=OUT_RESP_HEADERS,
response_body=OUT_RESPONSE_BODY, response_body=OUT_RESP_BODY,
)) ))
) )
output_options.add_argument( output_options.add_argument(
@@ -215,19 +217,19 @@ output_options.add_argument(
) )
output_options.add_argument( output_options.add_argument(
'--headers', '-t', dest='output_options', '--headers', '-t', dest='output_options',
action='store_const', const=OUT_RESPONSE_HEADERS, action='store_const', const=OUT_RESP_HEADERS,
help=_(''' help=_('''
Print only the response headers. Print only the response headers.
Shortcut for --print={0}. Shortcut for --print={0}.
'''.format(OUT_RESPONSE_HEADERS)) '''.format(OUT_RESP_HEADERS))
) )
output_options.add_argument( output_options.add_argument(
'--body', '-b', dest='output_options', '--body', '-b', dest='output_options',
action='store_const', const=OUT_RESPONSE_BODY, action='store_const', const=OUT_RESP_BODY,
help=_(''' help=_('''
Print only the response body. Print only the response body.
Shortcut for --print={0}. Shortcut for --print={0}.
'''.format(OUT_RESPONSE_BODY)) '''.format(OUT_RESP_BODY))
) )
parser.add_argument( parser.add_argument(

View File

@@ -3,7 +3,8 @@ import os
import sys import sys
import unittest import unittest
import argparse import argparse
from requests.compat import StringIO, is_py26, str from requests.compat import is_py26
import tempfile
TESTS_ROOT = os.path.dirname(__file__) TESTS_ROOT = os.path.dirname(__file__)
@@ -22,9 +23,12 @@ def http(*args, **kwargs):
'stdout_isatty': False 'stdout_isatty': False
} }
http_kwargs.update(kwargs) http_kwargs.update(kwargs)
stdout = http_kwargs.setdefault('stdout', StringIO()) stdout = http_kwargs.setdefault('stdout', tempfile.TemporaryFile())
__main__.main(args=args, **http_kwargs) __main__.main(args=args, **http_kwargs)
return stdout.getvalue() stdout.seek(0)
response = stdout.read().decode('utf8')
stdout.close()
return response
class BaseTest(unittest.TestCase): class BaseTest(unittest.TestCase):
@@ -83,7 +87,7 @@ class TestItemParsing(BaseTest):
self.assertDictEqual(data, { self.assertDictEqual(data, {
'bob:=': 'foo', 'bob:=': 'foo',
}) })
def test_valid_items(self): def test_valid_items(self):
headers, data, files = cli.parse_items([ headers, data, files = cli.parse_items([
self.kv('string=value'), self.kv('string=value'),