From 24f2513ad3cdb5d990d4b17e8858e7e64d1aade9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= Date: Thu, 20 Aug 2026 15:48:19 +0200 Subject: [PATCH 1/2] Fall back to loading the ObjC runtime by name ctypes.util.find_library() resolves a system library through the dyld shared cache, which requires _dyld_shared_cache_contains_path(). Modules/_ctypes/ callproc.c guards that symbol with __builtin_available(iOS 14.0), so on iOS 13 - the oldest release CPython's iOS support targets - find_library() returns None for any library that exists only in the cache, and importing _ios_support fails outright rather than degrading. dyld resolves a bare library name against the cache by itself, so use that when find_library() comes up empty. A genuine load failure is still reported as ImportError. --- Lib/_ios_support.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Lib/_ios_support.py b/Lib/_ios_support.py index 20467a7c2bcaeb0..cc51aa504916e36 100644 --- a/Lib/_ios_support.py +++ b/Lib/_ios_support.py @@ -10,12 +10,15 @@ else: # ctypes is available. Load the ObjC library, and wrap the objc_getClass, # sel_registerName methods - lib = util.find_library("objc") - if lib is None: - # Failed to load the objc library - raise ImportError("ObjC runtime library couldn't be loaded") + # find_library() resolves a system library through the dyld shared cache, + # which needs _dyld_shared_cache_contains_path(); that is unavailable before + # iOS 14, so fall back to the bare name, which dyld resolves by itself. + lib = util.find_library("objc") or "libobjc.dylib" - objc = cdll.LoadLibrary(lib) + try: + objc = cdll.LoadLibrary(lib) + except OSError: + raise ImportError("ObjC runtime library couldn't be loaded") objc.objc_getClass.restype = c_void_p objc.objc_getClass.argtypes = [c_char_p] objc.sel_registerName.restype = c_void_p From 1f1c09db5c0a4555db299404753f03f20c6cacff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= Date: Thu, 20 Aug 2026 15:50:49 +0200 Subject: [PATCH 2/2] Add NEWS entry --- .../Library/2026-08-20-13-50-49.gh-issue-156112.yEcma8.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-08-20-13-50-49.gh-issue-156112.yEcma8.rst diff --git a/Misc/NEWS.d/next/Library/2026-08-20-13-50-49.gh-issue-156112.yEcma8.rst b/Misc/NEWS.d/next/Library/2026-08-20-13-50-49.gh-issue-156112.yEcma8.rst new file mode 100644 index 000000000000000..ba92df3c5cb6c1d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-20-13-50-49.gh-issue-156112.yEcma8.rst @@ -0,0 +1,4 @@ +:mod:`!_ios_support` no longer fails to import when +:func:`ctypes.util.find_library` cannot resolve the ObjC runtime through the +dyld shared cache, as is the case on iOS 13. The runtime is now loaded by name, +which dyld resolves against the cache directly.