From f7447817b65c12dfe508249cea019c41ce0dc23f Mon Sep 17 00:00:00 2001 From: Benoit Pierre Date: Mon, 28 Jan 2019 22:57:20 +0100 Subject: test: add a simple regression test for `build_ext` --- setuptools/tests/environment.py | 2 ++ setuptools/tests/test_build_ext.py | 70 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/setuptools/tests/environment.py b/setuptools/tests/environment.py index c67898ca..bd3119ef 100644 --- a/setuptools/tests/environment.py +++ b/setuptools/tests/environment.py @@ -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, '' diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py index 60257154..3dc87ca3 100644 --- a/setuptools/tests/test_build_ext.py +++ b/setuptools/tests/test_build_ext.py @@ -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 -- cgit v1.2.3 From 9150b6b7272130f11a71190905e6bd3db31afd81 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Jan 2019 17:10:37 -0500 Subject: Prefer native strings on Python 2 when reading config files. Fixes #1653. --- setuptools/dist.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/setuptools/dist.py b/setuptools/dist.py index b8551228..ddb1787a 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -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 -- cgit v1.2.3 From 32c2ec8bab51ca5b4609cefc3dc4eb9c4b0d5b87 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Jan 2019 17:57:35 -0500 Subject: Add changelog --- changelog.d/1660.change.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1660.change.rst diff --git a/changelog.d/1660.change.rst b/changelog.d/1660.change.rst new file mode 100644 index 00000000..52f62397 --- /dev/null +++ b/changelog.d/1660.change.rst @@ -0,0 +1 @@ +On Python 2, when reading config files, downcast options from text to bytes to satisfy distutils expectations. -- cgit v1.2.3 From 5133d86c3e71709f59fbb9c5b60577bcdb8a7698 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Jan 2019 19:08:28 -0500 Subject: =?UTF-8?q?Bump=20version:=2040.7.0=20=E2=86=92=2040.7.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.rst | 6 ++++++ changelog.d/1660.change.rst | 1 - setup.cfg | 2 +- setup.py | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) delete mode 100644 changelog.d/1660.change.rst diff --git a/CHANGES.rst b/CHANGES.rst index ca7122e9..79ebe165 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -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 ------- diff --git a/changelog.d/1660.change.rst b/changelog.d/1660.change.rst deleted file mode 100644 index 52f62397..00000000 --- a/changelog.d/1660.change.rst +++ /dev/null @@ -1 +0,0 @@ -On Python 2, when reading config files, downcast options from text to bytes to satisfy distutils expectations. diff --git a/setup.cfg b/setup.cfg index 78eb7596..c934e2f4 100644 --- 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 diff --git a/setup.py b/setup.py index 00db0f0a..9e50513b 100755 --- 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" -- cgit v1.2.3