[Pythonmac-SIG] py2app standalone options

Bob Ippolito bob at redivi.com
Fri Dec 24 00:04:27 CET 2004


On Dec 23, 2004, at 5:25 PM, Dethe Elza wrote:

> With regards to refactoring setup.py files, here is what I've been 
> using for several different apps.  It has evolved as I've found new 
> requirements.
>
> The only things I have to change from app to app (at this point) are 
> the bits in ALL_CAPS at the beginning.  I've been meaning to factor 
> all of this into something like a function + .cfg, but haven't gotten 
> there yet, so I just copy this into  a new project and edit the few 
> lines that change.
>
> HTH
>
> --Dethe
>
> <snip>
> '''
> Run with:
> % python setup.py py2app
> '''
> from distutils.core import setup
> import py2app
>
> NAME = 'Oblique Strategies'
> SCRIPT = 'oblique.py'
> VERSION = '0.3'
> ICON = NAME
> ID = 'oblique_strategies'
> COPYRIGHT = 'Copyright 2004 Dethe Elza'
> DATA_FILES = ['English.lproj', 'data', 'MainMenu.gsmarkup', 
> 'MainWindow.gsmarkup', 'Credits.html']
>
> plist = dict(
>     CFBundleIconFile            = ICON,
>     CFBundleName                = NAME,
>     CFBundleShortVersionString  = ' '.join([NAME, VERSION]),
>     CFBundleGetInfoString       = NAME,
>     CFBundleExecutable          = NAME,
>     CFBundleIdentifier          = 'org.livingcode.examples.%s' % ID,
>     NSHumanReadableCopyright    = COPYRIGHT
> )
>
>
> app_data = dict(script=SCRIPT, plist=plist)
> py2app_opt = dict(frameworks=['Renaissance.framework'],)
> options = dict(py2app=py2app_opt,)
>
> setup(
>   data_files = DATA_FILES,
>   app = [app_data],
>   options = options,
> )

This looks pretty good to me.  I would put MainMenu.gsmarkup, 
MainWindow.gsmarkup, and Credits.html in English.lproj. -[NSBundle 
pathForResource:ofType:] and friends will look in localized 
directories.. so it saves you some typing and symlinks (in the case of 
an alias bundle).

It's not really useful to set CFBundleExecutable.  It doesn't matter 
what the executable's name is.  It will default to the name of the 
script you give it.
CFBundleName defaults to CFBundleExecutable, so if your script is named 
the same as your application you don't need to set this.
CFBundleIcon will default to the CFBundleExecutable, so if you name 
your icon the same as your script and throw it in English.lproj, you 
don't need to set this.
(reference py2app.apptemplate.plist_template and/or 
py2app.bundletemplate.plist_template to see this behavior for yourself)

The copyright, bundle identifier, info strings, version, etc. are not 
defaulted to anything particularly useful.. so it is a good idea to set 
those in an application for general distribution.

Since py2app doesn't really support multiple targets in a single 
setup(...) in a particularly useful way (and won't for some time, would 
require a hefty refactoring), you can make app = [SCRIPT] and add 
plist=plist to py2app_opt.

--

For the plist template, in the future, it may be worthwhile to have 
some flag that can take a plist file and do PEP-292 on its string 
values <http://www.python.org/peps/pep-0292.html>.  That way you can 
have a template plist file on-disk.  I'm not sure precisely how this 
should work, but I'll probably look to Xcode for a friendly-ish way to 
do things.

At some point, I may walk the module dependency graph to find direct 
dependencies in the objc module and do a little bytecode scanning to 
see if I can find "loadBundle" or "loadBundleFunctions" and 
automatically specify those as included frameworks.  Alternatively, I 
might just make it necessary to put some kind of editor turd in the 
file like you have to do for text encoding (because that would work for 
ctypes dependencies too).  That will likely happen at the same time 
PyObjC grows a smarter wrapper-generator that won't need to create 
extension modules as often (probably a PyObjC 1.3 feature).

-bob



More information about the Pythonmac-SIG mailing list