From bc9fd2d16f04717c07343c22c139013f5fbd1ced Mon Sep 17 00:00:00 2001 From: Benoit Pierre Date: Thu, 15 Jun 2017 11:49:04 +0200 Subject: [PATCH] fix #889 and #1062 --- setuptools/dist.py | 2 +- setuptools/py36compat.py | 39 ++++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/setuptools/dist.py b/setuptools/dist.py index 6b97ed33c55..653688fdf3a 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -352,7 +352,7 @@ def parse_config_files(self, filenames=None): and loads configuration. """ - _Distribution.parse_config_files(self, filenames=filenames) + Distribution_parse_config_files.parse_config_files(self, filenames=filenames) parse_configuration(self, self.command_options) if getattr(self, 'python_requires', None): diff --git a/setuptools/py36compat.py b/setuptools/py36compat.py index f5279696457..cb687df8fdc 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,18 +47,23 @@ def parse_config_files(self, filenames=None): 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) for opt in options: if opt != '__name__' and opt not in ignore_options: - val = parser.get(section,opt) + val = parser.get(section,opt,raw=True) opt = opt.replace('-', '_') opt_dict[opt] = (filename, val) @@ -69,12 +88,6 @@ def parse_config_files(self, filenames=None): 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.