{"id":6089,"library":"pyobjc-framework-coremidi","title":"PyObjC CoreMIDI Framework","description":"PyObjC CoreMIDI provides Python bindings for Apple's CoreMIDI framework on macOS, enabling Python applications to interact with MIDI devices and services. It is part of the larger PyObjC bridge, which allows full-featured Cocoa applications to be written in pure Python. The current version is 12.1, with releases typically tied to macOS SDK updates and Python version support changes.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","midi","framework","pyobjc","objective-c"],"install":[{"cmd":"pip install pyobjc-framework-coremidi","lang":"bash","label":"Install PyObjC CoreMIDI"}],"dependencies":[{"reason":"Core component providing the Python-Objective-C bridge.","package":"pyobjc-core","optional":false},{"reason":"Often required indirectly or for broader macOS application development context.","package":"pyobjc-framework-cocoa","optional":true}],"imports":[{"symbol":"CoreMIDI","correct":"import CoreMIDI"},{"symbol":"MIDIObjectGetStringProperty","correct":"from CoreMIDI import MIDIObjectGetStringProperty"}],"quickstart":{"code":"import CoreMIDI\nimport objc\n\ndef list_midi_devices():\n    \"\"\"Lists all available CoreMIDI devices.\"\"\"\n    print(\"MIDI Devices:\")\n    num_devices = CoreMIDI.MIDIGetNumberOfDevices()\n    if num_devices == 0:\n        print(\"  No MIDI devices found.\")\n        return\n\n    for i in range(num_devices):\n        midi_device_ref = CoreMIDI.MIDIGetDevice(i)\n        if midi_device_ref:\n            # MIDIObjectGetStringProperty returns a status code and the string value.\n            # PyObjC automatically bridges CFStringRef to Python string.\n            (name_result, name_str) = CoreMIDI.MIDIObjectGetStringProperty(\n                midi_device_ref, CoreMIDI.kMIDIPropertyName\n            )\n            if name_result == 0: # noErr\n                print(f\"  Device {i}: {name_str}\")\n            else:\n                print(f\"  Device {i}: (Error getting name, code {name_result})\")\n        else:\n            print(f\"  Device {i}: (Could not get device reference)\")\n\nif __name__ == \"__main__\":\n    list_midi_devices()","lang":"python","description":"This example demonstrates how to import the CoreMIDI framework and iterate through the available MIDI devices, printing their names. CoreMIDI is a low-level API; more complex interactions often require a deeper understanding of its C API and manual resource management."},"warnings":[{"fix":"Ensure your Python environment is 3.10 or newer.","message":"Python 3.9 support was dropped in PyObjC 12.0. Python 3.8 support was dropped in PyObjC 11.0. The current version requires Python >= 3.10.","severity":"breaking","affected_versions":">=11.0, >=12.0"},{"fix":"Consult the PyObjC API Notes for CoreMIDI and Apple's CoreMIDI C API documentation for detailed usage and limitations.","message":"CoreMIDI bindings are a low-level API, and for certain interactions, especially those not based on CoreFoundation or Objective-C types, users may need to perform manual reference counting. Some C functions like `MIDIDeviceCreate`, `MIDISend`, and event list manipulation (`MIDIEventListAdd`, `MIDIEventListInit`) are noted as requiring manual bindings or not being available from Python.","severity":"gotcha","affected_versions":"All"},{"fix":"Review custom Python subclasses of Objective-C classes, particularly `__new__` and `__init__` methods, to ensure compatibility with ARC behavior for initializers. Refer to `__init__` related breaking changes from v10.3/v10.3.1.","message":"PyObjC 11.1 aligned the core bridge's behavior with `clang`'s documentation for Automatic Reference Counting (ARC) regarding initializer methods. Methods in the 'init' family now correctly steal a reference to self and return a new reference, which differs from previous PyObjC versions' handling of partially initialized objects.","severity":"breaking","affected_versions":">=11.1"},{"fix":"Exercise caution and thorough testing when using PyObjC with experimental free-threading builds of Python 3.13 or newer. Stick to default Python builds for stable applications.","message":"Experimental support for free-threading (PEP 703) introduced in Python 3.13 is included in PyObjC 11, but PyObjC 10.3 explicitly did not support it. While PyObjC 12.1 supports Python 3.10+, if targeting Python 3.13 with free-threading, be aware of the experimental nature of this support.","severity":"gotcha","affected_versions":">=10.3, >=11.0"},{"fix":"If encountering issues with `__init__` not being called after `__new__`, ensure you are on PyObjC 10.3.1 or later, and review the specific conditions under which `__init__` is supported when `__new__` is user-implemented versus provided by PyObjC.","message":"The behavior of `__init__` when a user implements `__new__` in Objective-C bridged classes changed in PyObjC 10.3 (dropping support for `__init__` in such cases) and was partially reintroduced in 10.3.1 due to breaking popular projects.","severity":"gotcha","affected_versions":">=10.3, <=10.3.1"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z","problems":[]}