summaryrefslogtreecommitdiff
path: root/pip/req.py
diff options
context:
space:
mode:
authorStefan Scherfke <stefan@sofa-rockers.org>2013-11-21 11:06:27 +0100
committerDonald Stufft <donald@stufft.io>2013-12-20 12:49:52 -0500
commitb878de0fe19e9b1aed8202cc384b180418938265 (patch)
treec0b2d79b1221bb2e5b705ebc4a870f6592ca3e07 /pip/req.py
parentd4bcee7bdec788895c362536e84e864a8a0cfba8 (diff)
downloadpip-b878de0fe19e9b1aed8202cc384b180418938265.tar.gz
Try utf-8, the system’s default encoding, and latin1 when reading egg_info-files to avoid UnicodeDecodeErrors at the installation of a package.
Diffstat (limited to 'pip/req.py')
-rw-r--r--pip/req.py29
1 files changed, 26 insertions, 3 deletions
diff --git a/pip/req.py b/pip/req.py
index bf6d66636..f05aeeb66 100644
--- a/pip/req.py
+++ b/pip/req.py
@@ -1,6 +1,7 @@
from email.parser import FeedParser
import os
import imp
+import locale
import pkg_resources
import re
import sys
@@ -35,6 +36,30 @@ import pip.wheel
from pip.wheel import move_wheel_files, Wheel, wheel_ext
+def read_text_file(filename):
+ """Return the contents of *filename*.
+
+ Try to decode the file contents with utf-8, the preffered system encoding
+ (e.g., cp1252 on some Windows machines) and latin1, in that order. Decoding
+ a byte string with latin1 will never raise an error. In the worst case, the
+ returned string will contain some garbage characters.
+
+ """
+ with open(filename, 'rb') as fp:
+ data = fp.read()
+
+ encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1']
+ for enc in encodings:
+ try:
+ data = data.decode(enc)
+ except UnicodeDecodeError:
+ continue
+ break
+
+ assert type(data) != bytes # Latin1 should have worked.
+ return data
+
+
class InstallRequirement(object):
def __init__(self, req, comes_from, source_dir=None, editable=False,
@@ -322,9 +347,7 @@ exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n',
filename = self.egg_info_path(filename)
if not os.path.exists(filename):
return None
- fp = open(filename, 'r')
- data = fp.read()
- fp.close()
+ data = read_text_file(filename)
return data
def egg_info_path(self, filename):