{"id":5409,"library":"pyobjc-framework-libdispatch","title":"PyObjC Framework: libdispatch","description":"Wrappers for libdispatch on macOS, a low-level C API for concurrent code execution. PyObjC acts as a bridge between Python and Objective-C, enabling Python scripts to seamlessly utilize and extend Objective-C class libraries, including Apple's high-level system APIs. It allows for the development of full-featured Cocoa applications entirely in Python. The current version is 12.1 and follows the PyObjC release cadence.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","objective-c","cocoa","dispatch","libdispatch","wrapper","apple","concurrency","multithreading"],"install":[{"cmd":"pip install pyobjc-framework-libdispatch","lang":"bash","label":"Install `libdispatch` bindings"}],"dependencies":[{"reason":"This package provides bindings for a specific macOS framework, requiring the core PyObjC bridge functionality.","package":"pyobjc-core","optional":false},{"reason":"Requires Python 3.10 or later.","package":"Python","optional":false}],"imports":[{"note":"The preferred import name for libdispatch bindings is 'dispatch'. While 'libdispatch' still works for backward compatibility, 'dispatch' is the modern and recommended approach.","wrong":"import libdispatch","symbol":"dispatch","correct":"import dispatch"}],"quickstart":{"code":"import array\nfrom dispatch import dispatch_once\n\n# dispatch_once ensures a block of code is executed only once,\n# even if called multiple times from different threads.\n# It requires an array.array instance as its first argument\n# to track whether the block has been run.\n\npredicate = array.array('l', [0]) # Must be a mutable array of long (C 'long')\n\ndef my_initialization_function():\n    print(\"Performing one-time initialization...\")\n    # Simulate some work\n    import time\n    time.sleep(0.1)\n    print(\"Initialization complete.\")\n\nprint(\"Attempting to call dispatch_once for the first time...\")\ndispatch_once(predicate, my_initialization_function)\n\nprint(\"Attempting to call dispatch_once for the second time...\")\ndispatch_once(predicate, my_initialization_function)\n\nprint(\"Program finished.\")","lang":"python","description":"This quickstart demonstrates the use of `dispatch_once` from the `libdispatch` bindings to ensure a function runs only a single time across application execution. Note the requirement for an `array.array('l', [0])` as the predicate argument for `dispatch_once`."},"warnings":[{"fix":"Ensure your Python environment is version 3.10 or newer. If you must use an older Python version, install a compatible older PyObjC release.","message":"PyObjC 12.x (and thus `pyobjc-framework-libdispatch` 12.x) dropped support for Python 3.9. Similarly, PyObjC 11.x dropped support for Python 3.8. The current version of PyObjC and its framework wrappers require Python 3.10 or later.","severity":"breaking","affected_versions":"PyObjC 11.0 and later, `pyobjc-framework-libdispatch` 11.0 and later."},{"fix":"When subclassing Objective-C classes in Python, if you define an `__init__` method, it is best practice to also explicitly define a `__new__` method in your Python class, or adhere strictly to the Objective-C `init...` pattern without overriding `__new__`.","message":"PyObjC 10.3 introduced a change that broke `__init__` methods in Python subclasses of Objective-C classes if they implicitly relied on PyObjC's default `__new__` behavior without defining their own `__new__`. While partially reverted in 10.3.1, classes that implement `__init__` but not `__new__` and rely on PyObjC's `__new__` might still exhibit issues.","severity":"breaking","affected_versions":"PyObjC 10.3, partially mitigated in 10.3.1. Affects `pyobjc-framework-libdispatch` if used in custom Objective-C subclasses."},{"fix":"Always refer to Apple's official `libdispatch` documentation in conjunction with PyObjC's API Notes. Pay close attention to memory management, thread safety, and expected C types for arguments (e.g., pointers, blocks).","message":"`libdispatch` exposes a low-level C API. Incorrect usage of its functions and types through PyObjC can bypass Python's usual error handling, leading to hard crashes or undefined behavior in your application rather than graceful Python exceptions.","severity":"gotcha","affected_versions":"All versions."},{"fix":"Update all import statements from `import libdispatch` to `import dispatch` for future compatibility and to align with current best practices.","message":"The primary import for this framework is `import dispatch`. While `import libdispatch` currently functions for backward compatibility, it is considered the older name for the package. Future PyObjC versions may remove support for the `libdispatch` import name.","severity":"deprecated","affected_versions":"PyObjC 10.0 and later."},{"fix":"Before using a `libdispatch` function, consult the 'PyObjC API Notes: dispatch library' documentation to verify its availability and any specific Python binding requirements, such as the `array.array` argument for `dispatch_once`.","message":"Several `libdispatch` functions, such as `dispatch_retain`, `dispatch_release`, `dispatch_wait`, `dispatch_notify`, `dispatch_cancel`, and `dispatch_testcancel`, are either unavailable or require specific usage patterns (e.g., using object-specific variants). Additionally, the workgroup APIs introduced in macOS 11 are not supported.","severity":"gotcha","affected_versions":"All versions."}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}