CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyobjc-core

Python-to-Objective-C bridge providing seamless interoperability between Python and Objective-C programming languages on macOS systems.

Pending
Overview
Eval results
Files

pyobjctools.mddocs/

PyObjCTools Utilities

Essential utilities for Key-Value Coding, signal handling, and testing support that enhance PyObjC development workflows and provide additional functionality for macOS app development.

Capabilities

Key-Value Coding Support

Functions for accessing object attributes using Key-Value Coding conventions, enabling flexible property access patterns and keypath-based operations.

def getKey(obj, key):
    """
    Get attribute using Key-Value Coding semantics.
    
    Args:
        obj: Object to query
        key (str): Attribute name to retrieve
        
    Returns:
        Value of the specified attribute, following KVC lookup rules
        
    Uses KVC-compliant lookup order:
    1. Direct attribute access
    2. Getter method (getKey, key, isKey)
    3. Dictionary-style access if supported
    """

def setKey(obj, key, value):
    """
    Set attribute using Key-Value Coding semantics.
    
    Args:
        obj: Object to modify
        key (str): Attribute name to set
        value: Value to assign
        
    Sets the specified attribute following KVC assignment rules:
    1. Setter method (setKey:)
    2. Direct attribute assignment
    3. Dictionary-style assignment if supported
    """

def getKeyPath(obj, keypath):
    """
    Get nested attribute using keypath notation.
    
    Args:
        obj: Root object to query
        keypath (str): Dot-separated path like "user.profile.name"
        
    Returns:
        Value at the end of the keypath
        
    Traverses object hierarchy following the keypath, using KVC
    semantics at each level.
    """

def setKeyPath(obj, keypath, value):
    """
    Set nested attribute using keypath notation.
    
    Args:
        obj: Root object to modify  
        keypath (str): Dot-separated path like "user.profile.name"
        value: Value to assign at the keypath destination
        
    Sets the value at the specified keypath, creating intermediate
    objects if necessary and possible.
    """

Signal Handling Utilities

Functions for managing signal handling in PyObjC applications, useful for debugging and crash reporting.

def dumpStackOnFatalSignal():
    """
    Enable Python stack dump on fatal signals.
    
    Configures signal handlers to dump Python stack traces
    when fatal signals (SIGSEGV, SIGBUS, etc.) are received.
    Useful for debugging crashes in PyObjC applications.
    """

def resetFatalSignals():
    """
    Reset fatal signal handling to system defaults.
    
    Removes custom signal handlers installed by dumpStackOnFatalSignal()
    and restores default system signal handling behavior.
    """

Mach Signal Support

Platform-specific signal handling for advanced debugging scenarios.

def getsignal(signum):
    """
    Get Mach signal handler for specified signal.
    
    Args:
        signum (int): Signal number
        
    Returns:
        Current signal handler or None
    """

def signal(signum, handler):
    """
    Set Mach signal handler.
    
    Args:
        signum (int): Signal number to handle
        handler: Function to call when signal is received
        
    Returns:
        Previous signal handler
    """

Test Support Framework

Comprehensive testing utilities for PyObjC development (internal use).

The TestSupport module provides extensive testing infrastructure including:

  • Test case base classes for PyObjC-specific testing
  • Helper functions for Objective-C method testing
  • Exception testing utilities
  • Memory management testing support
  • Cross-platform compatibility helpers

Note: TestSupport is marked as internal/unsupported for external use.

Usage Examples:

import objc
from PyObjCTools.KeyValueCoding import getKey, setKey, getKeyPath, setKeyPath
from PyObjCTools.Signals import dumpStackOnFatalSignal, resetFatalSignals

# Key-Value Coding examples
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.profile = {"email": "person@example.com"}

class Company:
    def __init__(self):
        self.employees = []
    
    def addEmployee(self, person):
        self.employees.append(person)

# Basic KVC usage
person = Person("John Doe", 30)
name = getKey(person, "name")  # "John Doe"
setKey(person, "age", 31)      # Sets age to 31

# Keypath usage for nested access
company = Company()
employee = Person("Jane Smith", 25)
company.addEmployee(employee)

# Access nested attributes with keypaths
email = getKeyPath(company, "employees.0.profile.email")  # Works if properly implemented
# Note: List indexing in keypaths requires proper KVC implementation

# Practical KVC usage with Objective-C objects
ns_dict = objc.lookUpClass("NSMutableDictionary").dictionary()
setKey(ns_dict, "title", "My Application")
setKey(ns_dict, "version", "1.0")

title = getKey(ns_dict, "title")    # "My Application"
version = getKey(ns_dict, "version")  # "1.0"

# Signal handling for debugging
def setup_crash_reporting():
    """Enable crash reporting for debugging."""
    dumpStackOnFatalSignal()
    print("Crash reporting enabled - stack traces will be dumped on fatal signals")

def disable_crash_reporting():
    """Disable crash reporting."""
    resetFatalSignals()
    print("Crash reporting disabled")

# Use in development/testing
setup_crash_reporting()

# Your PyObjC application code here...
# If a crash occurs, Python stack trace will be dumped

# Clean up when needed
disable_crash_reporting()

Integration with Cocoa Patterns

Key-Value Coding integrates seamlessly with Cocoa design patterns:

# KVC with Cocoa bindings-style access
class ModelObject:
    def __init__(self):
        self.properties = {}
    
    def valueForKey_(self, key):
        """NSKeyValueCoding protocol method."""
        return getKey(self, key)
    
    def setValue_forKey_(self, value, key):
        """NSKeyValueCoding protocol method.""" 
        setKey(self, key, value)

# Observer pattern with KVC
class Observer:
    def observeValueForKeyPath_ofObject_change_context_(self, keypath, obj, change, context):
        """KVO observer method."""
        new_value = getKeyPath(obj, keypath)
        print(f"Property {keypath} changed to: {new_value}")

# Using with Core Data-style keypaths
def query_data_with_keypath(objects, keypath):
    """Extract values using keypath from object collection."""
    results = []
    for obj in objects:
        try:
            value = getKeyPath(obj, keypath)
            results.append(value)
        except:
            results.append(None)
    return results

# Example: Extract all employee names
employees = [Person("Alice", 28), Person("Bob", 32), Person("Carol", 29)]
names = query_data_with_keypath(employees, "name")  # ["Alice", "Bob", "Carol"]

Best Practices

  • Error Handling: Always handle potential KeyError exceptions with KVC operations
  • Performance: KVC has overhead; use direct attribute access for performance-critical code
  • Debugging: Enable signal handling during development for better crash diagnostics
  • Testing: Use TestSupport utilities for comprehensive PyObjC testing (when available)

Install with Tessl CLI

npx tessl i tessl/pypi-pyobjc-core

docs

bridge-registration.md

class-enhancement.md

core-bridge.md

framework-loading.md

index.md

interface-builder.md

method-decorators.md

properties-accessors.md

protocol-support.md

pyobjctools.md

tile.json