Python-to-Objective-C bridge providing seamless interoperability between Python and Objective-C programming languages on macOS systems.
—
Functions for enhancing Objective-C classes with additional Python functionality, registering Abstract Base Classes, and adding convenience methods for better Python integration.
Functions for adding convenience methods and Python functionality to existing Objective-C classes.
def addConvenienceForClass(classname, methods):
"""
Add Python methods to an Objective-C class.
Args:
classname (str): Name of the Objective-C class to enhance
methods (dict): Dictionary mapping method names to functions
Enhances the specified class with additional Python methods
that integrate seamlessly with existing Objective-C functionality.
"""Function for registering Python Abstract Base Classes with Objective-C classes for better type checking and polymorphism.
def registerABCForClass(classname, *abc_class):
"""
Register Abstract Base Class for an Objective-C class.
Args:
classname (str): Name of the Objective-C class
*abc_class: One or more ABC classes to register
Enables isinstance() and issubclass() checks between
Objective-C classes and Python ABCs.
"""Functions for controlling method availability and argument handling.
def registerUnavailableMethod(classname, selector):
"""
Mark a selector as unavailable on a class.
Args:
classname (str): Name of the Objective-C class
selector (str): Selector to mark as unavailable
Prevents access to specific methods that may be inappropriate
or dangerous when called from Python.
"""
def registerNewKeywords(classname, keywords, methodname):
"""
Register keyword arguments for __new__ method.
Args:
classname (str): Name of the Objective-C class
keywords (list): List of keyword argument names
methodname (str): Method name for initialization
Enables Python-style keyword arguments for object creation.
"""
def registerNewKeywordsFromSelector(classname, selector):
"""
Generate keyword arguments from selector signature.
Args:
classname (str): Name of the Objective-C class
selector (str): Selector to analyze for keyword generation
Automatically creates keyword arguments based on selector names.
"""Functions for adding Python-style convenience methods to Objective-C collection classes.
def addConvenienceForBasicMapping(name, readonly=False):
"""
Add mapping convenience methods to a class.
Args:
name (str): Class name to enhance
readonly (bool): Whether mapping should be read-only
Adds Python dict-like methods (__getitem__, __setitem__, etc.)
to Objective-C classes that represent key-value collections.
"""
def addConvenienceForBasicSequence(name, readonly=False):
"""
Add sequence convenience methods to a class.
Args:
name (str): Class name to enhance
readonly (bool): Whether sequence should be read-only
Adds Python list-like methods (__getitem__, __setitem__, __len__, etc.)
to Objective-C classes that represent ordered collections.
"""Usage Examples:
import objc
from objc import (addConvenienceForClass, registerABCForClass,
registerUnavailableMethod, addConvenienceForBasicSequence)
from collections.abc import Sequence, MutableSequence
# Add convenience methods to NSString
def python_split(self, separator=" "):
"""Add Python-style split method to NSString."""
return str(self).split(separator)
def python_strip(self):
"""Add Python-style strip method to NSString."""
return str(self).strip()
addConvenienceForClass("NSString", {
"split": python_split,
"strip": python_strip
})
# Now NSString instances have Python-style methods
ns_string = objc.lookUpClass("NSString").stringWithString_(" hello world ")
parts = ns_string.split(" ") # ['', '', 'hello', 'world', '', '']
clean = ns_string.strip() # "hello world"
# Register ABC for better type checking
registerABCForClass("NSArray", Sequence)
registerABCForClass("NSMutableArray", MutableSequence)
# Now isinstance checks work
ns_array = objc.lookUpClass("NSArray").arrayWithObjects_("a", "b", "c")
print(isinstance(ns_array, Sequence)) # True
ns_mutable = objc.lookUpClass("NSMutableArray").arrayWithObjects_("x", "y")
print(isinstance(ns_mutable, MutableSequence)) # True
# Mark dangerous methods as unavailable
registerUnavailableMethod("NSFileManager", "removeItemAtPath:error:")
# Add sequence convenience to custom collection class
addConvenienceForBasicSequence("MyCustomArray", readonly=False)
# Register keyword arguments for cleaner object creation
registerNewKeywords("NSRect", ["x", "y", "width", "height"], "__new__")
# Now can create with keywords (if properly implemented)
# rect = NSRect(x=10, y=20, width=100, height=50)Common patterns for enhancing Objective-C classes:
# Pattern 1: Adding Python idioms to Objective-C collections
def enhance_nsarray():
def python_contains(self, item):
"""Add 'in' operator support."""
return self.containsObject_(item)
def python_iter(self):
"""Add iterator support."""
for i in range(self.count()):
yield self.objectAtIndex_(i)
addConvenienceForClass("NSArray", {
"__contains__": python_contains,
"__iter__": python_iter
})
enhance_nsarray()
# Now NSArray works more like Python lists
ns_array = objc.lookUpClass("NSArray").arrayWithObjects_("a", "b", "c")
print("b" in ns_array) # True
for item in ns_array: # Iteration works
print(item)
# Pattern 2: Adding utility methods
def enhance_nsurl():
def to_path(self):
"""Convert NSURL to pathlib.Path."""
from pathlib import Path
return Path(self.path())
def read_text(self):
"""Read URL content as text."""
data = objc.lookUpClass("NSData").dataWithContentsOfURL_(self)
if data:
return str(data, 'utf-8')
return None
addConvenienceForClass("NSURL", {
"to_path": to_path,
"read_text": read_text
})
enhance_nsurl()
# Usage with enhanced NSURL
file_url = objc.lookUpClass("NSURL").fileURLWithPath_("/tmp/test.txt")
path = file_url.to_path() # Returns pathlib.Path object
content = file_url.read_text() # Read file contentInstall with Tessl CLI
npx tessl i tessl/pypi-pyobjc-core