From 30f0ccfd5373deabadcd9dd37e9cab97d59e09b8 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Mon, 8 Jun 2026 16:47:06 +0100 Subject: [PATCH 1/2] gh-151089: Fix mocking in test_ctypes/test_find.py:test_find_library_with_gcc() ctypes.util.find_library() on POSIX will try ldconfig then gcc then ld. test_find_library_with_gcc() mocks away just the use of ldconfig, so if gcc isn't actually present on the machine (because the tests are being ran on an installed system, for example) then it will happily fall back to using ld, which makes a mockery (pun unintended) of the test case name. Also mock _findLib_ld to return None, so the test either uses gcc or fails if it isn't present. --- Lib/test/test_ctypes/test_find.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py index 8bc84c3d2ef9f85..2927ebed294d6cd 100644 --- a/Lib/test/test_ctypes/test_find.py +++ b/Lib/test/test_ctypes/test_find.py @@ -118,7 +118,8 @@ def test_find_on_libpath(self): self.assertEqual(find_library(libname), 'lib%s.so' % libname) def test_find_library_with_gcc(self): - with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None): + with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \ + unittest.mock.patch("ctypes.util._findLib_ld", lambda *args: None): self.assertNotEqual(find_library('c'), None) def test_find_library_with_ld(self): From f126d558b0bf13a523ff78079c4b33b93b2d3bdf Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Mon, 8 Jun 2026 18:01:22 +0100 Subject: [PATCH 2/2] gh-151089: Generalise and improve test skipping in test_ctypes/test_find.py In FindLibraryLinux, check for gcc and ld in setUpClass and then skip the tests that need those commands to be present. --- Lib/test/test_ctypes/test_find.py | 31 +++++++++++++++---- ...-06-10-12-14-32.gh-issue-151089.grvjfj.rst | 3 ++ 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2026-06-10-12-14-32.gh-issue-151089.grvjfj.rst diff --git a/Lib/test/test_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py index 2927ebed294d6cd..875d99ae3cf2ca6 100644 --- a/Lib/test/test_ctypes/test_find.py +++ b/Lib/test/test_ctypes/test_find.py @@ -78,17 +78,30 @@ def test_shell_injection(self): @unittest.skipUnless(sys.platform.startswith('linux'), 'Test only valid for Linux') class FindLibraryLinux(unittest.TestCase): + @classmethod + def setUpClass(cls): + import subprocess + + try: + subprocess.check_output(['gcc', '--version']) + cls.has_gcc = True + except (FileNotFoundError, subprocess.CalledProcessError): + cls.has_gcc = False + + try: + subprocess.check_output(['ld', '--version']) + cls.has_ld = True + except (FileNotFoundError, subprocess.CalledProcessError): + cls.has_ld = False + @thread_unsafe('uses setenv') def test_find_on_libpath(self): + if not self.has_gcc: + self.skipTest("gcc not available") + import subprocess import tempfile - try: - p = subprocess.Popen(['gcc', '--version'], stdout=subprocess.PIPE, - stderr=subprocess.DEVNULL) - out, _ = p.communicate() - except OSError: - raise unittest.SkipTest('gcc, needed for test, not available') with tempfile.TemporaryDirectory() as d: # create an empty temporary file srcname = os.path.join(d, 'dummy.c') @@ -118,11 +131,17 @@ def test_find_on_libpath(self): self.assertEqual(find_library(libname), 'lib%s.so' % libname) def test_find_library_with_gcc(self): + if not self.has_gcc: + self.skipTest("gcc not available") + with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \ unittest.mock.patch("ctypes.util._findLib_ld", lambda *args: None): self.assertNotEqual(find_library('c'), None) def test_find_library_with_ld(self): + if not self.has_ld: + self.skipTest("ld not available") + with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \ unittest.mock.patch("ctypes.util._findLib_gcc", lambda *args: None): self.assertNotEqual(find_library('c'), None) diff --git a/Misc/NEWS.d/next/Tests/2026-06-10-12-14-32.gh-issue-151089.grvjfj.rst b/Misc/NEWS.d/next/Tests/2026-06-10-12-14-32.gh-issue-151089.grvjfj.rst new file mode 100644 index 000000000000000..0bc7b7610613739 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2026-06-10-12-14-32.gh-issue-151089.grvjfj.rst @@ -0,0 +1,3 @@ +Fix the mocking in test_ctypes/test_find.py:test_find_library_with_gcc() where +it will call ld if gcc isn't found, and skip the tests if ld or gcc isn't +available.