Thread: [Pyobjc-dev] Mail plugin
Brought to you by:
ronaldoussoren
From: Fortepianissimo <for...@gm...> - 2005-01-17 16:06:12
|
After a long while I finally started again on my quest of using PyObjC to write a Mail bundle plugin. For some consideration I want to start my plugin in objc - i.e., implement my bundle class in objc, and in the initialization load in a "plugin" bundle written in Python (in the spirit of SimpleComboBoxPlus example). The -init implementation of the objc bundle is (the plugin written in Python is called Foo.py, with a single class Foo in it): - (id)init { static id _singleton; if (_singleton) return _singleton; if (self = [super init]) { // load plugin (same code copied from main.m in SimpleComboBoxPlus // tutorial) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; thisBundle = [NSBundle bundleForClass:[self class]]; pluginPath = [thisBundle pathForResource:@"Foo" ofType:@"plugin"]; NSBundle *pluginBundle = [NSBundle bundleWithPath:pluginPath]; [pluginBundle load]; [pool release]; // instantiate Foo foo = [[objc_lookUpClass("Foo") alloc] init]; //[foo somemethod:@"testing!"]; } _singleton = self; return self; } Foo.py is implemented like this: import objc from Foundation import * from AppKit import * class Foo (NSObject): def init(self): self = super(Foo, self).init() if self: print 'inside init() of Foo' return self def somemethod_ (self, s): NSLog(s) I also created setup.py and run py2app to create Foo.plugin, and then included Foo.plugin in my resources. After placing the resulting mailbundle in ~/Library/Mail/Bundles and start Mail.app, I can see Foo.init() is correctly called. The problem: for some reason the commented-out line in the objc part: //[foo somemethod:@"testing!"]; caused the following runtime error: *** -[Foo somemethod:]: selector not recognized My question: why wasn't it recognized? BTW I didn't use a nib file in my mail bundle because I can't figure out a way to load the nib file *after* loading my Foo.plugin (thus the instantiation of Foo took place too early). Any suggestion is greatly appreciated! |
From: Bob I. <bo...@re...> - 2005-01-17 19:45:36
|
On Jan 17, 2005, at 11:06, Fortepianissimo wrote: > After a long while I finally started again on my quest of using PyObjC > to write a Mail bundle plugin. > > For some consideration I want to start my plugin in objc - i.e., > implement my bundle class in objc, and in the initialization load in a > "plugin" bundle written in Python (in the spirit of SimpleComboBoxPlus > example). The -init implementation of the objc bundle is (the plugin > written in Python is called Foo.py, with a single class Foo in it): > > - (id)init { > static id _singleton; > > if (_singleton) return _singleton; > > if (self = [super init]) { > // load plugin (same code copied from main.m in > SimpleComboBoxPlus > // tutorial) > NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; > > thisBundle = [NSBundle bundleForClass:[self class]]; > pluginPath = [thisBundle pathForResource:@"Foo" > ofType:@"plugin"]; > > NSBundle *pluginBundle = [NSBundle bundleWithPath:pluginPath]; > [pluginBundle load]; > > [pool release]; > > // instantiate Foo > foo = [[objc_lookUpClass("Foo") alloc] init]; > //[foo somemethod:@"testing!"]; > } > > _singleton = self; > return self; > } > > Foo.py is implemented like this: > > import objc > from Foundation import * > from AppKit import * > > class Foo (NSObject): > def init(self): > self = super(Foo, self).init() > if self: > print 'inside init() of Foo' > return self > > def somemethod_ (self, s): > NSLog(s) > > > I also created setup.py and run py2app to create Foo.plugin, and then > included Foo.plugin in my resources. > > After placing the resulting mailbundle in ~/Library/Mail/Bundles and > start Mail.app, I can see Foo.init() is correctly called. > > The problem: for some reason the commented-out line in the objc part: > > //[foo somemethod:@"testing!"]; > > caused the following runtime error: > > *** -[Foo somemethod:]: selector not recognized > > My question: why wasn't it recognized? Because Foo doesn't have a method named "somemethod_". You indented it too far, it's a nested function of the "init" method. > BTW I didn't use a nib file in my mail bundle because I can't figure > out a way to load the nib file *after* loading my Foo.plugin (thus the > instantiation of Foo took place too early). If it's not the NSMainNibFile (i.e. loaded manually) then this shouldn't be a problem. I'm not sure why you are writing an Objective-C plug-in that loads a Python plug-in. I'd do it the other way around (or include the Objective-C code as an extension inside the Python plug-in). -bob |
From: Fortepianissimo <for...@gm...> - 2005-01-17 21:56:59
|
On Mon, 17 Jan 2005 14:45:28 -0500, Bob Ippolito <bo...@re...> wrote: > > On Jan 17, 2005, at 11:06, Fortepianissimo wrote: > > > After a long while I finally started again on my quest of using PyObjC > > to write a Mail bundle plugin. > > > > For some consideration I want to start my plugin in objc - i.e., > > implement my bundle class in objc, and in the initialization load in a > > "plugin" bundle written in Python (in the spirit of SimpleComboBoxPlus > > example). The -init implementation of the objc bundle is (the plugin > > written in Python is called Foo.py, with a single class Foo in it): > > > > - (id)init { > > static id _singleton; > > > > if (_singleton) return _singleton; > > > > if (self = [super init]) { > > // load plugin (same code copied from main.m in > > SimpleComboBoxPlus > > // tutorial) > > NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; > > > > thisBundle = [NSBundle bundleForClass:[self class]]; > > pluginPath = [thisBundle pathForResource:@"Foo" > > ofType:@"plugin"]; > > > > NSBundle *pluginBundle = [NSBundle bundleWithPath:pluginPath]; > > [pluginBundle load]; > > > > [pool release]; > > > > // instantiate Foo > > foo = [[objc_lookUpClass("Foo") alloc] init]; > > //[foo somemethod:@"testing!"]; > > } > > > > _singleton = self; > > return self; > > } > > > > Foo.py is implemented like this: > > > > import objc > > from Foundation import * > > from AppKit import * > > > > class Foo (NSObject): > > def init(self): > > self = super(Foo, self).init() > > if self: > > print 'inside init() of Foo' > > return self > > > > def somemethod_ (self, s): > > NSLog(s) > > > > > > I also created setup.py and run py2app to create Foo.plugin, and then > > included Foo.plugin in my resources. > > > > After placing the resulting mailbundle in ~/Library/Mail/Bundles and > > start Mail.app, I can see Foo.init() is correctly called. > > > > The problem: for some reason the commented-out line in the objc part: > > > > //[foo somemethod:@"testing!"]; > > > > caused the following runtime error: > > > > *** -[Foo somemethod:]: selector not recognized > > > > My question: why wasn't it recognized? > > Because Foo doesn't have a method named "somemethod_". You indented it > too far, it's a nested function of the "init" method. OMG - lesson learned: don't mix Emacs and Xcode together... Thanks for pointing it out! Now I ran into another problem: it looks like I'm having deadlock of some sort. My hunch is that the Foo class is instantiated in one thread, but when I try to do foo.somemethod_() inside some other thread, I bumped directly into the much dreaded GIL? So my general question is: is it possible to call foo.somemethod_(u'string') (or shall I say [foo somemethod:@"string"] ) in an objc thread that's different from the thread that instantiates foo? If yes, how should I do it? (the same threading problem will happen if I started out from the Python side) Thanks! > > > BTW I didn't use a nib file in my mail bundle because I can't figure > > out a way to load the nib file *after* loading my Foo.plugin (thus the > > instantiation of Foo took place too early). > > If it's not the NSMainNibFile (i.e. loaded manually) then this > shouldn't be a problem. I'm not sure why you are writing an > Objective-C plug-in that loads a Python plug-in. I'd do it the other > way around (or include the Objective-C code as an extension inside the > Python plug-in). > > -bob > > |
From: Bob I. <bo...@re...> - 2005-01-17 22:09:12
|
On Jan 17, 2005, at 16:56, Fortepianissimo wrote: > On Mon, 17 Jan 2005 14:45:28 -0500, Bob Ippolito <bo...@re...> > wrote: >> >> On Jan 17, 2005, at 11:06, Fortepianissimo wrote: >> >>> After a long while I finally started again on my quest of using >>> PyObjC >>> to write a Mail bundle plugin. >>> >>> For some consideration I want to start my plugin in objc - i.e., >>> implement my bundle class in objc, and in the initialization load in >>> a >>> "plugin" bundle written in Python (in the spirit of >>> SimpleComboBoxPlus >>> example). The -init implementation of the objc bundle is (the plugin >>> written in Python is called Foo.py, with a single class Foo in it): ... >>> I also created setup.py and run py2app to create Foo.plugin, and then >>> included Foo.plugin in my resources. >>> >>> After placing the resulting mailbundle in ~/Library/Mail/Bundles and >>> start Mail.app, I can see Foo.init() is correctly called. > > Now I ran into another problem: it looks like I'm having deadlock of > some sort. My hunch is that the Foo class is instantiated in one > thread, but when I try to do foo.somemethod_() inside some other > thread, I bumped directly into the much dreaded GIL? The way we use the GIL should not cause a deadlock like that. It could be a bug in your code, PyObjC, or Python. If you can give me a minimal example that can reproduce this problem *without* being loaded as a plugin to Mail.app, then I will look into it. Otherwise, you're on your own. > So my general question is: is it possible to call > foo.somemethod_(u'string') (or shall I say [foo somemethod:@"string"] > ) in an objc thread that's different from the thread that instantiates > foo? If yes, how should I do it? Yes, and just like you normally would. It should work just fine. > (the same threading problem will happen if I started out from the > Python side) Are you sure? Did you try it? -bob |
From: ytrewq1 <yt...@gm...> - 2005-01-17 22:52:36
|
I don't know if it's quite the same situation, but when working on PyObjC plug-ins for Quicksilver which used the threading module, I found the autoGIL module helped: http://docs.python.org/mac/module-autoGIL.html Without it, I'd find that a thread I'd make would hang in the middle of processing. It was odd, I'd invoke a command implemented in a PyObjC plug-in from Quicksilver, noticed the processing start (via logging), but then it would just stop after a bit -- just activating Quicksilver would make the processing continue a little, but then it would stop shortly. Just adding: import autoGIL autoGIL.installAutoGIL() to the plug-ins which used the threading module appeared to address the issue. P.S. For a while this was what I stuck to, but now I'm considering switching over to having all PyObjC plug-ins integrate w/ Twisted (using cfreactor) -- this way I'm hoping to avoid multiple threads as much as possible. On Mon, 17 Jan 2005 16:56:50 -0500, Fortepianissimo <for...@gm...> wrote: > On Mon, 17 Jan 2005 14:45:28 -0500, Bob Ippolito <bo...@re...> wrote: > > > > On Jan 17, 2005, at 11:06, Fortepianissimo wrote: > > > > > After a long while I finally started again on my quest of using PyObjC > > > to write a Mail bundle plugin. > > > > > > For some consideration I want to start my plugin in objc - i.e., > > > implement my bundle class in objc, and in the initialization load in a > > > "plugin" bundle written in Python (in the spirit of SimpleComboBoxPlus > > > example). The -init implementation of the objc bundle is (the plugin > > > written in Python is called Foo.py, with a single class Foo in it): > > > > > > - (id)init { > > > static id _singleton; > > > > > > if (_singleton) return _singleton; > > > > > > if (self = [super init]) { > > > // load plugin (same code copied from main.m in > > > SimpleComboBoxPlus > > > // tutorial) > > > NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; > > > > > > thisBundle = [NSBundle bundleForClass:[self class]]; > > > pluginPath = [thisBundle pathForResource:@"Foo" > > > ofType:@"plugin"]; > > > > > > NSBundle *pluginBundle = [NSBundle bundleWithPath:pluginPath]; > > > [pluginBundle load]; > > > > > > [pool release]; > > > > > > // instantiate Foo > > > foo = [[objc_lookUpClass("Foo") alloc] init]; > > > //[foo somemethod:@"testing!"]; > > > } > > > > > > _singleton = self; > > > return self; > > > } > > > > > > Foo.py is implemented like this: > > > > > > import objc > > > from Foundation import * > > > from AppKit import * > > > > > > class Foo (NSObject): > > > def init(self): > > > self = super(Foo, self).init() > > > if self: > > > print 'inside init() of Foo' > > > return self > > > > > > def somemethod_ (self, s): > > > NSLog(s) > > > > > > > > > I also created setup.py and run py2app to create Foo.plugin, and then > > > included Foo.plugin in my resources. > > > > > > After placing the resulting mailbundle in ~/Library/Mail/Bundles and > > > start Mail.app, I can see Foo.init() is correctly called. > > > > > > The problem: for some reason the commented-out line in the objc part: > > > > > > //[foo somemethod:@"testing!"]; > > > > > > caused the following runtime error: > > > > > > *** -[Foo somemethod:]: selector not recognized > > > > > > My question: why wasn't it recognized? > > > > Because Foo doesn't have a method named "somemethod_". You indented it > > too far, it's a nested function of the "init" method. > > OMG - lesson learned: don't mix Emacs and Xcode together... Thanks for > pointing it out! > > Now I ran into another problem: it looks like I'm having deadlock of > some sort. My hunch is that the Foo class is instantiated in one > thread, but when I try to do foo.somemethod_() inside some other > thread, I bumped directly into the much dreaded GIL? > > So my general question is: is it possible to call > foo.somemethod_(u'string') (or shall I say [foo somemethod:@"string"] > ) in an objc thread that's different from the thread that instantiates > foo? If yes, how should I do it? > > (the same threading problem will happen if I started out from the Python side) > > Thanks! > > > > > > BTW I didn't use a nib file in my mail bundle because I can't figure > > > out a way to load the nib file *after* loading my Foo.plugin (thus the > > > instantiation of Foo took place too early). > > > > If it's not the NSMainNibFile (i.e. loaded manually) then this > > shouldn't be a problem. I'm not sure why you are writing an > > Objective-C plug-in that loads a Python plug-in. I'd do it the other > > way around (or include the Objective-C code as an extension inside the > > Python plug-in). > > > > -bob > > > > > > ------------------------------------------------------- > The SF.Net email is sponsored by: Beat the post-holiday blues > Get a FREE limited edition SourceForge.net t-shirt from ThinkGeek. > It's fun and FREE -- well, almost....http://www.thinkgeek.com/sfshirt > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev > |
From: Bob I. <bo...@re...> - 2005-01-18 01:01:27
|
On Jan 17, 2005, at 17:52, ytrewq1 wrote: > I don't know if it's quite the same situation, but when working on > PyObjC plug-ins for Quicksilver which used the threading module, I > found the autoGIL module helped: > > http://docs.python.org/mac/module-autoGIL.html > > Without it, I'd find that a thread I'd make would hang in the middle > of processing. It was odd, I'd invoke a command implemented in a > PyObjC plug-in from Quicksilver, noticed the processing start (via > logging), but then it would just stop after a bit -- just activating > Quicksilver would make the processing continue a little, but then it > would stop shortly. Just adding: > > import autoGIL > autoGIL.installAutoGIL() > > to the plug-ins which used the threading module appeared to address > the issue. Don't do that! autoGIL should not EVER be used for PyObjC 1.1 and later. -bob |
From: Bob I. <bo...@re...> - 2005-01-18 09:08:42
|
On Jan 18, 2005, at 3:57, ytrewq1 wrote: > On Mon, 17 Jan 2005 20:01:19 -0500, Bob Ippolito <bo...@re...> > wrote: >> On Jan 17, 2005, at 17:52, ytrewq1 wrote: >> >>> I don't know if it's quite the same situation, but when working on >>> PyObjC plug-ins for Quicksilver which used the threading module, I >>> found the autoGIL module helped: >>> >>> http://docs.python.org/mac/module-autoGIL.html >>> >>> Without it, I'd find that a thread I'd make would hang in the middle >>> of processing. It was odd, I'd invoke a command implemented in a >>> PyObjC plug-in from Quicksilver, noticed the processing start (via >>> logging), but then it would just stop after a bit -- just activating >>> Quicksilver would make the processing continue a little, but then it >>> would stop shortly. Just adding: >>> >>> import autoGIL >>> autoGIL.installAutoGIL() >>> >>> to the plug-ins which used the threading module appeared to address >>> the issue. >> >> Don't do that! autoGIL should not EVER be used for PyObjC 1.1 and >> later. >> > Thanks for the advice. If I do switch all of the plug-ins over to > using Twisted, I won't be using autoGIL any more. autoGIL with PyObjC 1.1+ almost guarantees a crash somewhere.. you should remove it immediately and fix the code. > At the moment though, I don't know how else to address the issue of > the hanging threads (other than to not use the threading module). It > may be that the code I used to get plug-ins working for Quicksilver is > problematic -- I adapted some ObjC from pluginbuilder.py in the 1.1 > release to get things working and I wouldn't be surprised if what I > did was quite bad :-) The code in pluginbuilder wasn't very good to begin with. py2app does it right. Obviously something you're doing is wrong. If you switch to py2app, this problem should just go away. I'm not going to bother debugging your code, because it is simply not necessary with py2app. No Objective-C whatsoever is required when using py2app, you don't even need a compiler installed. > FWIW, I think the following shows typical glue code for current PyObjC > QS plug-ins: > > http://www.google.com/search?q=cache:zvdOtPMELKMJ:paste.lisp.org/ > display/2340+pyobjc+lisp+paste+quicksilver&hl=ko&client=firefox- > a%20target=nw > > I'd like to switch over to using objc.registerPlugin and friends, but > I need to verify that: You should probably go ahead and use svn trunk of py2app (0.1.8) and PyObjC (1.3a0), I deprecated objc.registerPlugin today and came up with a better way of doing it that requires less effort. The documentation is up to date. http://svn.red-bean.com/pyobjc/trunk/pyobjc/NEWS.txt > 1) It'll work for QS plug-ins (I don't imagine it won't) > 2) I can package up PyObjC in a way that doesn't require it having to > live in each PyObjC plug-in (my current approach has a post 1.1 pre > 1.2 version of PyObjC living in a plug-in which all other PyObjC > plug-ins reference) If you included it in every plugin, it would just load whichever one comes first since sys.modules is global. If you have one plugin that always loads first, then you can simply exclude it from every other Python-based plugin and it should just work. -bob |
From: ytrewq1 <yt...@gm...> - 2005-01-19 06:17:34
|
On Tue, 18 Jan 2005 04:08:34 -0500, Bob Ippolito <bo...@re...> wrote: > On Jan 18, 2005, at 3:57, ytrewq1 wrote: > > > On Mon, 17 Jan 2005 20:01:19 -0500, Bob Ippolito <bo...@re...> > > wrote: > >> On Jan 17, 2005, at 17:52, ytrewq1 wrote: > >> > >>> I don't know if it's quite the same situation, but when working on > >>> PyObjC plug-ins for Quicksilver which used the threading module, I > >>> found the autoGIL module helped: > >>> > >>> http://docs.python.org/mac/module-autoGIL.html > >>> > >>> Without it, I'd find that a thread I'd make would hang in the middle > >>> of processing. It was odd, I'd invoke a command implemented in a > >>> PyObjC plug-in from Quicksilver, noticed the processing start (via > >>> logging), but then it would just stop after a bit -- just activating > >>> Quicksilver would make the processing continue a little, but then it > >>> would stop shortly. Just adding: > >>> > >>> import autoGIL > >>> autoGIL.installAutoGIL() > >>> > >>> to the plug-ins which used the threading module appeared to address > >>> the issue. > >> > >> Don't do that! autoGIL should not EVER be used for PyObjC 1.1 and > >> later. > >> > > Thanks for the advice. If I do switch all of the plug-ins over to > > using Twisted, I won't be using autoGIL any more. > > autoGIL with PyObjC 1.1+ almost guarantees a crash somewhere.. you > should remove it immediately and fix the code. Ok, I've started working on this. > > At the moment though, I don't know how else to address the issue of > > the hanging threads (other than to not use the threading module). It > > may be that the code I used to get plug-ins working for Quicksilver is > > problematic -- I adapted some ObjC from pluginbuilder.py in the 1.1 > > release to get things working and I wouldn't be surprised if what I > > did was quite bad :-) > > The code in pluginbuilder wasn't very good to begin with. py2app does > it right. Obviously something you're doing is wrong. :-) > If you switch to py2app, this problem should just go away. I'm not going to > bother debugging your code, because it is simply not necessary with py2app. > No Objective-C whatsoever is required when using py2app, you don't even > need a compiler installed. Nice. > > FWIW, I think the following shows typical glue code for current PyObjC > > QS plug-ins: > > > > http://www.google.com/search?q=cache:zvdOtPMELKMJ:paste.lisp.org/ > > display/2340+pyobjc+lisp+paste+quicksilver&hl=ko&client=firefox- > > a%20target=nw > > > > I'd like to switch over to using objc.registerPlugin and friends, but > > I need to verify that: > > You should probably go ahead and use svn trunk of py2app (0.1.8) and > PyObjC (1.3a0), I deprecated objc.registerPlugin today and came up with > a better way of doing it that requires less effort. The documentation > is up to date. > > http://svn.red-bean.com/pyobjc/trunk/pyobjc/NEWS.txt Thanks for this. I've pulled down svn trunk for both and installed them [1]. I modified several of my existing plug-ins to be built using py2app and tested them. In my limited testing so far they seem fine (though I haven't yet modified the ones that had the thread execution problem). > > 1) It'll work for QS plug-ins (I don't imagine it won't) > > 2) I can package up PyObjC in a way that doesn't require it having to > > live in each PyObjC plug-in (my current approach has a post 1.1 pre > > 1.2 version of PyObjC living in a plug-in which all other PyObjC > > plug-ins reference) > > If you included it in every plugin, it would just load whichever one > comes first since sys.modules is global. If you have one plugin that > always loads first, then you can simply exclude it from every other > Python-based plugin and it should just work. PyObjC plug-ins I've built that include PyObjC bits tend to be larger than 1 MB and QS plug-ins are typically a fair bit smaller (e.g. less than 100 kB). The author of QS is not too keen on larger plug-ins -- which is one of the reasons I'd packaged up PyObjC separately and had the other plug-ins depend on it. I've made some Makefiles to prune PyObjC bits from lib-dynload and site-packages.zip -- does that sound like a reasonable approach or is there a way to prevent certain items from getting included that I'm missing? Thanks for your help! [1] I don't know why but I think the py2app examples got installed in '/' -- I wonder what I'm doing wrong. |
From: Bob I. <bo...@re...> - 2005-01-19 06:33:45
|
On Jan 19, 2005, at 1:17, ytrewq1 wrote: > On Tue, 18 Jan 2005 04:08:34 -0500, Bob Ippolito <bo...@re...> > wrote: >> >> You should probably go ahead and use svn trunk of py2app (0.1.8) and >> PyObjC (1.3a0), I deprecated objc.registerPlugin today and came up >> with >> a better way of doing it that requires less effort. The documentation >> is up to date. >> >> http://svn.red-bean.com/pyobjc/trunk/pyobjc/NEWS.txt > > Thanks for this. I've pulled down svn trunk for both and installed > them [1]. ... > [1] I don't know why but I think the py2app examples got installed in > '/' -- > I wonder what I'm doing wrong. The installer packages are not in sync with the code. For early development, I use "python setup.py install" for PyObjC, and I have a pth file that points to my py2app source tree (no installation necessary). I've been rewriting bits of bdist_mpkg, and will probably have the installer packages working correctly again tonight. Sorry about that, I should change the message it displays in svn trunk. I'll probably add a distutils command to the PyObjC setup scripts that will create pth files that allow you to install in "developer" mode.. which will just make pth files for you that point to the build directory of PyObjC and the source directory of py2app. >>> 1) It'll work for QS plug-ins (I don't imagine it won't) >>> 2) I can package up PyObjC in a way that doesn't require it having to >>> live in each PyObjC plug-in (my current approach has a post 1.1 pre >>> 1.2 version of PyObjC living in a plug-in which all other PyObjC >>> plug-ins reference) >> >> If you included it in every plugin, it would just load whichever one >> comes first since sys.modules is global. If you have one plugin that >> always loads first, then you can simply exclude it from every other >> Python-based plugin and it should just work. > > PyObjC plug-ins I've built that include PyObjC bits tend to be larger > than > 1 MB and QS plug-ins are typically a fair bit smaller (e.g. less than > 100 kB). > The author of QS is not too keen on larger plug-ins -- which is one of > the > reasons I'd packaged up PyObjC separately and had the other plug-ins > depend on it. > > I've made some Makefiles to prune PyObjC bits from lib-dynload and > site-packages.zip -- does that sound like a reasonable approach or is > there a way to prevent certain items from getting included that I'm > missing? If you use --excludes=objc,Foundation,AppKit,PyObjCTools it will probably do that. The "PyObjC plugin" will probably want to have "import objc; import Foundation; import AppKit" in its source code (so that it doesn't pick up the tests) and --includes=PyObjCTools.* (should include the whole package, but still make it into the zip file). The module/package dependency stuff in py2app is currently really only suited for standalone packaging, but it'll grow built-in support for your use case eventually. -bob |
From: Ronald O. <ron...@ma...> - 2005-01-19 20:05:27
|
On 18-jan-05, at 10:08, Bob Ippolito wrote: > > You should probably go ahead and use svn trunk of py2app (0.1.8) and > PyObjC (1.3a0), I deprecated objc.registerPlugin today and came up > with a better way of doing it that requires less effort. The > documentation is up to date. > > http://svn.red-bean.com/pyobjc/trunk/pyobjc/NEWS.txt One thing that should be documented is that objc.currentBundle() only works correctly during initialisation of a plugin. objc.currentBundle() will always return the last python-based bundle that was loaded (unless I completely misunderstand the code. The same is probably true of __bundle_hack__ and the code that replaces it. BTW. This should not be a problem in most programs. Ronald |
From: Bob I. <bo...@re...> - 2005-01-19 20:19:11
|
On Jan 19, 2005, at 15:05, Ronald Oussoren wrote: > On 18-jan-05, at 10:08, Bob Ippolito wrote: >> >> You should probably go ahead and use svn trunk of py2app (0.1.8) and >> PyObjC (1.3a0), I deprecated objc.registerPlugin today and came up >> with a better way of doing it that requires less effort. The >> documentation is up to date. >> >> http://svn.red-bean.com/pyobjc/trunk/pyobjc/NEWS.txt > > One thing that should be documented is that objc.currentBundle() only > works correctly during initialisation of a plugin. > objc.currentBundle() will always return the last python-based bundle > that was loaded (unless I completely misunderstand the code. objc.currentBundle() will always return the current effective bundle. The py2app bootstrap will swap this environment variable before and after the bundle runs, so if a plugin happens to load another plugin mid-script it will just work. Basically, as soon as that PyRun_File returns the environment variable will be swapped back. If there is nothing on this "stack" of current bundles, then it will return mainBundle. > The same is probably true of __bundle_hack__ and the code that > replaces it. > > BTW. This should not be a problem in most programs. NSBundle.bundleForClass_(SomeClass) should be used to find the current bundle in code that is not effectively module-level... the same as you do in Objective-C. objc.currentBundle() shouldn't typically be necessary from user code, since the implementation of NibClassBuilder uses it. -bob |
From: Ronald O. <ron...@ma...> - 2005-01-20 10:21:13
|
On 19-jan-05, at 21:19, Bob Ippolito wrote: > >> The same is probably true of __bundle_hack__ and the code that >> replaces it. >> >> BTW. This should not be a problem in most programs. > > NSBundle.bundleForClass_(SomeClass) should be used to find the current > bundle in code that is not effectively module-level... the same as you > do in Objective-C. > > objc.currentBundle() shouldn't typically be necessary from user code, > since the implementation of NibClassBuilder uses it. I still think that objc.currentBundle should mention that it supposed to be used during the initialisation of a program or plugin. Ronald |
From: Bob I. <bo...@re...> - 2005-01-20 11:09:18
|
On Jan 20, 2005, at 5:21 AM, Ronald Oussoren wrote: > On 19-jan-05, at 21:19, Bob Ippolito wrote: > >> >>> The same is probably true of __bundle_hack__ and the code that >>> replaces it. >>> >>> BTW. This should not be a problem in most programs. >> NSBundle.bundleForClass_(SomeClass) should be used to find the >> current bundle in code that is not effectively module-level... the >> same as you do in Objective-C. >> >> objc.currentBundle() shouldn't typically be necessary from user code, >> since the implementation of NibClassBuilder uses it. > I still think that objc.currentBundle should mention that it supposed > to be used during the initialisation of a program or plugin. > Ok, doc string is updated in r1371 >>> import objc >>> print objc.currentBundle.__doc__ currentBundle() -> bundle Get the current bundle during module initialization. Works for plug-ins and applications. Note that this is the default bundle used by NibClassBuilder.extractClasses(...), so calling it explicitly is rarely useful. After module initialization, use NSBundle.bundleForClass_(ClassInYourBundle). -bob |