Thread: [Pyobjc-dev] Detecting Python interpreters on startup
Brought to you by:
ronaldoussoren
From: Dinu G. <gh...@da...> - 2003-09-05 07:07:48
|
Hi, I got the following request, which makes me wonder how the one Python interpreter is located running PyObjC applications? > I was very impressed with the movie of reSTedit. As I use reST all > the time, I down-loaded it, When I tried to run it on my Mac (10.2.6) > by double-clickign the application, it started and then closed without > any screen coming up. I normally run Python 2.3 via XDarwin (a Fink > load) but I do have Python 2.2.1 in my Applications. In my bin-python-main.py (which might not be the newest one) I found the following snippet: ## bin-python-main.py // figure out which python interpreter to use NSString *pythonBinPath = [[NSUserDefaults standardUserDefaults] stringForKey: @"PythonBinPath"]; pythonBinPath = pythonBinPath ? pythonBinPath : @"/usr/bin/python"; Is this hardwiring /usr/bin/python as the one interpreter to use? Or has this been determined at "project instantiation time" using the Python-Cocoa Application template? What is the general policy in chosing between possibly many installed Python interpreters and/or can this decission be delayed until the launch time of an application and how? Thanks, Dinu -- Dinu C. Gherman ...................................................................... "Political satire became obsolete when Henry Kissinger was awarded the Nobel Peace Prize." (Tom Lehrer) |
From: Just v. R. <ju...@le...> - 2003-09-05 13:25:28
|
Dinu Gherman wrote: > I got the following request, which makes me wonder how the one Python > interpreter is located running PyObjC applications? > > > I was very impressed with the movie of reSTedit. As I use reST all > > the time, I down-loaded it, When I tried to run it on my Mac > > (10.2.6) by double-clickign the application, it started and then > > closed without any screen coming up. I normally run Python 2.3 via > > XDarwin (a Fink load) but I do have Python 2.2.1 in my > > Applications. > > In my bin-python-main.py (which might not be the newest one) I found > the following snippet: > > ## bin-python-main.py > > // figure out which python interpreter to use > NSString *pythonBinPath = [[NSUserDefaults standardUserDefaults] > stringForKey: @"PythonBinPath"]; > pythonBinPath = pythonBinPath ? pythonBinPath : @"/usr/bin/python"; > > Is this hardwiring /usr/bin/python as the one interpreter to use? Or > has this been determined at "project instantiation time" using the > Python-Cocoa Application template? > > What is the general policy in chosing between possibly many installed > Python interpreters and/or can this decission be delayed until the > launch time of an application and how? Apps built with bundlebuilder.py also hard-wire /usr/bin/python, but only as the #! line of the bootstrap script. If someone _deletes_ /usr/bin/python, he/she has a broken system. People should simply not touch /usr/bin, period. Just |
From: Zachery B. <zb...@ur...> - 2003-09-05 13:39:12
|
On Friday, September 5, 2003, at 09:25 AM, Just van Rossum wrote: > Apps built with bundlebuilder.py also hard-wire /usr/bin/python, but > only as the #! line of the bootstrap script. If someone _deletes_ > /usr/bin/python, he/she has a broken system. People should simply not > touch /usr/bin, period. No doubt, but I think Dinu's pointing out that his friend prefers using /usr/local/bin/python2.3 (or the like) Zac |
From: Just v. R. <ju...@le...> - 2003-09-05 13:54:16
|
Zachery Bir wrote: > No doubt, but I think Dinu's pointing out that his friend prefers > using /usr/local/bin/python2.3 (or the like) If you're shipping an app that is meant to run with the Apple-privided 2.2, it should be run with that. Why would an end user have anything to say about that? Or do I still miss the point of the question? Quite possible, since I have trouble thinking clearly again today... Just |
From: Dinu G. <gh...@da...> - 2003-09-05 14:16:04
|
Just van Rossum: > Zachery Bir wrote: > >> No doubt, but I think Dinu's pointing out that his friend prefers >> using /usr/local/bin/python2.3 (or the like) > > If you're shipping an app that is meant to run with the Apple-privided > 2.2, it should be run with that. Why would an end user have anything to > say about that? Or do I still miss the point of the question? Quite > possible, since I have trouble thinking clearly again today... The person uses Fink Python 2.3 on 10.2.6, so I think that if he never touched his /usr/bin/python it shouldl still be a more or less broken Python 2.1, but I'll sort this out... Anyway... The real question for me is: given multiple options for locations and versions of installed Python interpreters on OS X, is there any possibility to deploy an application that has the following properties: 1. it finds and uses the one Python interpreter if there is only one, 2. it can be told at launch time or via some kind of config file before launch time which interpreter to use, 3. it makes its own "best choice" for 2. I think nobody wants to maintain different packages for people be- longing to either Fink-, Apple-, Mac-Python and any other camps. And for testing with different interpreters (even of the same camp) this would also be very useful. Dinu -- Dinu C. Gherman ...................................................................... "I am a gentlemen: I live by robbing the poor." (George Bernard Shaw) |
From: Just v. R. <ju...@le...> - 2003-09-05 14:41:34
|
Dinu Gherman wrote: > The person uses Fink Python 2.3 on 10.2.6, so I think that if he > never touched his /usr/bin/python When he wrote """When I tried to run it on my Mac (10.2.6) by double-clickign the application, it started and then closed without any screen coming up""" I immediately thought: his /usr/bin/python is broken or gone. We'll never know for sure until we see what's in his Console.app. [ ... ] > The real question for me is: given multiple options for locations > and versions of installed Python interpreters on OS X, is there > any possibility to deploy an application that has the following > properties: > > 1. it finds and uses the one Python interpreter if there is > only one, > > 2. it can be told at launch time or via some kind of config > file before launch time which interpreter to use, > > 3. it makes its own "best choice" for 2. > > I think nobody wants to maintain different packages for people be- > longing to either Fink-, Apple-, Mac-Python and any other camps. > And for testing with different interpreters (even of the same camp) > this would also be very useful. It's moderately safe to make your app dependent on Jag's 2.2 (most things should work when running under Panther, but you can't know for sure. It's safe if Jaguar is all you need to support (unless someone breaks his sistem by messing with /usr/bin/python). Extension modules are not always compatible between Python versions. Due to sheer luck it appears that extension modules linked against a flat unix build also work when used with a framework build, but the other way round does not work. If you really want to use an installed version, you should just specify exactly which one. For end user apps, the best thing to do is INCLUDE the Python you're testing and building with with your app bundle. Luckily bundlebuilder makes this very easy. Use --standalone, with --strip to reduce the size of the bundle. Using Python 2.3 enables zipimport, making your .app smaller yet. I built a tiny standalone PyObjC app today, and compressed with StuffIt it's a 1 meg download. This includes a (stripped down version of) Python.framework. "python2.3 buildapp.py --standalone --strip build" was all there was to it. Just |
From: Dinu G. <gh...@da...> - 2003-09-05 15:51:12
|
Just van Rossum: > When he wrote """When I tried to run it on my Mac (10.2.6) by > double-clickign the application, it started and then closed without any > screen coming up""" I immediately thought: his /usr/bin/python is > broken > or gone. We'll never know for sure until we see what's in his > Console.app. That's (at least partly) entirely my fault, so let's ignore that... > For end user apps, the best thing to do is INCLUDE the Python you're > testing and building with with your app bundle. Luckily bundlebuilder > makes this very easy. Use --standalone, with --strip to reduce the size > of the bundle. Using Python 2.3 enables zipimport, making your .app > smaller yet. I built a tiny standalone PyObjC app today, and compressed > with StuffIt it's a 1 meg download. This includes a (stripped down > version of) Python.framework. "python2.3 buildapp.py --standalone > --strip build" was all there was to it. Yes, that's probably the best thing to do. I sniffed more into bundlebuilder now. On 2.3 it seems to use a modulefinder, ok... I wasn't quite aware how cool it is! But... when creating two vanilla PB projects from the PyCocoaApp and PyCocoaDocApp templates and adjusting the buildapp.py script as below (run with python buildapp.py --standalone --strip build) I get a working app only for the single document version. The multi- document version launches, but never shows any window. Any idea? What's the role of the myseterious Main.py files in some of the sample projects? Thanks, Dinu PS: I think "#! /usr/bin/env python" should be really preferred over "#! /usr/local/bin/python"... #! /usr/bin/env python import os from bundlebuilder import buildapp src = [ fn for fn in os.listdir('.') if fn.endswith('.py') and fn not in ('buildapp.py',) ] buildapp( name = "TestTest2", mainprogram = "__main__.py", resources = ["English.lproj"] + src, nibname = "MainMenu", ) |
From: Just v. R. <ju...@le...> - 2003-09-05 16:06:57
|
Dinu Gherman wrote: > Yes, that's probably the best thing to do. I sniffed more into > bundlebuilder now. On 2.3 it seems to use a modulefinder, ok... I > wasn't quite aware how cool it is! Actually, it does so with 2.2 as well, provided modulefinder.py is installed. The only thing it can't use with 2.2 is zipimport, so 2.2 .app bundles are somewhat larger. Ronald: I think modulefinder.py should be included with PyObjC in MPCompat, next to bundlebuilder.py and plistlib.py. Would you agree? Just |
From: Ronald O. <ous...@ci...> - 2003-09-05 16:16:13
|
On 5 sep 2003, at 18:06, Just van Rossum wrote: > Dinu Gherman wrote: > >> Yes, that's probably the best thing to do. I sniffed more into >> bundlebuilder now. On 2.3 it seems to use a modulefinder, ok... I >> wasn't quite aware how cool it is! > > Actually, it does so with 2.2 as well, provided modulefinder.py is > installed. The only thing it can't use with 2.2 is zipimport, so 2.2 > .app bundles are somewhat larger. > > Ronald: I think modulefinder.py should be included with PyObjC in > MPCompat, next to bundlebuilder.py and plistlib.py. Would you agree? I do, please check it in. The --standalone option is very usefull. BTW. I don't think useing 'whatever python the user has installed' would be useful, unless you don't test applications before releasing them :-) Ronald |
From: Bob I. <bo...@re...> - 2003-09-05 16:27:59
|
On Friday, Sep 5, 2003, at 12:15 America/New_York, Ronald Oussoren wrote: > > On 5 sep 2003, at 18:06, Just van Rossum wrote: > >> Dinu Gherman wrote: >> >>> Yes, that's probably the best thing to do. I sniffed more into >>> bundlebuilder now. On 2.3 it seems to use a modulefinder, ok... I >>> wasn't quite aware how cool it is! >> >> Actually, it does so with 2.2 as well, provided modulefinder.py is >> installed. The only thing it can't use with 2.2 is zipimport, so 2.2 >> .app bundles are somewhat larger. >> >> Ronald: I think modulefinder.py should be included with PyObjC in >> MPCompat, next to bundlebuilder.py and plistlib.py. Would you agree? > > I do, please check it in. The --standalone option is very usefull. > > BTW. I don't think useing 'whatever python the user has installed' > would be useful, unless you don't test applications before releasing > them :-) Yeah, other than saving bandwidth there is no good reason to NOT include a tested and working version of Python with your executable. You can say on the distribution page: download SMALLER VERSION if you have OS X 10.3 installed, or have installed MacPython 2.3 yourself in OS X 10.2.X download LARGER VERSION otherwise Most people have bandwidth to spare these days. On the distribution end, there's always SourceForge (assuming you're an open source developer). It would be interesting if SMALLER VERSION would be able to detect if it is running on the proper system (maybe a C bootstrap, or python 2.2) before doing anything, and if it's not running on a capable system then it would pop up a dialog box with instructions for how to download the LARGER version or install MacPython 2.3. -bob |
From: Dinu G. <gh...@da...> - 2003-09-05 22:49:43
|
I wrote: > But... when creating two vanilla PB projects from the PyCocoaApp > and PyCocoaDocApp templates and adjusting the buildapp.py script > as below (run with python buildapp.py --standalone --strip build) > I get a working app only for the single document version. The multi- > document version launches, but never shows any window. Any idea? > What's the role of the myseterious Main.py files in some of the > sample projects? I still don't think I understand how to convert an existing PB project into one to be created by bundlebuilder. The existing PyObjC samples rarely use multiple NIB files and I'm missing some short description of what the "canonical" way of writing a call to bundlebuilder really is... Thanks for any insight, Dinu -- Dinu C. Gherman ...................................................................... "There are causes worth dying for, but none worth killing for." (Albert Camus) |
From: Just v. R. <ju...@le...> - 2003-09-06 11:12:05
|
Dinu Gherman wrote: > > But... when creating two vanilla PB projects from the PyCocoaApp > > and PyCocoaDocApp templates and adjusting the buildapp.py script > > as below (run with python buildapp.py --standalone --strip build) > > I get a working app only for the single document version. The multi- > > document version launches, but never shows any window. Any idea? > > What's the role of the myseterious Main.py files in some of the > > sample projects? > > I still don't think I understand how to convert an existing PB > project into one to be created by bundlebuilder. The existing > PyObjC samples rarely use multiple NIB files and I'm missing > some short description of what the "canonical" way of writing > a call to bundlebuilder really is... > > Thanks for any insight, Multi-doc app: make sure you either create an Info.plist file or manually create a plist object in your buildapp.py script. Example of the latter: from bundlebuilder import buildapp from plistlib import Plist, Dict, True plist = Plist( CFBundleDocumentTypes = [ Dict( CFBundleTypeExtensions = ["*"], CFBundleTypeName = "Universal Font Object", LSTypeIsPackage = True, CFBundleTypeRole = "Viewer", NSDocumentClass = "GlyphSetDocument", ), Dict( CFBundleTypeExtensions = ["ttf", "otf"], CFBundleTypeName = "OpenType Font", CFBundleTypeRole = "Viewer", NSDocumentClass = "GlyphSetDocument", ), Dict( CFBundleTypeExtensions = ["pfb", "pfa"], CFBundleTypeName = "Type1 Font", CFBundleTypeRole = "Viewer", NSDocumentClass = "GlyphSetDocument", ), Dict( CFBundleTypeExtensions = ["*"], CFBundleTypeOSTypes = ["LWFN"], CFBundleTypeName = "Type1 Font", CFBundleTypeRole = "Viewer", NSDocumentClass = "GlyphSetDocument", ), ] ) buildapp( mainprogram = "GlyphViewer.py", resources = ["MainMenu.nib", "GlyphSetWindow.nib"], nibname = "MainMenu", plist = plist, ) Alternatively you can add --plist=myinfo.plist to the command line, or replace the above with plist = Plist.fromFile("myinfo.plist") Just |
From: Dinu G. <gh...@da...> - 2003-09-06 15:29:29
|
Just van Rossum: > Multi-doc app: make sure you either create an Info.plist file or > manually create a plist object in your buildapp.py script. I've tried that, but I still don't get it. It's not clear what kind of entries I need for what kind of file (file types?)? You example has too much of a font context for me... Also, I'm uncertain if I really need a new Main.py or if the template's __main__.py will do and what the Main.py file should contain compared to __main__.py? Let's make a laboratory experiment. If it works out ok, I'll become a very happy user of bundlebuilder! let's use the PB template for a "Cocoa Python Document-based Application" and save it using a name like CocoaPyDocApp. "pbxbuild build" turns that into an application just as I'd expect it. Before running it I have this list of files: dinu% tree2.py -f CocoaPyDocApp/ | / | | 00README.txt | | __main__.py | | bin-python-main.m | | CocoaPyDocApp.pbproj/ | | | dinu.pbxuser | | | project.pbxproj | | English.lproj/ | | | Credits.rtf | | | InfoPlist.strings | | | MainMenu.nib/ | | | | classes.nib | | | | info.nib | | | | keyedobjects.nib | | | MyDocument.nib/ | | | | classes.nib | | | | info.nib | | | | objects.nib | | MyAppDelegate.py | | MyDocument.py After running "pbxbuild build" I get this list (only the output app wrapper is listed): dinu% tree2.py -f CocoaPyDocApp/ | / | | build/ | | | CocoaPyDocApp.app/ | | | | Contents/ | | | | | Info.plist | | | | | MacOS/ | | | | | | CocoaPyDocApp | | | | | pbdevelopment.plist | | | | | PkgInfo | | | | | Resources/ | | | | | | __main__.py | | | | | | English.lproj/ | | | | | | | Credits.rtf | | | | | | | InfoPlist.strings | | | | | | | MainMenu.nib/ | | | | | | | | classes.nib | | | | | | | | info.nib | | | | | | | | keyedobjects.nib | | | | | | | MyDocument.nib/ | | | | | | | | classes.nib | | | | | | | | info.nib | | | | | | | | objects.nib | | | | | | MyAppDelegate.py | | | | | | MyDocument.py I can safely remove the pbdevelopment.plist and the app still launches ok. So I guess all your plist magic deals with generating the Info.plist, right? Ok, let's keep going. Remove the build folder after copying the following file to some safe place: build/CocoaPyDocApp.app/Contents/Info.plist . Write a simpple buildapp.py like this in the project root folder: #! /usr/bin/env python from bundlebuilder import buildapp buildapp( name = "CocoaPyDocApp", mainprogram = "__main__.py", resources = ["English.lproj", "MyAppDelegate.py", "MyDocument.py"], nibname = "MainMenu", ) Now rebuild the application using "buildapp.py build". This is what we get (only app wrapper listed): [localhost:~/Developer/Cocoa/CocoaPyDocApp] dinu% tree2.py -f . ./ | build/ | | CocoaPyDocApp.app/ | | | Contents/ | | | | Info.plist | | | | MacOS/ | | | | | CocoaPyDocApp | | | | | python | | | | PkgInfo | | | | Resources/ | | | | | __main__.py | | | | | English.lproj/ | | | | | | Credits.rtf | | | | | | InfoPlist.strings | | | | | | MainMenu.nib/ | | | | | | | classes.nib | | | | | | | info.nib | | | | | | | keyedobjects.nib | | | | | | MyDocument.nib/ | | | | | | | classes.nib | | | | | | | info.nib | | | | | | | objects.nib | | | | | MyAppDelegate.py | | | | | MyDocument.py As expected this application doesn't work as it should. It starts up, but doesn't show any window! But... drumrolls...! If you replace its top Info.plist with the one previously saved the app runs just fine!! The big question then is how to generate this Info.plist below using bundlebuilder tool?? (At least it seems like I could simply keep the __main__.py file.) Also, the same copy-trick works when using the longer version: "buildapp.py --standalone --strip build". Your-turn-again,-Sherlock'ly, Dinu <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeExtensions</key> <array> <string>????</string> </array> <key>CFBundleTypeName</key> <string>DocumentType</string> <key>CFBundleTypeOSTypes</key> <array> <string>????</string> </array> <key>CFBundleTypeRole</key> <string>Editor</string> <key>NSDocumentClass</key> <string>MyDocument</string> </dict> </array> <key>CFBundleExecutable</key> <string>CocoaPyDocApp</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>0.1</string> <key>NSMainNibFile</key> <string>MainMenu</string> <key>NSPrincipalClass</key> <string>NSApplication</string> </dict> </plist> |
From: Just v. R. <ju...@le...> - 2003-09-06 16:40:53
|
Dinu Gherman wrote: > > Multi-doc app: make sure you either create an Info.plist file or > > manually create a plist object in your buildapp.py script. > > I've tried that, but I still don't get it. It's not clear what kind > of entries I need for what kind of file (file types?)? You example > has too much of a font context for me... Well, check what you get when you do Plist.fromFile("yourplist"). You only need to fill in those values that bundlebuilder can fill in for you, in many cases you only need to worry about CFBundleDocumentTypes. I can't be bothered to compare directory structures, but I'll do you the favor of translating the relevant portion of your Info.plist to Python. See below. > I can safely remove the pbdevelopment.plist and the app still launches > ok. So I guess all your plist magic deals with generating the > Info.plist, > right? Ok, let's keep going. Why do you think it's magic? The "plist" argument of buildapp is indeed for Info.plist, it does nothing else. Read the source, it's pretty simple. Bundlebuilder usually creates one for you, but you can give it one for stuff it can't guess, such as CFBundleDocumentTypes. > As expected this application doesn't work as it should. It starts up, > but doesn't show any window! But... drumrolls...! If you replace its > top Info.plist with the one previously saved the app runs just fine!! Which is why (drumroll!) I pointed you towards buildapp's plist to begin with. Snipping those entries filled in by bundlebuilder if not given: > <?xml version="1.0" encoding="UTF-8"?> > <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" > "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> > <plist version="1.0"> > <dict> [ ... ] > <key>CFBundleDocumentTypes</key> > <array> > <dict> > <key>CFBundleTypeExtensions</key> > <array> > <string>????</string> > </array> > <key>CFBundleTypeName</key> > <string>DocumentType</string> > <key>CFBundleTypeOSTypes</key> > <array> > <string>????</string> > </array> > <key>CFBundleTypeRole</key> > <string>Editor</string> > <key>NSDocumentClass</key> > <string>MyDocument</string> > </dict> > </array> [ ... ] > </dict> > </plist> plist = Plist( CFBundleDocumentTypes = [ Dict( CFBundleTypeExtensions = ["????"], CFBundleTypeName = "DocumentType", CFBundleTypeOSTypes = ["???"], CFBundleTypeRole = "Editor", NSDocumentClass = "MyDocument", ), ] ) Instead of plistlib's Dict() you can also use 2.3's dict(), it also accepts keyword args to construct the dict. The following is equivalent to the above: plist = Plist() plist.update({ "CFBundleDocumentTypes": [ { "CFBundleTypeExtensions": ["????"], "CFBundleTypeName": "DocumentType", "CFBundleTypeOSTypes": ["???"], "CFBundleTypeRole": "Editor", "NSDocumentClass": "MyDocument", }, ] }) Just |
From: Dinu G. <gh...@da...> - 2003-09-06 18:14:40
|
Just van Rossum: > I can't be bothered to compare directory structures, but I'll do you > the > favor of translating the relevant portion of your Info.plist to Python. > See below. Thanks! I didn't mean to bother you, but while taking notes and executing commands I was happy to find some hackish way to get a working app... I'm making progress in understanding what's going on and will look deeper into the source. Something I seem to miss in bundlebuilder is the ability to build not only in a specific output directory but also to take an in- put from a specific directory. At least the options below don't indicate this. Maybe this is because bundlebuilder try following the philosophy of Distutils? BTW, what about having bundlebuilder as a plugin for Distutils, so you can generate OS X bundles, like RPMs, say? Here is a result of a maybe useful application that I've just build with Python included, please let me know if it causes any strange (startup) effects for any of you: http://python.net/~gherman/RegexPlor.html Thanks and regards, Dinu Usage: python bundlebuilder.py [options] command python mybuildscript.py [options] command Commands: build build the application report print a report Options: -b, --builddir=DIR the build directory; defaults to "build" -n, --name=NAME application name -r, --resource=FILE extra file or folder to be copied to Resources -e, --executable=FILE the executable to be used -m, --mainprogram=FILE the Python main program -p, --plist=FILE .plist file (default: generate one) --nib=NAME main nib name -c, --creator=CCCC 4-char creator code (default: '????') -l, --link symlink files/folder instead of copying them --link-exec symlink the executable instead of copying it --standalone build a standalone application, which is fully independent of a Python installation -x, --exclude=MODULE exclude module (with --standalone) -i, --include=MODULE include module (with --standalone) --package=PACKAGE include a whole package (with --standalone) --strip strip binaries (remove debug info) -v, --verbose increase verbosity level -q, --quiet decrease verbosity level -h, --help print this message |
From: Just v. R. <ju...@le...> - 2003-09-06 11:08:41
|
Dinu Gherman wrote: > #! /usr/bin/env python > > import os > from bundlebuilder import buildapp > > src = [ fn for fn in os.listdir('.') > if fn.endswith('.py') and fn not in ('buildapp.py',) ] > > buildapp( > name = "TestTest2", > mainprogram = "__main__.py", > resources = ["English.lproj"] + src, > nibname = "MainMenu", > ) Btw, you don't *need* to include all sources from "." as resources, _as_long_as_ you either use --standalone or --link. With --link, you basically create an applet that contains symlinks to everything you specify, so it's very much tied to your setup. But: also the main .py program is symlinked, and with the way Python handles the main script, it turns out the the directory of the _original_ main script (not the dir that contains the symlink!) gets on sys.path. So things "just work". (But the truly best thing about --link is that you don't have to rebuild your app(let) when you edit sources or nibs!) And with --standalone, modulefinder.py will pick up the needed modules anyway, so you *also* don't need to add your other modules to the resources list. In retrospect, I find the option-less "python buildapp.py build" invocation pretty useless. I personally never use it. Time to write documentation! :) Just |