[Pythonmac-SIG] [ANN] PyMacApp - Flexible Executable Stub For Python (v0.2)

Bob Ippolito bob at redivi.com
Thu Mar 4 17:33:14 EST 2004


I've polished off some more things, written documentation (in the 
email, as reST), and added new features.. today's snapshot is here:

	http://undefined.org/python/PyMacApp-0.2.tgz

And now for your documentation reading pleasure..

-----------------------------------------------
  PyMacApp: Flexible Executable Stub For Python
-----------------------------------------------

Introduction
------------

PyMacApp is a Cocoa executable stub for Python that accomplishes the 
following
goals:

- A single binary can run on OS X 10.1 or later, with no recompilation
   required under any circumstance.  Therefore, bundles can be built on 
systems
   without Xcode and/or the SDKs installed.

- It must provide helpful and somewhat customizable errors to the user 
in the
   form of GUI alert panels.

- It must be able to link to one of many possible Python frameworks at
   runtime.  This allows the same executable bundle to run in just about
   any environment, even if the developer does have to explicitly manage
   a separate set of extensions per-framework until we resolve linking 
issues.

- It must be able to gracefully handle Python exceptions, because they 
may
   prevent the application from starting.

- It must not use execve for performance reasons and to ease debugging.

- It should be integrated with BundleBuilder2.

- It should be integrated with Python/PyObjC Xcode templates in source 
and/or
   binary form.

- It should consider non-framework builds of Python, but there are no 
plans
   to test this scenario.

Using PyMacApp
--------------

PyMacApp has three required preconditions for use:

- PyMacApp must be the CFBundleExecutable for your application 
according to
   Info.plist.  It is recommended to rename PyMacApp to agree with the
   name of your application bundle.

- A ``PyRuntimeLocations`` key must be added to your Info.plist, it is 
an
   ordered array of strings.  Here are some examples:

   - Embedded Python 2.3 runtime, as created by BundleBuilder2's 
--standalone option.

     
``@executable_path/../Frameworks/Python.framework/Versions/2.3/Python``


   - User-installed Python 2.3 runtime.

     ``~/Library/Frameworks/Python.framework/Versions/2.3/Python``


   - Vendor-installed Python 2.3 runtime, such as the one in OS X 10.3.

     ``/System/Library/Frameworks/Python.framework/Versions/2.3/Python``

- A main script must be placed in the Resources folder of your 
application
   bundle.  By default, PyMacApp will first check Info.plist for a
   ``PyMainFileNames`` key, which should be an array of possible names as
   strings.  If this key is not present, or if no main script is found, 
then
   these script names are attempted (in this order):

   - ``__main__.py``, ``__main__.pyc``, ``__main__.pyo``

   - ``__realmain__.py``, ``__realmain__.pyc``, ``__realmain__.pyo``

   - ``Main.py``, ``Main.pyc``, ``Main.pyo``

Handling Errors Gracefully
--------------------------

PyMacApp offers alert panels for several common errors that can happen. 
  The
following errors are low level, and their responses can not be 
overridden:

   - The ``PyRuntimeLocations`` key is not present in the Info.plist.

   - No main script could be located.

   - A link error occurred when attempting to load the Python runtime or 
one
     of its symbols.

   - The main script exited with an exception, but there was an error 
acquiring
     the name of the exception type.

In addition to this, several common high level errors can be handled by 
an
error handling script.  There is an optional Info.plist key analagous to
``PyMainFileNames`` called ``PyErrorScripts`, and the additional script 
names
attempted are: ``__error__``, ``__error__.py``, and ``__error__.sh``.  
Note
that the script must be executable (chmod +x), or error handling will 
not
work.  Also note that the script may be written in any language (with 
the
appropriate "hash-bang" line), or may even be a compiled executable.

An error handling script will always receive the user displayable name 
of the
application, such as "PyMacApp" as the first argument.  If no other 
arguments
are received, then there was an error locating a suitable Python 
runtime.
Otherwise, the second argument is the name of the Python exception type
(e.g. "ImportError") and the third argument is the string value of the
exception instance (e.g. "No module named foobar").

The stdout of the script is parsed under the following conditions:

- The newline character is '\n'

- The first line of output is required, and will be the title of the 
error
   dialog (displayed in bold).

- Any additional lines of text are optional, and will be the body of 
the error
   dialog (not displayed in bold).

Additionally, if the last line of the script is in the form

``ERRORURL: http://example.com/detailederror/ View Detailed Error 
Report``

then the "Open Console" button will be replaced with a
"View Detailed Error Report" button that when clicked, will open the
user's default web browser to http://example.com/detailederror/.  If a
title is not provided (just the URL), then the button will be named
"Visit Website".  It is recommended that this is used to direct a user 
to
instructions on how to solve their problem (i.e. download Python, file 
a bug,
etc.).

This is an example ``__error__.sh`` script::

     #!/bin/sh
     if ( test -n "$2" ) ; then
             echo "$1 Error"
             echo "An unexpected error has occurred during execution of 
the main script"
             echo ""
             echo "$2: $3"
             echo ""
             echo "See the Console for a detailed traceback."
     else
             echo "$1 Error"
             echo "MacPython 2.3 is required to run this application.";
             echo "ERRORURL: 
http://homepages.cwi.nl/~jack/macpython/index.html Visit the MacPython 
Website";
     fi

Reference
---------

PYTHONPATH
     This environment variable is set to
     ``"Contents/Resources:Contents/Resources/PyObjC:$PYTHONPATH"``

CFBundleExecutable
     A required Info.plist key, see "Using PyMacApp" and Apple's 
documentation.

PyRuntimeLocations
     A required Info.plist key, see "Using PyMacApp".

PyExecutableName
     An optional Info.plist key representing the name of the python 
executable.
     It will be merged with the found Python runtime location and will 
affect
     sys.executable and sys.prefix.  The default, ``python``, is 
sensible.

PyErrorScripts
     An optional Info.plist key, see "Handling Errors Gracefully".

Known Bugs
----------

- It is not currently possible to use a Py_TRACE_REFS Python runtime as 
the
   PyObject structure does not have the reference count at the head.  It 
is not
   obvious how this could be solved.




More information about the Pythonmac-SIG mailing list