{"id":6150,"library":"pyobjc-framework-opendirectory","title":"PyObjC OpenDirectory Framework","description":"PyObjC is a bridge between Python and Objective-C, enabling Python scripts to interact with Objective-C libraries, most notably macOS Cocoa frameworks. The `pyobjc-framework-opendirectory` package provides Python wrappers for the OpenDirectory and CFOpenDirectory frameworks on macOS. The project maintains an active and sustainable release cadence, typically aligning 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","framework","opendirectory","pyobjc","objective-c"],"install":[{"cmd":"pip install pyobjc-framework-opendirectory","lang":"bash","label":"Install pyobjc-framework-opendirectory"}],"dependencies":[{"reason":"This package is a wrapper for a specific macOS framework, requiring the core PyObjC bridge.","package":"pyobjc-core","optional":false}],"imports":[{"note":"The bindings for the OpenDirectory framework are accessed directly through the `OpenDirectory` package.","symbol":"OpenDirectory","correct":"import OpenDirectory"}],"quickstart":{"code":"import OpenDirectory\n\n# A simple quickstart for OpenDirectory.\n# This demonstrates importing the framework and accessing a default session.\n# More complex operations would involve querying specific nodes, users, or groups.\n\ndef get_opendirectory_info():\n    \"\"\"\n    Retrieves information from the default OpenDirectory session.\n    \"\"\"\n    print(\"Attempting to get default OpenDirectory session...\")\n    try:\n        # Access the shared default session\n        session = OpenDirectory.ODSession.defaultSession()\n        if session:\n            print(f\"Successfully obtained default OpenDirectory session: {session}\")\n\n            # Example: list all node names\n            # ODSession.nodeNamesAndReturnError_ is a common way to get node names.\n            # The second argument is for an NSError object, passed as None from Python.\n            node_names, error = session.nodeNamesAndReturnError_(None)\n\n            if node_names:\n                print(f\"Available OpenDirectory nodes: {', '.join(node_names)}\")\n            elif error:\n                print(f\"Error listing nodes: {error.localizedDescription()}\")\n            else:\n                print(\"No OpenDirectory nodes found.\")\n            return session\n        else:\n            print(\"Failed to obtain default OpenDirectory session.\")\n            return None\n    except Exception as e:\n        print(f\"An error occurred: {e}\")\n        return None\n\nif __name__ == \"__main__\":\n    get_opendirectory_info()\n","lang":"python","description":"This quickstart demonstrates how to import the `OpenDirectory` framework and retrieve the default OpenDirectory session on macOS. It then attempts to list the available directory node names, showcasing basic interaction with the framework."},"warnings":[{"fix":"Ensure your Python version is compatible with the PyObjC version you are installing. PyObjC 12.1 requires Python >=3.10. Always check `requires_python` on PyPI or the PyObjC changelog for specific version requirements.","message":"PyObjC frequently drops support for older Python versions to align with macOS SDKs and Python's own EOL cycle. For instance, PyObjC 12.0 dropped support for Python 3.9, and PyObjC 11.0 dropped Python 3.8.","severity":"breaking","affected_versions":"11.0, 12.0"},{"fix":"Review code that interacts with object initialization, especially custom subclasses or factory methods, to ensure correct reference handling. While explicit memory management is rarely needed in Python, understanding the underlying Objective-C semantics is crucial for correct behavior.","message":"PyObjC 11.1 introduced a major change in how initializer methods (those in the 'init' family) are modeled, now correctly reflecting that they 'steal' a reference to `self` and return a new one, as per clang's ARC documentation. This affects object lifecycle and reference counting.","severity":"breaking","affected_versions":">=11.1"},{"fix":"Ensure you are using PyObjC 10.3.1 or later if your Python classes override `__new__` and also define `__init__`.","message":"PyObjC 10.3 introduced a change that temporarily broke the ability to use `__init__` in Python classes when a user-defined `__new__` method was present. This was fixed in 10.3.1.","severity":"gotcha","affected_versions":"10.3"},{"fix":"If using custom Python subclasses of `NSProxy`, upgrade to PyObjC 12.1 or later to benefit from automatic KVO handling, or be aware of potential KVO interaction issues in older versions.","message":"In PyObjC 12.1, support was added to automatically disable Key-Value Observing (KVO) usage for subclasses of `NSProxy` defined in Python. This implies that earlier versions might have exhibited unexpected KVO behavior for such subclasses.","severity":"gotcha","affected_versions":"<12.1"},{"fix":"When using Python 3.13+ with PyObjC, be aware that free-threading support is experimental. Consult the PyObjC changelog for the latest status and any specific caveats or recommendations regarding thread safety.","message":"PyObjC 11.0 introduced *experimental* support for free-threading (PEP 703) in Python 3.13, but PyObjC 10.3 explicitly stated it did *not* support experimental free threading in Python 3.13. This can lead to confusion and instability if not carefully managed.","severity":"gotcha","affected_versions":"10.3, 11.0+"},{"fix":"Applications relying on `IMServicePlugIn` must update to alternative macOS APIs or ensure they are targeting an older macOS version and PyObjC release that still includes these bindings.","message":"The \"IMServicePlugIn\" bindings were removed in PyObjC 10.0. The entire framework was deprecated in macOS 10.13 and removed in macOS 14.","severity":"deprecated","affected_versions":">=10.0"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z","problems":[]}