diff --git a/newsfragments/5084.bugfix.rst b/newsfragments/5084.bugfix.rst new file mode 100644 index 0000000000..f35ca12b0d --- /dev/null +++ b/newsfragments/5084.bugfix.rst @@ -0,0 +1,2 @@ +Fixed a bug where calling ``build_ext.finalize_options`` after ``define`` or +``undef`` attributes were already set would raise an exception. diff --git a/setuptools/_distutils/command/build_ext.py b/setuptools/_distutils/command/build_ext.py index ec45b4403e..6e61e56777 100644 --- a/setuptools/_distutils/command/build_ext.py +++ b/setuptools/_distutils/command/build_ext.py @@ -266,14 +266,14 @@ def finalize_options(self) -> None: # noqa: C901 # specified by the 'define' option will be set to '1'. Multiple # symbols can be separated with commas. - if self.define: + if isinstance(self.define, str): defines = self.define.split(',') self.define = [(symbol, '1') for symbol in defines] # The option for macros to undefine is also a string from the # option parsing, but has to be a list. Multiple symbols can also # be separated with commas here. - if self.undef: + if isinstance(self.undef, str): self.undef = self.undef.split(',') if self.swig_opts is None: diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py index c7b60ac32f..d7525995c6 100644 --- a/setuptools/tests/test_build_ext.py +++ b/setuptools/tests/test_build_ext.py @@ -178,6 +178,22 @@ def C(file): assert example_stub.startswith(f"{build_lib}/mypkg/__pycache__/ext1") assert example_stub.endswith(".pyc") + def test_finalize_options_subclassing(self): + """ + Regression test. Check that calling build_ext.finalize_options after + define or undef attributes were already set to their final type doesn't raise. + """ + extension = Extension('spam.eggs', ['eggs.c']) + dist = Distribution(dict(ext_modules=[extension])) + cmd = build_ext(dist) + cmd.define = [("MY_MACRO", "1")] + cmd.undef = ["EVIL_MACRO"] + + cmd.finalize_options() + + assert cmd.define == [("MY_MACRO", "1")] + assert cmd.undef == ["EVIL_MACRO"] + class TestBuildExtInplace: def get_build_ext_cmd(self, optional: bool, **opts) -> build_ext: