Imported Upstream version 40.7.1 upstream/40.7.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 28 Dec 2020 02:13:15 +0000 (11:13 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 28 Dec 2020 02:13:15 +0000 (11:13 +0900)
CHANGES.rst
setup.cfg
setup.py
setuptools/dist.py
setuptools/tests/environment.py
setuptools/tests/test_build_ext.py

index ca7122e..79ebe16 100644 (file)
@@ -1,3 +1,9 @@
+v40.7.1
+-------
+
+* #1660: On Python 2, when reading config files, downcast options from text to bytes to satisfy distutils expectations.
+
+
 v40.7.0
 -------
 
index 78eb759..c934e2f 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 40.7.0
+current_version = 40.7.1
 commit = True
 tag = True
 
index 00db0f0..9e50513 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -89,7 +89,7 @@ def pypi_link(pkg_filename):
 
 setup_params = dict(
     name="setuptools",
-    version="40.7.0",
+    version="40.7.1",
     description=(
         "Easily download, build, install, upgrade, and uninstall "
         "Python packages"
index b855122..ddb1787 100644 (file)
@@ -603,7 +603,7 @@ class Distribution(_Distribution):
 
                 for opt in options:
                     if opt != '__name__' and opt not in ignore_options:
-                        val = parser.get(section, opt)
+                        val = self._try_str(parser.get(section, opt))
                         opt = opt.replace('-', '_')
                         opt_dict[opt] = (filename, val)
 
@@ -627,6 +627,26 @@ class Distribution(_Distribution):
                 except ValueError as msg:
                     raise DistutilsOptionError(msg)
 
+    @staticmethod
+    def _try_str(val):
+        """
+        On Python 2, much of distutils relies on string values being of
+        type 'str' (bytes) and not unicode text. If the value can be safely
+        encoded to bytes using the default encoding, prefer that.
+
+        Why the default encoding? Because that value can be implicitly
+        decoded back to text if needed.
+
+        Ref #1653
+        """
+        if six.PY3:
+            return val
+        try:
+            return val.encode()
+        except UnicodeEncodeError:
+            pass
+        return val
+
     def _set_command_options(self, command_obj, option_dict=None):
         """
         Set the options for 'command_obj' from 'option_dict'.  Basically
index c67898c..bd3119e 100644 (file)
@@ -46,6 +46,8 @@ def run_setup_py(cmd, pypath=None, path=None,
             cmd, stdout=_PIPE, stderr=_PIPE, shell=shell, env=env,
         )
 
+        if isinstance(data_stream, tuple):
+            data_stream = slice(*data_stream)
         data = proc.communicate()[data_stream]
     except OSError:
         return 1, ''
index 6025715..3dc87ca 100644 (file)
@@ -8,6 +8,10 @@ from setuptools.command.build_ext import build_ext, get_abi3_suffix
 from setuptools.dist import Distribution
 from setuptools.extension import Extension
 
+from . import environment
+from .files import build_files
+from .textwrap import DALS
+
 
 class TestBuildExt:
     def test_get_ext_filename(self):
@@ -43,3 +47,69 @@ class TestBuildExt:
             assert res.endswith('eggs.pyd')
         else:
             assert 'abi3' in res
+
+
+def test_build_ext_config_handling(tmpdir_cwd):
+    files = {
+        'setup.py': DALS(
+            """
+            from setuptools import Extension, setup
+            setup(
+                name='foo',
+                version='0.0.0',
+                ext_modules=[Extension('foo', ['foo.c'])],
+            )
+            """),
+        'foo.c': DALS(
+            """
+            #include "Python.h"
+
+            #if PY_MAJOR_VERSION >= 3
+
+            static struct PyModuleDef moduledef = {
+                    PyModuleDef_HEAD_INIT,
+                    "foo",
+                    NULL,
+                    0,
+                    NULL,
+                    NULL,
+                    NULL,
+                    NULL,
+                    NULL
+            };
+
+            #define INITERROR return NULL
+
+            PyMODINIT_FUNC PyInit_foo(void)
+
+            #else
+
+            #define INITERROR return
+
+            void initfoo(void)
+
+            #endif
+            {
+            #if PY_MAJOR_VERSION >= 3
+                PyObject *module = PyModule_Create(&moduledef);
+            #else
+                PyObject *module = Py_InitModule("extension", NULL);
+            #endif
+                if (module == NULL)
+                    INITERROR;
+            #if PY_MAJOR_VERSION >= 3
+                return module;
+            #endif
+            }
+            """),
+        'setup.cfg': DALS(
+            """
+            [build]
+            build-base = foo_build
+            """),
+    }
+    build_files(files)
+    code, output = environment.run_setup_py(
+        cmd=['build'], data_stream=(0, 2),
+    )
+    assert code == 0, '\nSTDOUT:\n%s\nSTDERR:\n%s' % output