Python-to-Objective-C bridge providing seamless interoperability between Python and Objective-C programming languages on macOS systems.
—
Utilities for loading Objective-C frameworks and libraries dynamically, including BridgeSupport file parsing, lazy module loading, and framework introspection capabilities.
Functions for locating and loading frameworks and dynamic libraries using dyld semantics.
def dyld_framework(filename, framework_name, version=None):
"""
Find framework using dyld semantics.
Args:
filename (str): Framework filename
framework_name (str): Name of the framework
version (str, optional): Specific version to load
Returns:
str: Path to the framework or None if not found
"""
def dyld_library(filename, libname):
"""
Find dynamic library using dyld semantics.
Args:
filename (str): Library filename
libname (str): Library name
Returns:
str: Path to the library or None if not found
"""
def dyld_find(filename):
"""
Generic dyld locator function for libraries and frameworks.
Args:
filename (str): File to locate using dyld search paths
Returns:
str: Full path to located file or None if not found
"""Functions for obtaining framework metadata and path information.
def pathForFramework(path):
"""
Get the full path for a framework.
Args:
path (str): Framework path or name
Returns:
str: Full framework path
"""
def infoForFramework(filename):
"""
Get framework metadata information.
Args:
filename (str): Framework filename or path
Returns:
dict: Framework information including version, identifier, etc.
"""Functions for parsing BridgeSupport files and initializing framework wrappers.
def initFrameworkWrapper(frameworkName, frameworkPath, frameworkIdentifier,
isIndirect=False, frameworkDict=None,
frameworkGlobals=None, inline_list=None,
initialdict=None, metadict=None):
"""
Initialize a framework wrapper with BridgeSupport data.
Args:
frameworkName (str): Name of the framework
frameworkPath (str): Path to framework bundle
frameworkIdentifier (str): Framework bundle identifier
isIndirect (bool): Whether framework is loaded indirectly
frameworkDict (dict, optional): Framework-specific data
frameworkGlobals (dict, optional): Global symbols
inline_list (list, optional): Inline function definitions
initialdict (dict, optional): Initial symbol dictionary
metadict (dict, optional): Metadata dictionary
Returns:
Module-like object providing access to framework APIs
"""
def parseBridgeSupport(xmldata, globals, frameworkName, dylib_path=None, inlineTab=None):
"""
Parse BridgeSupport XML files to extract API metadata.
Args:
xmldata (bytes): BridgeSupport XML data
globals (dict): Global namespace to populate
frameworkName (str): Name of the framework being parsed
dylib_path (str, optional): Path to dynamic library
inlineTab (dict, optional): Inline function table
Populates the globals dictionary with parsed API definitions.
"""Classes and functions for implementing lazy framework loading to improve startup performance.
class ObjCLazyModule:
"""
Lazy module loading class for frameworks.
Delays actual framework loading until first access to minimize
startup time and memory usage.
"""
def createFrameworkDirAndGetattr():
"""
Framework directory creation utility for lazy loading.
Creates framework directory structures and handles attribute
access for lazy-loaded framework modules.
"""Usage Examples:
import objc
from objc import dyld_framework, pathForFramework, initFrameworkWrapper
# Find and load a framework
framework_path = dyld_framework("AppKit", "AppKit")
if framework_path:
print(f"Found AppKit at: {framework_path}")
# Get framework information
info = infoForFramework("Foundation")
print(f"Foundation info: {info}")
# Load a custom framework
custom_path = dyld_framework("MyFramework", "MyFramework", version="1.0")
# Using lazy loading for better performance
class LazyFrameworkLoader:
def __init__(self, framework_name):
self.framework_name = framework_name
self._framework = None
@property
def framework(self):
if self._framework is None:
path = dyld_framework(self.framework_name, self.framework_name)
if path:
self._framework = initFrameworkWrapper(
self.framework_name,
path,
f"com.apple.{self.framework_name.lower()}"
)
return self._framework
# Lazy load Core Graphics framework
cg_loader = LazyFrameworkLoader("CoreGraphics")
# Framework is only loaded when first accessed
cg_framework = cg_loader.frameworkCommon patterns for framework loading and integration:
# Standard framework loading
import objc
# Load system frameworks (these are typically auto-loaded)
# Foundation and AppKit are loaded automatically with PyObjC
# Manual framework loading for less common frameworks
try:
# Try to find and load Metal framework
metal_path = objc.dyld_framework("Metal", "Metal")
if metal_path:
# Initialize Metal framework wrapper
metal = objc.initFrameworkWrapper(
"Metal",
metal_path,
"com.apple.Metal"
)
# Now can use Metal APIs
print("Metal framework loaded successfully")
except Exception as e:
print(f"Failed to load Metal framework: {e}")
# Loading private or third-party frameworks
custom_framework_path = "/Library/Frameworks/MyFramework.framework"
custom_info = objc.infoForFramework(custom_framework_path)
if custom_info:
custom_framework = objc.initFrameworkWrapper(
"MyFramework",
custom_framework_path,
custom_info.get("identifier", "com.example.MyFramework")
)Framework loading enables access to the complete macOS development ecosystem:
Install with Tessl CLI
npx tessl i tessl/pypi-pyobjc-core