[Pythonmac-SIG] PyObjC vs "old school" embedding

gandreas@gandreas.com gandreas at gandreas.com
Tue May 31 22:17:40 CEST 2005


So PyOXIDE is based on the traditional way to embed python in an  
application (explicitly calling the python APIs to access and call  
stuff), and this worked reasonably well.  For example, it runs  
various scripts at startup, which register various callbacks to  
handle things like new documents, new interactives, etc... (and then  
the underlying Objective C code explicitly calls these callbacks at  
appropriate points).

Unfortunately, things recently have gone downhill (with either  the  
Tiger system framework or the 2.4 unofficial official framework, with  
PyObjC 1.3.5(*)).  I've got an "interactive" window (i.e., the  
interactive shell) which is loaded via a menu command - in the  
window's controller awakenFromNib: I've got the  following code:
- (void) awakeFromNib
{
     NSLog(@"Interactive awakeFromNib");
     myMain = PyImport_AddModule("__main__");
     if (myMain == NULL || (PyErr_Occurred())) {
     //NSLog(@"Couldn't add module __main__");
     PyErr_Print();
     }
(... and then the code that calls the python code to hook the  
interactive window to the text view, etc...)


Now, when the interactive window is created by the menu, everything  
works fine (application main loop calls the Objective C code which  
loads a nib, nib loading calls above routine, everything fine).  If  
the same thing includes a layer of python on the stack, such as is  
done as part of the debugger (since I've got interactive windows in  
the debugger so you can directly access/execute code in your debugged  
context), it fails - namely, PyImport_AddModule crashes:

#0  0x100a68d8 in PyImport_AddModule (name=0x159c8 "__main__") at / 
Users/bob/src/Python-2.4.1/Python/import.c:308
#1  0x000090bc in -[PyInteractive awakeFromNib] (self=0x54b71a0,  
_cmd=0x909f36ac) at /Volumes/YWork1/PyOXIDE/Source/PyInteractive.mm:132
#2  0x92886788 in -[NSSet makeObjectsPerformSelector:] ()
#3  0x93636f94 in -[NSIBObjectData  
nibInstantiateWithOwner:topLevelObjects:] ()
#4  0x9370dbdc in old_loadNib ()
[snip]
#8  0x9370d6a4 in -[NSWindowController window] ()
#9  0x007d7a98 in ffi_call_DARWIN ()
#10 0x007d74b0 in ffi_call ()
#11 0x007beb24 in PyObjCFFI_Caller ()
#12 0x007d1e3c in PyObjCAPI_Register ()
#13 0x1000c348 in PyObject_Call (func=0x0, arg=0x101158b4,  
kw=0x101268b8) at /Users/bob/src/Python-2.4.1/Objects/abstract.c:1751
[snip]
#39 0x100092cc in PyObject_CallMethod (o=0x0, name=0x10119178 "a more  
convenient interface.", format=0x713030 "") at /Users/bob/src/ 
Python-2.4.1/Objects/abstract.c:1751
#40 0x0000d954 in -[NSDocument(NSDocumentPyHandler) pythonOnHandler:]  
(self=0x4cef190, _cmd=0x1746c, sender=0x387220) at /Volumes/YWork1/ 
PyOXIDE/Source/NSDocumentPyHandler.mm:181
#41 0x936be08c in -[NSApplication sendAction:to:from:] ()
[snip]

Basically, the app calls my object to handle the menu command  
("Debug") which calls PyObject_CallMethod  to handle the "bound menu  
routine".  That python code does a bunch of stuff, loads a nib, the  
nib loading fires off my awakeFromNib code, which tries to get the  
__main__ module, and boom!

Looking at import.c:308:

PyObject *
PyImport_GetModuleDict(void)
{
     PyInterpreterState *interp = PyThreadState_GET()->interp; //  
Crash is here, since PyThreadState_GET is NULL
     if (interp->modules == NULL)
         Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
     return interp->modules;
}


There are no python threads running, I've not called  
PyEval_InitThreads() or anything like that.  So it _appears_ that any  
code called from Python through the Objective C bridge can no longer  
access the interpreter - is this correct?  What would be the approach  
to allow this to work? Should I initialize threads support, and  
execute all my callbacks on a separate thread?  Or would I need to  
create a new interpreter state for these?  Or am I just plain hosed  
on mixing "traditional" embedding techniques with PyObjC?



(* - I've downloaded and installed PyObjC 1.3.6 twice but for some  
reason it doesn't want to use it:

gandreas% /Library/Frameworks/Python.framework/Versions/Current/bin/ 
python2.4
Python 2.4.1 (#2, Mar 31 2005, 00:05:10)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1666)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
 >>> import objc
 >>> objc.__version__
'1.3.5'
 >>> objc.__file__
'/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site- 
packages/PyObjC/objc/__init__.pyc'
)



Glenn Andreas                      gandreas at gandreas.com
  <http://www.gandreas.com/> wicked fun!
Widgetarium | the quickest path to widgets

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/pythonmac-sig/attachments/20050531/d1a05a80/attachment-0001.html


More information about the Pythonmac-SIG mailing list