aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools/py36compat.py
diff options
context:
space:
mode:
authorBenoit Pierre <benoit.pierre@gmail.com>2017-10-25 17:55:26 +0200
committerBenoit Pierre <benoit.pierre@gmail.com>2017-10-25 23:16:15 +0200
commit2c897b5b877d401e13b661f2a0a14e99a1aabdc8 (patch)
tree5f6e7a21ba5566840d879ca3a0d1fef180c2d47f /setuptools/py36compat.py
parent3686dedb4bfbd0e6630c10119c8fe7af9369248e (diff)
downloadexternal_python_setuptools-2c897b5b877d401e13b661f2a0a14e99a1aabdc8.tar.gz
external_python_setuptools-2c897b5b877d401e13b661f2a0a14e99a1aabdc8.tar.bz2
external_python_setuptools-2c897b5b877d401e13b661f2a0a14e99a1aabdc8.zip
improve encoding handling for `setup.cfg`
Support the same mechanism as for Python sources for declaring the encoding to be used when reading `setup.cfg` (see PEP 263), and return the results of reading it as Unicode. Fix #1062 and #1136.
Diffstat (limited to 'setuptools/py36compat.py')
-rw-r--r--setuptools/py36compat.py37
1 files changed, 25 insertions, 12 deletions
diff --git a/setuptools/py36compat.py b/setuptools/py36compat.py
index f5279696..3d3c34ec 100644
--- a/setuptools/py36compat.py
+++ b/setuptools/py36compat.py
@@ -1,7 +1,21 @@
+import io
+import re
import sys
from distutils.errors import DistutilsOptionError
from distutils.util import strtobool
from distutils.debug import DEBUG
+from setuptools.extern import six
+
+
+CODING_RE = re.compile(br'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)')
+
+def detect_encoding(fp):
+ first_line = fp.readline()
+ fp.seek(0)
+ m = CODING_RE.match(first_line)
+ if m is None:
+ return None
+ return m.group(1).decode('ascii')
class Distribution_parse_config_files:
@@ -13,10 +27,10 @@ class Distribution_parse_config_files:
as implemented in distutils.
"""
def parse_config_files(self, filenames=None):
- from configparser import ConfigParser
+ from setuptools.extern.six.moves.configparser import ConfigParser
# Ignore install directory options if we have a venv
- if sys.prefix != sys.base_prefix:
+ if six.PY3 and sys.prefix != sys.base_prefix:
ignore_options = [
'install-base', 'install-platbase', 'install-lib',
'install-platlib', 'install-purelib', 'install-headers',
@@ -33,11 +47,16 @@ class Distribution_parse_config_files:
if DEBUG:
self.announce("Distribution.parse_config_files():")
- parser = ConfigParser(interpolation=None)
+ parser = ConfigParser()
for filename in filenames:
- if DEBUG:
- self.announce(" reading %s" % filename)
- parser.read(filename)
+ with io.open(filename, 'rb') as fp:
+ encoding = detect_encoding(fp)
+ if DEBUG:
+ self.announce(" reading %s [%s]" % (
+ filename, encoding or 'locale')
+ )
+ reader = io.TextIOWrapper(fp, encoding=encoding)
+ (parser.read_file if six.PY3 else parser.readfp)(reader)
for section in parser.sections():
options = parser.options(section)
opt_dict = self.get_option_dict(section)
@@ -69,12 +88,6 @@ class Distribution_parse_config_files:
raise DistutilsOptionError(msg)
-if sys.version_info < (3,):
- # Python 2 behavior is sufficient
- class Distribution_parse_config_files:
- pass
-
-
if False:
# When updated behavior is available upstream,
# disable override here.