"protocol u'NSSpeechSynthesizerDelegate' does not exist"

$sw_vers-productVersion10.8.2$pythonPython2.7.2(v2.7.2:8527427914a2,Jun112011,15:22:34)[GCC4.2.1(AppleInc.build5666)(dot3)]ondarwinType"help","copyright","credits"or"license"formoreinformation.>>>importobjc>>>fromAppKitimport*>>>objc.protocolNamed("NSLocking")<objc.formal_protocolNSLockingat0x105a9fd80>>>>objc.protocolNamed("NSSpeechSynthesizerDelegate")Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"/Users/qwerty/.python/lib/python/pyobjc_core-2.4-py2.7-macosx-10.8-intel.egg/objc/_protocols.py",line33,inprotocolNamedraiseProtocolError("protocol %r does not exist"%(name,),name)objc.ProtocolError:("protocol u'NSSpeechSynthesizerDelegate' does not exist",u'NSSpeechSynthesizerDelegate')>>>

I haven't applied the patch yet because I don't particularly like it. I first want to check if it is possible to force the runtime to load all protocol definitions, even if they don't appear to be used.

If that doesn't work this patch will be used, although properly in a more generic manner and in a way that won't cause compile errors on older OSX releases.

Also it should be very helpfull to have something like "register_formal_protocol" function uses objc_getProtocol, and to be able to call it directly from Python code via PyObjC.
Then registering unknown to PyObjC protocols will not require recompiling PyObjC code.

Doing it "properly" might end up being the hack I posted earlier because the ObjC runtime doesn't seem to instantiate protocols unless they are actually used (at least on OSX 10.8, I haven't checked other OS X releases yet).

That is, even the Cocoa functions for getting a protocol fail: Cocoa.NSProtocolFromString('NSCollectionViewDelegate')

I have located the ObjC runtime source code, but haven't tried yet to find the code that realizes protocols. With some luck it will be possible to force the runtime to realize all protocols, not just the onces referenced from code. If that is possible there won't have to be an API to create a formal_protocol for a not-yet-loaded protocol.

Anyway, just calling objc_getProtocol isn't good enough, I've tried this and that fails to find NSSpeechSynthesizerDelegate unless the protocol is already realized due to a reference in code (an (at)protocol line or a class that implements the protocol).

This situation sucks. I'll probably end up filing a bugreport at Apple, but that won't help until OSX 10.9 at the earliest (if this ever gets fixed).

UPDATE: Changed text to replace an at-sign by (at) to avoid a link to a person page.

It seems that protocols that aren't used internally aren't actually present in the shared library image.

That is, if you dump the contents of the objc section with otool ("otool -vo /System/Library/Frameworks/AppKit.framework/AppKit") you can find "NSToolbarDelegate" (one of the protocols you could fetch with objc.protocolNamed), in the output but not "NSTextStorageDelegate" (a protocol that cannot be fetched with objc.protocolNamed).

This indicates that the compiler won't generate code for a protocol unless the protocol is referenced somewhere.

That would mean that I'll have go generate code that references all protocols defined in a framework, just to be sure. Generating that code isn't hard, but I had hoped to remove more C code, not add new code.

This is needed because framework only export those protocol
definitions that are used by the code in that framework. Without
the extensions some protocols are not available to python code,
see issue #44 for more information.

This is needed because framework only export those protocol
definitions that are used by the code in that framework. Without
the extensions some protocols are not available to python code,
see issue #44 for more information.