teams-bots/write-message/venv/lib/python3.10/site-packages/objc/_dyld.py

144 lines
4.1 KiB
Python

"""
dyld emulation
"""
__all__ = [
"dyld_framework",
"dyld_library",
"dyld_find",
"pathForFramework",
"infoForFramework",
]
import os
from objc._framework import infoForFramework
from objc._objc import _dyld_shared_cache_contains_path
# These are the defaults as per man dyld(1)
#
DEFAULT_FRAMEWORK_FALLBACK = ":".join(
[
os.path.expanduser("~/Library/Frameworks"),
"/Library/Frameworks",
"/Network/Library/Frameworks",
"/System/Library/Frameworks",
]
)
DEFAULT_LIBRARY_FALLBACK = ":".join(
[os.path.expanduser("~/lib"), "/usr/local/lib", "/lib", "/usr/lib"]
)
def ensure_unicode(s):
"""Not all of PyObjC understands unicode paths very well yet"""
if isinstance(s, bytes):
return s.decode("utf-8")
return s
def inject_suffixes(iterator):
suffix = ensure_unicode(os.environ.get("DYLD_IMAGE_SUFFIX", None))
if suffix is None:
return iterator
def _inject(iterator=iterator, suffix=suffix):
for path in iterator:
if path.endswith(".dylib"):
yield path[:-6] + suffix + ".dylib"
else:
yield path + suffix
yield path
return _inject()
def dyld_framework(filename, framework_name, version=None):
"""Find a framework using dyld semantics"""
filename = ensure_unicode(filename)
framework_name = ensure_unicode(framework_name)
version = ensure_unicode(version)
def _search():
spath = ensure_unicode(os.environ.get("DYLD_FRAMEWORK_PATH", None))
if spath is not None:
for path in spath.split(":"):
if version:
yield os.path.join(
path,
framework_name + ".framework",
"Versions",
version,
framework_name,
)
else:
yield os.path.join(
path, framework_name + ".framework", framework_name
)
yield filename
spath = ensure_unicode(
os.environ.get("DYLD_FALLBACK_FRAMEWORK_PATH", DEFAULT_FRAMEWORK_FALLBACK)
)
for path in spath.split(":"):
if version:
yield os.path.join(
path,
framework_name + ".framework",
"Versions",
version,
framework_name,
)
else:
yield os.path.join(path, framework_name + ".framework", framework_name)
for f in inject_suffixes(_search()):
if _dyld_shared_cache_contains_path(f):
return f
if os.path.exists(f):
return f
# raise ..
raise ImportError(f"Framework {framework_name} could not be found")
def dyld_library(filename, libname):
"""Find a dylib using dyld semantics"""
filename = ensure_unicode(filename)
libname = ensure_unicode(libname)
def _search():
spath = ensure_unicode(os.environ.get("DYLD_LIBRARY_PATH", None))
if spath is not None:
for path in spath.split(":"):
yield os.path.join(path, libname)
yield filename
spath = ensure_unicode(
os.environ.get("DYLD_FALLBACK_LIBRARY_PATH", DEFAULT_LIBRARY_FALLBACK)
)
for path in spath.split(":"):
yield os.path.join(path, libname)
for f in inject_suffixes(_search()):
if _dyld_shared_cache_contains_path(f):
return f
if os.path.exists(f):
return f
raise ValueError(f"dylib {filename} could not be found")
def dyld_find(filename):
"""Generic way to locate a dyld framework or dyld"""
filename = os.path.realpath(filename)
res = infoForFramework(filename)
if res:
framework_loc, framework_name, version = res
return dyld_framework(filename, framework_name, version)
else:
return dyld_library(filename, os.path.basename(filename))
def pathForFramework(path):
fpath, name, version = infoForFramework(dyld_find(path))
return os.path.join(fpath, name + ".framework")