Wrappers for the Cocoa frameworks on macOS
—
Python-friendly enhancements automatically added to native Objective-C classes, providing familiar Python interfaces like dictionary access, iteration support, and context managers. These enhancements make Cocoa objects more natural to use in Python code.
Enhanced methods automatically available on Foundation framework classes to provide Python-like behavior and improved usability.
def __len__(self):
"""
Returns the length of the attributed string.
Returns:
int: Number of characters in the attributed string
Example:
attr_string = NSAttributedString.alloc().initWithString_("Hello")
length = len(attr_string) # Returns 5
"""def __getitem__(self, key):
"""
Gets cached object for key using dictionary-style access.
Args:
key: Cache key
Returns:
Cached object or None if NSNull
Raises:
KeyError: If key not found in cache
Example:
cache = NSCache.alloc().init()
value = cache["user_data"] # Raises KeyError if not found
"""
def get(self, key, default=None):
"""
Gets cached object for key with optional default value.
Args:
key: Cache key
default: Value to return if key not found
Returns:
Cached object, None if NSNull, or default if not found
Example:
cache = NSCache.alloc().init()
value = cache.get("user_data", {}) # Returns {} if not found
"""
def __setitem__(self, key, value):
"""
Sets cached object for key using dictionary-style assignment.
Args:
key: Cache key
value: Object to cache (None values stored as NSNull)
Example:
cache = NSCache.alloc().init()
cache["user_data"] = user_object
cache["setting"] = None # Stored as NSNull
"""
def __delitem__(self, key):
"""
Removes cached object for key.
Args:
key: Cache key to remove
Example:
cache = NSCache.alloc().init()
del cache["old_data"]
"""
def clear(self):
"""
Removes all cached objects.
Example:
cache = NSCache.alloc().init()
cache.clear() # Empty cache
"""def __len__(self):
"""
Returns the number of objects in the hash table.
Returns:
int: Count of objects in hash table
"""
def __iter__(self):
"""
Iterates over objects in the hash table.
Yields:
Objects stored in hash table (NSNull converted to None)
"""
def add(self, value):
"""
Adds object to hash table (None values stored as NSNull).
Args:
value: Object to add to hash table
"""
def remove(self, value):
"""
Removes object from hash table.
Args:
value: Object to remove (None converted to NSNull)
"""
def __contains__(self, value):
"""
Checks if hash table contains object.
Args:
value: Object to check for (None converted to NSNull)
Returns:
bool: True if object is in hash table
"""
def pop(self):
"""
Removes and returns arbitrary object from hash table.
Returns:
Arbitrary object from hash table (NSNull converted to None)
"""
def clear(self):
"""
Removes all objects from hash table.
"""def __len__(self):
"""
Returns the count of indices in the set.
Returns:
int: Number of indices in set
"""
def __iter__(self):
"""
Iterates over indices in ascending order.
Yields:
int: Indices in the set from lowest to highest
"""
def __reversed__(self):
"""
Iterates over indices in descending order.
Yields:
int: Indices in the set from highest to lowest
"""
def __eq__(self, other):
"""
Compares index sets for equality.
Args:
other: Another NSIndexSet to compare
Returns:
bool: True if index sets contain same indices
"""
def __ne__(self, other):
"""
Compares index sets for inequality.
Args:
other: Another NSIndexSet to compare
Returns:
bool: True if index sets contain different indices
"""
def __contains__(self, value):
"""
Checks if index set contains specific index.
Args:
value (int): Index to check for
Returns:
bool: True if index is in set
"""def clear(self):
"""
Removes all indices from the set.
"""
def add(self, value):
"""
Adds index to the set.
Args:
value (int): Index to add
"""
def remove(self, value):
"""
Removes index from the set.
Args:
value (int): Index to remove
"""Classes enhanced with dictionary-like interface for key-value access to their underlying data stores.
# NSMergeConflict (mutable dictionary interface)
def __getitem__(self, key): ...
def __setitem__(self, key, value): ...
def __delitem__(self, key): ...
def __len__(self): ...
def __iter__(self): ...
def keys(self): ...
def values(self): ...
def items(self): ...
def get(self, key, default=None): ...
def clear(self): ...
def update(self, other): ...
# NSUbiquitousKeyValueStore (read-only dictionary interface)
def __getitem__(self, key): ...
def __len__(self): ...
def __iter__(self): ...
def keys(self): ...
def values(self): ...
def items(self): ...
def get(self, key, default=None): ...
# NSUserDefaults (read-only dictionary interface)
def __getitem__(self, key): ...
def __len__(self): ...
def __iter__(self): ...
def keys(self): ...
def values(self): ...
def items(self): ...
def get(self, key, default=None): ...def __getitem__(self, key):
"""
Gets locale information for key using dictionary-style access.
Args:
key: Locale information key (NSLocale constants)
Returns:
Locale-specific information for key
Example:
locale = NSLocale.currentLocale()
country = locale[NSLocaleCountryCode]
currency = locale[NSLocaleCurrencyCode]
"""def __len__(self):
"""
Returns the length of the index path.
Returns:
int: Number of indices in the path
"""
def __getitem__(self, index):
"""
Gets index at specific position in the path.
Args:
index (int): Position in the index path
Returns:
int: Index value at position
"""
def __add__(self, index):
"""
Creates new index path with additional index appended.
Args:
index (int): Index to append
Returns:
NSIndexPath: New index path with appended index
"""def __fspath__(self):
"""
Returns file system path for use with pathlib and os.path.
Returns:
str: File system path string
Example:
url = NSURL.fileURLWithPath_("/Users/user/document.txt")
path = os.path.dirname(url) # Uses __fspath__ automatically
pathlib_path = pathlib.Path(url) # Also works
"""Enhanced methods automatically available on AppKit framework classes.
def __getitem__(self, key):
"""
Gets font attribute value using dictionary-style access.
Args:
key: Font attribute key (NSFontAttributeName constants)
Returns:
Font attribute value
Raises:
KeyError: If attribute key not found
Example:
descriptor = NSFontDescriptor.fontDescriptorWithName_size_("Helvetica", 12)
family = descriptor[NSFontFamilyAttribute]
size = descriptor[NSFontSizeAttribute]
"""
def get(self, key, default=None):
"""
Gets font attribute value with optional default.
Args:
key: Font attribute key
default: Value to return if key not found
Returns:
Font attribute value or default
Example:
descriptor = NSFontDescriptor.fontDescriptorWithName_size_("Helvetica", 12)
traits = descriptor.get(NSFontTraitsAttribute, {})
weight = traits.get(NSFontWeightTrait, 0.0) if traits else 0.0
"""Classes that provide Python context manager support for managing macOS system behaviors during critical operations.
class NSDisabledAutomaticTermination:
"""
Context manager for temporarily disabling automatic application termination.
Prevents macOS from automatically terminating the application during
critical operations that must complete without interruption.
Usage:
with NSDisabledAutomaticTermination():
# Critical work that shouldn't be interrupted
save_all_documents()
perform_cleanup_operations()
"""
class NSDisabledSuddenTermination:
"""
Context manager for temporarily disabling sudden application termination.
Prevents macOS from suddenly terminating the application (e.g., during
logout or shutdown) while important operations are in progress.
Usage:
with NSDisabledSuddenTermination():
# Critical work that needs to complete
export_user_data()
synchronize_with_server()
"""Enhanced NSObject methods that provide safe selector execution with proper exception handling.
def pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_(self, sel, obj, wait):
"""
Safely executes selector on main thread with exception handling.
Args:
sel: Selector to execute
obj: Object argument to pass to selector
wait (bool): Whether to wait for completion
Returns:
Result of selector execution or None if exception occurred
"""
def pyobjc_performSelectorOnMainThread_withObject_modes_(self, sel, obj, modes):
"""
Safely executes selector on main thread in specific run loop modes.
Args:
sel: Selector to execute
obj: Object argument to pass to selector
modes: List of run loop modes for execution
Returns:
Result of selector execution or None if exception occurred
"""
def pyobjc_performSelectorOnMainThread_withObject_(self, sel, obj):
"""
Safely executes selector on main thread and returns result.
Args:
sel: Selector to execute
obj: Object argument to pass to selector
Returns:
Result of selector execution or None if exception occurred
"""
def pyobjc_performSelector_onThread_withObject_waitUntilDone_(self, sel, thread, obj, wait):
"""
Safely executes selector on specific thread with exception handling.
Args:
sel: Selector to execute
thread: NSThread to execute on
obj: Object argument to pass to selector
wait (bool): Whether to wait for completion
Returns:
Result of selector execution or None if exception occurred
"""
def pyobjc_performSelector_onThread_withObject_modes_(self, sel, thread, obj, modes):
"""
Safely executes selector on thread in specific run loop modes.
Args:
sel: Selector to execute
thread: NSThread to execute on
obj: Object argument to pass to selector
modes: List of run loop modes for execution
Returns:
Result of selector execution or None if exception occurred
"""
def pyobjc_performSelector_onThread_withObject_(self, sel, thread, obj):
"""
Safely executes selector on thread and returns result.
Args:
sel: Selector to execute
thread: NSThread to execute on
obj: Object argument to pass to selector
Returns:
Result of selector execution or None if exception occurred
"""
def pyobjc_performSelectorInBackground_withObject_(self, sel, obj):
"""
Safely executes selector in background thread.
Args:
sel: Selector to execute
obj: Object argument to pass to selector
Returns:
None (executes asynchronously)
"""
def pyobjc_performSelector_withObject_afterDelay_(self, sel, obj, delay):
"""
Safely executes selector after specified delay.
Args:
sel: Selector to execute
obj: Object argument to pass to selector
delay (float): Delay in seconds before execution
Returns:
None (executes asynchronously)
"""
def pyobjc_performSelector_withObject_afterDelay_inModes_(self, sel, obj, delay, modes):
"""
Safely executes selector after delay in specific run loop modes.
Args:
sel: Selector to execute
obj: Object argument to pass to selector
delay (float): Delay in seconds before execution
modes: List of run loop modes for execution
Returns:
None (executes asynchronously)
"""import Foundation
# NSCache with dictionary interface
cache = Foundation.NSCache.alloc().init()
cache.setName_("MyCache")
# Dictionary-style access
cache["user_session"] = user_session_data
cache["app_preferences"] = preferences_dict
# Get with default
session = cache.get("user_session", create_default_session())
# Check and remove
if "old_cache_key" in cache:
del cache["old_cache_key"]
# Clear all cached data
cache.clear()import Foundation
# NSMutableIndexSet with set interface
selected_rows = Foundation.NSMutableIndexSet.indexSet()
# Add indices like a set
selected_rows.add(0)
selected_rows.add(5)
selected_rows.add(10)
# Iterate over selected indices
for row_index in selected_rows:
print(f"Row {row_index} is selected")
# Check membership
if 5 in selected_rows:
print("Row 5 is selected")
# Set operations
other_selection = Foundation.NSIndexSet.indexSetWithIndex_(3)
selected_rows.addIndexes_(other_selection)
# Clear selection
selected_rows.clear()import Foundation
# Create hash table with strong memory semantics
hash_table = Foundation.NSHashTable.hashTableWithOptions_(
Foundation.NSPointerFunctionsStrongMemory
)
# Add items like a set
hash_table.add("item1")
hash_table.add("item2")
hash_table.add(None) # Automatically converted to NSNull
# Iterate over items
for item in hash_table:
print(f"Hash table contains: {item}") # None values converted back
# Check membership and remove
if "item1" in hash_table:
hash_table.remove("item1")
# Get arbitrary item
if len(hash_table) > 0:
random_item = hash_table.pop()
print(f"Removed item: {random_item}")import Foundation
import os
import pathlib
# NSAttributedString length
attr_string = Foundation.NSAttributedString.alloc().initWithString_("Hello, World!")
print(f"String length: {len(attr_string)}") # Uses __len__ enhancement
# NSURL path integration
file_url = Foundation.NSURL.fileURLWithPath_("/Users/user/Documents/file.txt")
# Use with standard Python path operations
directory = os.path.dirname(file_url) # Uses __fspath__ enhancement
file_path = pathlib.Path(file_url) # Also uses __fspath__
parent_dir = file_path.parent
file_exists = file_path.exists()import AppKit
# Create font descriptor
descriptor = AppKit.NSFontDescriptor.fontDescriptorWithName_size_("Helvetica Neue", 14)
# Dictionary-style access to attributes
family_name = descriptor[AppKit.NSFontFamilyAttribute]
font_size = descriptor[AppKit.NSFontSizeAttribute]
# Safe access with defaults
traits = descriptor.get(AppKit.NSFontTraitsAttribute, {})
if traits:
weight = traits.get(AppKit.NSFontWeightTrait, 0.0)
slant = traits.get(AppKit.NSFontSlantTrait, 0.0)
print(f"Font weight: {weight}, slant: {slant}")
# Create modified descriptor
bold_descriptor = descriptor.fontDescriptorWithSymbolicTraits_(
AppKit.NSFontBoldTrait
)import Foundation
# Disable automatic termination during critical operations
with Foundation.NSDisabledAutomaticTermination():
# Perform critical work that shouldn't be interrupted
backup_user_data()
synchronize_settings()
cleanup_temporary_files()
# Automatic termination re-enabled automatically
# Disable sudden termination during data operations
with Foundation.NSDisabledSuddenTermination():
# Ensure these operations complete even during shutdown
save_document_changes()
commit_database_transaction()
# Sudden termination re-enabled automaticallyimport Foundation
import AppKit
# Create string object
string_obj = Foundation.NSString.stringWithString_("hello world")
# Safe execution on main thread
uppercased = string_obj.pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_(
"uppercaseString",
None, # no argument needed
True # wait for result
)
print(f"Uppercased: {uppercased}")
# Background execution with error handling
def background_processing():
result = string_obj.pyobjc_performSelectorInBackground_withObject_(
"capitalizedString",
None
)
# Result will be None if executed in background
# Delayed execution
string_obj.pyobjc_performSelector_withObject_afterDelay_(
"uppercaseString",
None,
2.0 # Execute after 2 seconds
)import Foundation
# Get current locale
locale = Foundation.NSLocale.currentLocale()
# Dictionary-style access to locale information
country_code = locale[Foundation.NSLocaleCountryCode]
language_code = locale[Foundation.NSLocaleLanguageCode]
currency_code = locale[Foundation.NSLocaleCurrencyCode]
currency_symbol = locale[Foundation.NSLocaleCurrencySymbol]
print(f"Country: {country_code}")
print(f"Language: {language_code}")
print(f"Currency: {currency_code} ({currency_symbol})")
# Create specific locale and access its properties
us_locale = Foundation.NSLocale.localeWithLocaleIdentifier_("en_US")
us_currency = us_locale[Foundation.NSLocaleCurrencyCode] # "USD"import Foundation
# Create index path for table view
section_0_row_5 = Foundation.NSIndexPath.indexPathForRow_inSection_(5, 0)
# Enhanced operations
path_length = len(section_0_row_5) # Returns 2 (section and row)
section = section_0_row_5[0] # Get section index
row = section_0_row_5[1] # Get row index
# Create new path by adding index
extended_path = section_0_row_5 + 3 # Adds index 3 to path
print(f"Original path length: {path_length}")
print(f"Section: {section}, Row: {row}")
print(f"Extended path: {extended_path}")All these enhancements are applied automatically when the respective framework modules are imported:
import Foundation # Automatically applies Foundation enhancements
import AppKit # Automatically applies AppKit enhancements
# Enhancements are immediately available on all instances
cache = Foundation.NSCache.alloc().init()
cache["key"] = "value" # Dictionary-style access works immediately
descriptor = AppKit.NSFontDescriptor.fontDescriptorWithName_size_("Arial", 12)
family = descriptor[AppKit.NSFontFamilyAttribute] # Dictionary access worksThe enhancements provide a more Pythonic interface to Cocoa objects while maintaining full compatibility with standard Objective-C methods and patterns.
Install with Tessl CLI
npx tessl i tessl/pypi-pyobjc-framework-cocoa