Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue 326 unicode decode error #374

Merged
merged 5 commits into from
Feb 7, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion pip/backwardcompat.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ def u(s):
return s.decode('utf-8') return s.decode('utf-8')


def console_to_str(s): def console_to_str(s):
return s.decode(console_encoding) try:
return s.decode(console_encoding)
except UnicodeDecodeError:
return s.decode('utf_8')

def fwrite(f, s):
f.buffer.write(b(s))

bytes = bytes bytes = bytes
string_types = (str,) string_types = (str,)
raw_input = input raw_input = input
Expand All @@ -86,6 +93,10 @@ def u(s):


def console_to_str(s): def console_to_str(s):
return s return s

def fwrite(f, s):
f.write(s)

bytes = str bytes = str
string_types = (basestring,) string_types = (basestring,)
reduce = reduce reduce = reduce
Expand Down
5 changes: 4 additions & 1 deletion pip/log.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import sys import sys
import logging import logging


import pip.backwardcompat



class Logger(object): class Logger(object):


Expand Down Expand Up @@ -71,7 +73,8 @@ def log(self, level, msg, *args, **kw):
## FIXME: should this be a name, not a level number? ## FIXME: should this be a name, not a level number?
rendered = '%02i %s' % (level, rendered) rendered = '%02i %s' % (level, rendered)
if hasattr(consumer, 'write'): if hasattr(consumer, 'write'):
consumer.write(rendered+'\n') rendered += '\n'
pip.backwardcompat.fwrite(consumer, rendered)
else: else:
consumer(rendered) consumer(rendered)


Expand Down
Empty file.
25 changes: 25 additions & 0 deletions tests/packages/BrokenEmitsUTF8/setup.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-

from distutils.core import setup
import sys

class FakeError(Exception):
pass

if sys.argv[1] == 'install':
if hasattr(sys.stdout, 'buffer'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, let's encapsulate this into pip.backwardcompat.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er, never mind, given the context here (setup.py of a fake package), better leave it as is, not a problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, left this as-is.

sys.stdout.buffer.write('\nThis package prints out UTF-8 stuff like:\n'.encode('utf-8'))
sys.stdout.buffer.write('* return type of ‘main’ is not ‘int’\n'.encode('utf-8'))
sys.stdout.buffer.write('* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]'.encode('utf-8'))
else:
pass
sys.stdout.write('\nThis package prints out UTF-8 stuff like:\n')
sys.stdout.write('* return type of \xe2\x80\x98main\xe2\x80\x99 is not \xe2\x80\x98int\xe2\x80\x99\n')
sys.stdout.write('* Bj\xc3\xb6rk Gu\xc3\xb0mundsd\xc3\xb3ttir [\xcb\x88pj\xc5\x93r\xcc\xa5k \xcb\x88kv\xca\x8f\xc3\xb0m\xca\x8fnts\xcb\x8cto\xca\x8aht\xc9\xaar]\n')

raise FakeError('this package designed to fail on install')

setup(name='broken',
version='0.2broken',
py_modules=['broken'],
)
25 changes: 25 additions & 0 deletions tests/test_unicode.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,25 @@
import os
from tests.test_pip import here, reset_env, run_pip


def test_install_package_that_emits_unicode():
"""
Install a package with a setup.py that emits UTF-8 output and then fails.
This works fine in Python 2, but fails in Python 3 with:

Traceback (most recent call last):
...
File "/Users/marc/python/virtualenvs/py3.1-phpserialize/lib/python3.2/site-packages/pip-1.0.2-py3.2.egg/pip/__init__.py", line 230, in call_subprocess
line = console_to_str(stdout.readline())
File "/Users/marc/python/virtualenvs/py3.1-phpserialize/lib/python3.2/site-packages/pip-1.0.2-py3.2.egg/pip/backwardcompat.py", line 60, in console_to_str
return s.decode(console_encoding)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 17: ordinal not in range(128)

Refs https://github.com/pypa/pip/issues/326
"""

env = reset_env()
to_install = os.path.abspath(os.path.join(here, 'packages', 'BrokenEmitsUTF8'))
result = run_pip('install', to_install, expect_error=True)
assert '__main__.FakeError: this package designed to fail on install' in result.stdout
assert 'UnicodeDecodeError' not in result.stdout