Skip to content

_ios_support fails to import on iOS 13, where find_library() cannot query the dyld shared cache #156112

Description

@clementperon

Bug report

Bug description:

Lib/_ios_support.py raises ImportError at module import if ctypes.util.find_library("objc") returns None:

lib = util.find_library("objc")
if lib is None:
    # Failed to load the objc library
    raise ImportError("ObjC runtime library couldn't be loaded")

On Apple platforms the ObjC runtime exists only in the dyld shared cache, not as a file on disk, so find_library() cannot resolve it by a filesystem check. ctypes.macholib.dyld.dyld_find() handles that by falling back to _dyld_shared_cache_contains_path():

if os.path.isfile(path):
    return path
try:
    if _dyld_shared_cache_contains_path(path):
        return path
except NotImplementedError:
    pass

That symbol is availability-guarded at runtime in Modules/_ctypes/callproc.c:

#define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \
    __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)

so on iOS 13 the probe raises NotImplementedError, dyld_find() gives up, find_library("objc") returns None, and importing _ios_support fails outright. IPHONEOS_DEPLOYMENT_TARGET defaults to 13.0 in configure.ac, so this is inside the range iOS support targets, and it takes platform.platform(), platform.ios_ver() and anything else built on _ios_support down with it.

dyld resolves a bare library name against the shared cache by itself, so the runtime is loadable even when find_library() cannot name a path for it. On macOS, where the same cache mechanism applies:

>>> from ctypes import cdll, util; import os
>>> util.find_library("objc")
'/usr/lib/libobjc.dylib'
>>> os.path.isfile("/usr/lib/libobjc.dylib")
False
>>> cdll.LoadLibrary("libobjc.dylib")
<CDLL 'libobjc.dylib', handle ... at ...>

The suggested fix is to fall back to the bare name when find_library() comes up empty, and to keep reporting a genuine load failure as ImportError. With find_library patched to return None, the module then loads the runtime and objc_getClass(b"NSProcessInfo") works.

A caveat on the evidence: I do not have an iOS 13 device or simulator runtime, so I have not reproduced the import failure on-device — the chain above is read from the source. The fallback itself is verified, as shown.

CPython versions tested on:

CPython main

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-iosstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions