{"id":6101,"library":"pyobjc-framework-exceptionhandling","title":"PyObjC Framework: ExceptionHandling","description":"This library provides Python wrappers for the macOS `ExceptionHandling` framework, enabling Python applications to interact with Objective-C's exception mechanisms. It's part of the larger PyObjC bridge, which allows full-featured Cocoa applications to be written in pure Python. PyObjC is actively maintained, with new versions typically released to align with macOS SDK updates and Python version support. The current version is 12.1.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","objective-c","cocoa","framework","exception-handling","pyobjc"],"install":[{"cmd":"pip install pyobjc-framework-exceptionhandling","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"This package provides the core bridging functionality between Python and Objective-C, which is essential for all pyobjc-framework-* wrappers.","package":"pyobjc-core"}],"imports":[{"note":"Framework wrappers are imported as top-level modules named after the framework, not as attributes of the `objc` module.","wrong":"from objc import ExceptionHandling","symbol":"ExceptionHandling","correct":"import ExceptionHandling"}],"quickstart":{"code":"import objc\nfrom Foundation import NSObject, NSLog\n\n# Enable verbose logging for PyObjC to see detailed stack traces\n# when exceptions cross the Python/Objective-C boundary.\n# This is key for understanding issues related to ExceptionHandling.\nobjc.setVerbose(True)\n\nclass MyPythonException(Exception):\n    \"\"\"A custom Python exception to demonstrate bridging.\"\"\"\n    pass\n\n# Define an Objective-C class (via Python subclassing NSObject)\nclass MyObjCClass(NSObject):\n    def init(self):\n        self = super().init()\n        if self:\n            NSLog(\"MyObjCClass initialized in Python\")\n        return self\n\n    def triggerPythonException_(self, arg):\n        \"\"\"An Objective-C callable method that might raise a Python exception.\"\"\"\n        NSLog(\"Objective-C calling Python method to trigger exception with arg: %@\", arg)\n        if arg == \"error\":\n            raise MyPythonException(\"An error occurred in Python!\")\n        return \"Python successfully processed: \" + arg\n\nif __name__ == \"__main__\":\n    obj = MyObjCClass.alloc().init()\n\n    # Example 1: Call method that triggers a Python exception\n    print(\"\\n--- Attempting to trigger an exception ---\")\n    try:\n        # When Python raises an exception, PyObjC translates it into an\n        # Objective-C exception. If caught back in Python, it manifests as objc.error.\n        result = obj.triggerPythonException_(\"error\")\n        print(f\"Result (should not be reached): {result}\")\n    except objc.error as e:\n        print(f\"Caught Objective-C error (originally Python exception): {e}\")\n    except MyPythonException as e: # This would not be caught directly here\n        print(f\"Caught Python exception directly: {e}\")\n\n    # Example 2: Call method that succeeds\n    print(\"\\n--- Attempting a successful call ---\")\n    result = obj.triggerPythonException_(\"success\")\n    print(f\"Successful call result: {result}\")\n","lang":"python","description":"This quickstart demonstrates how PyObjC bridges Python exceptions when Objective-C code calls into Python. By setting `objc.setVerbose(True)`, you can observe more detailed Python stack traces in the console when exceptions cross the language boundary. The `ExceptionHandling` framework itself is low-level, so this example focuses on PyObjC's general exception bridging behavior, which is the primary user-facing aspect of exception interaction."},"warnings":[{"fix":"Upgrade your Python environment to Python 3.10 or newer.","message":"PyObjC 12.0 dropped support for Python 3.9, and PyObjC 11.0 dropped support for Python 3.8. Ensure your Python version meets the `pyobjc-framework-exceptionhandling` requirements (>=3.10).","severity":"breaking","affected_versions":">=11.0"},{"fix":"Review Python classes subclassing Objective-C classes. If `__new__` is user-defined, `__init__` can be used. If `__new__` is implicitly provided by PyObjC, avoid using `__init__` on those classes.","message":"Versions 10.3 and 10.3.1 introduced changes in how `__init__` and `__new__` methods are handled in Python subclasses of Objective-C classes, particularly when a user-defined `__new__` is present. Code relying on the PyObjC-provided `__new__` can no longer use `__init__`.","severity":"breaking","affected_versions":">=10.3"},{"fix":"While this change should primarily affect advanced use cases, be mindful of reference counting if you are manually managing object lifetimes or observing unexpected deallocations, especially around `init` methods.","message":"PyObjC 11.1 aligned with `clang`'s Automatic Reference Counting (ARC) documentation for initializer methods (those in the 'init' family). PyObjC now correctly models that these methods steal a reference to `self` and return a new one, which might alter reference counting behavior in complex scenarios.","severity":"gotcha","affected_versions":">=11.1"},{"fix":"Use decorators or `try...except` blocks in Python methods called from Objective-C to catch and log exceptions internally, preventing them from propagating across the bridge.","message":"Objective-C code is generally not written with Python-style exception safety in mind. It is advisable to avoid raising Python exceptions that will cross the boundary from Python to Objective-C, as this can lead to unexpected program termination or unstable behavior.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Add `import objc; objc.setVerbose(True)` early in your application's lifecycle for improved debugging visibility.","message":"For debugging exceptions that cross the Python/Objective-C boundary, call `objc.setVerbose(True)`. This will cause PyObjC to print Python stack traces to `stderr` when translating exceptions.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}