+v40.7.1
+-------
+
+* #1660: On Python 2, when reading config files, downcast options from text to bytes to satisfy distutils expectations.
+
+
v40.7.0
-------
[bumpversion]
-current_version = 40.7.0
+current_version = 40.7.1
commit = True
tag = True
setup_params = dict(
name="setuptools",
- version="40.7.0",
+ version="40.7.1",
description=(
"Easily download, build, install, upgrade, and uninstall "
"Python packages"
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)
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
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, ''
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):
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