From 4595b9821150576d1888ed2cb65c229569ea34a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Robert?= Date: Mon, 15 Sep 2025 13:58:08 +0200 Subject: [PATCH] BUG: fix a bug where calling `distutils.build_ext.finalize_options` more than once would raise an exception --- newsfragments/5083.bugfix.rst | 2 ++ setuptools/_distutils/command/build_ext.py | 6 +++--- setuptools/tests/test_build_ext.py | 11 +++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 newsfragments/5083.bugfix.rst diff --git a/newsfragments/5083.bugfix.rst b/newsfragments/5083.bugfix.rst new file mode 100644 index 0000000000..d87f0364b2 --- /dev/null +++ b/newsfragments/5083.bugfix.rst @@ -0,0 +1,2 @@ +Fixed a bug where calling ``build_ext.finalize_options`` more than once would +raise an exception. \ No newline at end of file diff --git a/setuptools/_distutils/command/build_ext.py b/setuptools/_distutils/command/build_ext.py index ec45b4403e..1b4763ebc2 100644 --- a/setuptools/_distutils/command/build_ext.py +++ b/setuptools/_distutils/command/build_ext.py @@ -276,10 +276,10 @@ def finalize_options(self) -> None: # noqa: C901 if self.undef: self.undef = self.undef.split(',') - if self.swig_opts is None: - self.swig_opts = [] - else: + if isinstance(self.swig_opts, str): self.swig_opts = self.swig_opts.split(' ') + elif self.swig_opts is None: + self.swig_opts = [] # Finally add the user include and library directories if requested if self.user: diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py index c7b60ac32f..f818e5d36b 100644 --- a/setuptools/tests/test_build_ext.py +++ b/setuptools/tests/test_build_ext.py @@ -178,6 +178,17 @@ def C(file): assert example_stub.startswith(f"{build_lib}/mypkg/__pycache__/ext1") assert example_stub.endswith(".pyc") + def test_finalize_options_multiple_call(self): + """ + Regression test. Check that calling build_ext.finalize_options + more than once doesn't raise an exception. + """ + extension = Extension('spam.eggs', ['eggs.c']) + dist = Distribution(dict(ext_modules=[extension])) + cmd = build_ext(dist) + cmd.finalize_options() + cmd.finalize_options() + class TestBuildExtInplace: def get_build_ext_cmd(self, optional: bool, **opts) -> build_ext: