From d2581bf30b6cfaa64f8b570b368a6f4ed5a710ff Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Apr 2024 13:47:03 -0400 Subject: [PATCH 1/3] Add 'consolidate_linker_args' wrapper to protect the old behavior for now. Closes pypa/distutils#246. --- distutils/compat/__init__.py | 15 +++++++++++++++ distutils/compat/py38.py | 23 +++++++++++++++++++++++ distutils/tests/test_unixccompiler.py | 17 +++++++++-------- distutils/unixccompiler.py | 5 +++-- 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 distutils/compat/__init__.py create mode 100644 distutils/compat/py38.py diff --git a/distutils/compat/__init__.py b/distutils/compat/__init__.py new file mode 100644 index 0000000000..b7be72678f --- /dev/null +++ b/distutils/compat/__init__.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from .py38 import removeprefix + + +def consolidate_linker_args(args: list[str]) -> str: + """ + Ensure the return value is a string for backward compatibility. + + Retain until at least 2024-10-31. + """ + + if not all(arg.startswith('-Wl,') for arg in args): + return args + return '-Wl,' + ','.join(removeprefix(arg, '-Wl,') for arg in args) diff --git a/distutils/compat/py38.py b/distutils/compat/py38.py new file mode 100644 index 0000000000..0af3814017 --- /dev/null +++ b/distutils/compat/py38.py @@ -0,0 +1,23 @@ +import sys + +if sys.version_info < (3, 9): + + def removesuffix(self, suffix): + # suffix='' should not call self[:-0]. + if suffix and self.endswith(suffix): + return self[: -len(suffix)] + else: + return self[:] + + def removeprefix(self, prefix): + if self.startswith(prefix): + return self[len(prefix) :] + else: + return self[:] +else: + + def removesuffix(self, suffix): + return self.removesuffix(suffix) + + def removeprefix(self, prefix): + return self.removeprefix(prefix) diff --git a/distutils/tests/test_unixccompiler.py b/distutils/tests/test_unixccompiler.py index f17edf2f6b..6f05fa6989 100644 --- a/distutils/tests/test_unixccompiler.py +++ b/distutils/tests/test_unixccompiler.py @@ -4,6 +4,7 @@ import sys import unittest.mock as mock from distutils import sysconfig +from distutils.compat import consolidate_linker_args from distutils.errors import DistutilsPlatformError from distutils.unixccompiler import UnixCCompiler from distutils.util import _clear_cached_macosx_ver @@ -149,10 +150,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) def gcv(v): if v == 'CC': @@ -161,10 +162,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) # GCC non-GNULD sys.platform = 'bar' @@ -189,10 +190,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) # non-GCC GNULD sys.platform = 'bar' @@ -204,10 +205,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) # non-GCC non-GNULD sys.platform = 'bar' diff --git a/distutils/unixccompiler.py b/distutils/unixccompiler.py index a54481c01b..0248bde87b 100644 --- a/distutils/unixccompiler.py +++ b/distutils/unixccompiler.py @@ -22,6 +22,7 @@ import sys from . import sysconfig +from .compat import consolidate_linker_args from ._log import log from ._macos_compat import compiler_fixup from ._modified import newer @@ -315,11 +316,11 @@ def runtime_library_dir_option(self, dir: str) -> str | list[str]: # For all compilers, `-Wl` is the presumed way to pass a # compiler option to the linker if sysconfig.get_config_var("GNULD") == "yes": - return [ + return consolidate_linker_args([ # Force RUNPATH instead of RPATH "-Wl,--enable-new-dtags", "-Wl,-rpath," + dir, - ] + ]) else: return "-Wl,-R" + dir From 98eee7f74c93fb84226d18f370f883956e644619 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Apr 2024 14:03:03 -0400 Subject: [PATCH 2/3] Exclude compat package from coverage. --- .coveragerc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.coveragerc b/.coveragerc index 35b98b1df9..bcef31d957 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,6 +2,9 @@ omit = # leading `*/` for pytest-dev/pytest-cov#456 */.tox/* + + # local + */compat/* disable_warnings = couldnt-parse From ef297f26182823d54acfe3719416aa2661706b29 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Apr 2024 16:40:21 -0400 Subject: [PATCH 3/3] Extend the retention of the compatibility. --- distutils/compat/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distutils/compat/__init__.py b/distutils/compat/__init__.py index b7be72678f..b1ee3fe8b0 100644 --- a/distutils/compat/__init__.py +++ b/distutils/compat/__init__.py @@ -7,7 +7,7 @@ def consolidate_linker_args(args: list[str]) -> str: """ Ensure the return value is a string for backward compatibility. - Retain until at least 2024-10-31. + Retain until at least 2024-04-31. See pypa/distutils#246 """ if not all(arg.startswith('-Wl,') for arg in args):