py2app is a Python distutils suite which provides several useful features for distributing Python applications and libraries on the Mac OS X platform. The py2app suite contains the following packages:
py2app:
A distutils command that converts Python scripts into executable Mac OS X applications, able to run without requiring a Python installation. It has been used to create standalone application bundles and plug-ins for open source, commercial, and in-house projects. It is known compatible with GUI frameworks such as wxPython, Tkinter, pygame, PyQt, and PyObjC, but it should work in the context of any framework with little or no effort. It may also be used in conjunction with PyObjC to write plug-ins for Cocoa applications, screen savers, preference panes, etc. This is a complete replacement for the bundlebuilder tool included in the Python standard library.
bdist_mpkg:
Creates Mac OS X installer .mpkg files from Python libraries. Installer packages are familiar to Mac OS X users, provide a safe and easy way to authenticate as root to install privileged files such as headers and scripts. Once a bdist_mpkg distribution has been created, it may be installed to other machines with a similar Python environment without requiring a compiler. Installer packages can be used to do distributed installations with tools such as Apple Remote Desktop or they could be integrated into a custom Mac OS X installation DVD with a tool such as Slipy.
macholib:
Reads and writes the Mach-O object file format. Used by py2app to build a dependency graph of dyld and framework dependencies for your application, and then to copy them into your application and rewrite their load commands to be @executable_path relative. The end result is that your application is going to be completely standalone beyond a default install of Mac OS X. You no longer have to worry about linking all of your dependencies statically, using install_name_tool, etc. It's all taken care of!
modulegraph:
A replacement for the Python standard library modulefinder. Stores the module dependency tree in a graph data structure and allows for advanced filtering and analysis capabilities, such as GraphViz dot output. This is used internally by py2app, but the code should be completely cross-platform. It is hoped that this package will be adopted by application packaging software for other platforms in the future, such as py2exe and cx_Freeze.
altgraph:
This is a fork of Istvan Albert's graphlib, and it used internally by both macholib and modulegraph. It contains several small feature and performance enhancements over the original graphlib.
Any components of the py2app suite may be distributed under the MIT or PSF open source licenses.
Note that the installer for PyObjC 1.2 ships with py2app 0.1.7.
An installer for py2app 0.1.8 may be downloaded from:
The source to py2app 0.1.8 may be downloaded here:
py2app maintains a public subversion source code repository currently located at:
As of version 0.1.6, py2app uses the extra_path feature of distutils, which changes the installation layout. If you have py2app 0.1.5 or earlier installed, you must manually remove the following directories from your site-packages directory (probably /Library/Python/2.3) if they exist before upgrading:
How do I use py2app?
py2app is a distutils command that is used in a similar manner to py2exe. For your application, you must create a Python script (conventionally named setup.py) that looks like the following:
#!/usr/bin/env python """ setup.py - script for building MyApplication Usage: % python setup.py py2app """ from distutils.core import setup import py2app setup( app=['MyApplication.py'], )
When running this script as directed, py2app will do the following:
Process the command line for arguments. The arguments accepted by the py2app command can be enumerated using the following command line:
% python setup.py py2app --help Global options: ... (these are available from any distutils command) Options for 'py2app' command: ... (these are specific to py2app) usage: ... (this is a generic distutils usage message)
Note that any of the options accepted on the command line may also be used in your setup.py script! For example:
#!/usr/bin/env python """ setup.py - script for building MyApplication """ from distutils.core import setup import py2app # Note that you must replace hypens '-' with underscores '_' # when converting option names from the command line to a script. # For example, the --argv-emulation option is passed as # argv_emulation in an options dict. py2app_options = dict( # Map "open document" events to sys.argv. # Scripts that expect files as command line arguments # can be trivially used as "droplets" using this option. # Without this option, sys.argv should not be used at all # as it will contain only Mac OS X specific stuff. argv_emulation=True, # This is a shortcut that will place MyApplication.icns # in the Contents/Resources folder of the application bundle, # and make sure the CFBundleIcon plist key is set appropriately. iconfile='MyApplication.icns', ) setup( app=['MyApplication.py'], options=dict( # Each command is allowed to have its own # options, so we must specify that these # options are py2app specific. py2app=py2app_options, ) )
Issue the distutils build command
Analyze the application for Python dependencies
Make sense of the dependencies
Create the application bundle
Make the application bundle standalone
What recipes does py2app come with?
Locates and includes all plugins that ship with docutils (languages, parsers, readers, writers)
Removes several dependencies that are only used when running the pydoc web server or Tkinter GUI (Tkinter, tty, BaseHTTPServer, mimetools, select, threading, ic, getopt).
Includes the whole pygame package as-is, so that it will locate its data files correctly. This recipe may be improved in the future if pygame undergoes appropriate modifications.
PIL:
Locates and includes all image plugins (Python modules that end with ImagePlugin.py), removes unwanted dependencies on Tkinter.
Includes the whole pyOpenGL package as-is, so that it can read its version file during __init__.py. This recipe may be improved in the future if PyOpenGL undergoes appropriate modifications.
py2app:
Includes the whole py2app package as-is, so that it has copies of the executable and plugin templates. This recipe may be improved in the future if py2app undergoes appropriate modifications.
sip:
If ANY extension that uses sip is detected, include all extensions that use sip. This is necessary because sip generates C code to do its imports, and is thus not trackable by bytecode analysis. The only package known to use sip is PyQt, so what this means is that if you use any of PyQt, then all of it will be included.
Note that recipes are developed on an as-needed basis, and coverage of every single Python library is not possible. If you have trouble with a particular library, please let us know.
The following packages are known to need recipes, but none currently exist:
PEAK:
The workaround is to include PEAK using the packages option.
Anything that uses Pango or GTK+:
These C libraries require data files and environment variables set up. A workaround exists, but one has not yet been written and tested.
wxPython 2.4.x:
A data_files option to include a resource file must be added to setup.py:
#!/usr/bin/env python """ setup.py - workaround for wxPython 2.4.x Usage: % python setup.py py2app """ from distutils.core import setup import py2app setup( app=['test.py'], data_files=[('../Frameworks', [ '/usr/local/lib/libwx_mac-2.4.0.rsrc', ] )], )
The py2app development model
Currently, the best description for the preferred development model when doing py2app based development lives in the PyObjC tutorial.
What is an alias bundle (the --alias option)?
An alias bundle is intended to be used only during development. Alias bundles Are not portable to other machines and are not standalone in any way. Alias bundles have the following features:
An alias bundle is similar to BundleBuilder's --link option, and is roughly equivalent to the idea of Xcode's ZeroLink feature.
What does py2app install?
/Library/Python/2.3 (or your site-packages directory):
A py2app folder containing the py2app, macholib, altgraph, and bdist_mpkg packages. A py2app.pth file is also created, so that this py2app folder is automatically added to your sys.path. This corresponds to the src folder in the py2app sources.
/usr/local/bin:
Several command line tools that make the py2app suite easier to use, see the Tools section. This corresponds to the scripts folder in the py2app sources.
/Developer/Python/py2app/Examples:
Several examples of py2app setup.py scripts of varying complexity. This corresponds to the examples folder in the py2app sources.
/Developer/Applications/Python Tools/py2app:
Several GUI tools and droplets that make the py2app suite easier to use, see the GUI Tools section. This corresponds to the tools folder in the py2app sources.
How does py2app differ from py2exe or cx_Freeze?
What are the similarities between py2app, py2exe, and cx_Freeze?
XXX
What is the canonical way for my application to detect if it is being run in a bundled application environment?
Currently this information is in the pythonmac.org FAQ.
When should I subclass the py2app command?
There are no known cases where this has been necessary, so you probably don't!
Known issues with py2app
Current issues with py2app are reflected in the TODO document in the source tree. The linked document reflects the current development version. Also see the errata in the section about recipes above.
How do I use bdist_mpkg?
bdist_mpkg is intended to package existing Python software that already has a distutils setup.py script.
The easiest way to use the features of bdist_mpkg is simply to use the bdist_mpkg tool, as documented in the Tools section below.
Otherwise, in order to enable the bdist_mpkg command in a given setup.py script, simply add an import bdist_mpkg statement near the top of the setup.py script.
What options does bdist_mpkg accept?
To see the list of options that bdist_mpkg accepts, simply run it with the --help option (this must be done in a directory containing a distutils setup.py script):
% bdist_mpkg --help Global options: ... (these are available from any distutils command) Options for 'bdist_mpkg' command: ... (these are specific to bdist_mpkg) usage: ... (this is a generic distutils usage message)
When should I subclass the bdist_mpkg command?
Subclassing bdist_mpkg is currently necessary in order to add additional features to the installation package, such as documentation, examples, tools, etc.
Currently, the documentation for doing this is the source, and the examples are the source to the py2app and PyObjC setup.py scripts.
The API for bdist_mpkg is not guaranteed to be stable, so avoid subclassing at this time unless you plan to communicate with the author about your requirements and are willing to make changes to accommodate changes in the API as bdist_mpkg improves.
By default, the following tools are installed to /usr/local/bin:
bdist_mpkg:
A convenient way to run the bdist_mpkg distutils command. Equivalent to editing the setup.py in the current directory to import bdist_mpkg and running the following command:
% python setup.py bdist_mpkg --openIf any options are given, then they are given in place of --open.
macho_find:
A tool for finding Mach-O object files using macholib. The arguments may be files or directories. The output of this tool is identical to that of the BSD find command.
macho_standalone:
A tool that makes a valiant attempt to make the given application bundle standalone using macholib using machinery similar, but not identical to, what happens when using py2app. This tool modifies the given application bundle in-place, so you may want to make a backup before performing this operation. This tool works for ANY Mach-O executable bundle, and contains no Python-specific functionality.
py2applet:
A convenient way to run the py2app distutils command without creating a setup.py. The first python script passed as an argument will be the main script, any additional files or directories will be considered as data files. If a file with the .icns extension is passed, it will be used as the application's icon. If a file named Info.plist is given, it will be used as the template for the application's Info.plist. The application will be built with the --argv-emulation on. It is not possible to pass options to py2applet. If you need anything more, you should create a setup.py and use the py2app command in the normal fashion.
By default, the following GUI tools are installed to /Developer/Applications/Python Tools/py2app:
PackageInstaller:
A droplet version of the bdist_mpkg tool, it does not have any interactivity, so it is not possible to use this tool to pass options other than the default. Errors and informational messages will go to the Console.
py2applet:
A droplet version of the py2applet tool. It works in exactly the same way and provides no interactivity. Note that since you have no guarantee of the order of files in the pasteboard, you should drag only one at a time to this script. Errors and informational messages will go to the console.
Copyright (c) 2004, 2005 Bob Ippolito <bob at redivi.com>.