<HTML>
<HEAD>
<TITLE>Using Python 1.5 on the Macintosh</TITLE>
</HEAD>
<BODY>
<H1>Using Python 1.5 on the Macintosh</H1>
<HR>

This document is an introduction to using Python on the Apple
Macintosh.  It does not introduce the language itself, for this you
should refer to the <A
HREF="http://www.python.org/doc/tut/tut.html">Python Tutorial</A> by
Guido van Rossum. This guide more-or-less replaces chapter two of the
tutorial, and provides some additional material. <p>

The tutorial, along with other indispensible documentation like the
library reference and such, is also available in a number of different
formats at <a href="ftp://ftp.python.org/pub/python/doc">
ftp://ftp.python.org/pub/python/doc</a>. The Adobe Acrobat <code>.pdf</code>
files are probably a good choice for reading or printing the documents
from your mac. <p>

There is currently no good tutorial for the mac-specific features of
Python, but to whet your appetite: it has interfaces to many MacOS
toolboxes (quickdraw, sound, quicktime, open scripting, etc) and
various portable toolboxes are available too (Tk, stdwin, complex
numbers, image manipulation, etc). Some <A HREF="index.html">
annotated sample programs</A> are available to give you an idea of
Python's power. <P>

<h2>Invoking the interpreter</h2>

The name of the interpreter may differ on different installations: it
may be called <CODE>PythonFAT</CODE> (for powerpc macs and 68K macs with
CFM68K installed) or <CODE>Python68K</CODE> (for 68K macs). 
It will always
be recognizable by the "16 ton" icon, though. You start the
interpreter in interactive mode by double-clicking its icon: <p>

<img src="html.icons/python.gif"><p>

This should give you a text window with an informative version string
and a prompt, something like the following:
<PRE>
Python 1.5.1 (#122 Aug 27, 1997)  [CW PPC w/GUSI MSL]
Copyright 1991-1997 Stichting Mathematisch Centrum, Amsterdam
&gt;&gt;&gt;
</PRE>
The version string tells you the version of Python, whether it was
built for PPC or 68K macs and possibly some options used to build the
interpreter. If you find a bug or have a question about how the
interpreter works it is a good idea to include the version information
in your message. <p>

At the prompt you can type interactive python commands. See the
tutorial for more information. The interactive window works
more-or-less like a Communication Toolbox or Telnet window: you type
commands at the bottom and terminate them with the <EM>[return]</EM>
or <EM>[enter]</EM> key. Interpreter feedback also appears at the
bottom of the window, and the contents scroll as output is added. You
can use copy and paste in the normal way, but be sure to paste only at
the bottom of the document.

<h2>Creating Python scripts</h2>

The Python interpreter works in a way that is different from what you
would expect of a macintosh program: the interpreter is just that: an
interpreter.  There is no builtin editor or other development
support. Hence, to create a Python script you need an external text
editor. For a first script you can use any editor that can create
plain, unstyled text files, such as <CODE>SimpleText</CODE>. <p>

For more serious scripts, though, it is advisable to use a programmers
editor, such as <CODE>BBEdit</CODE> or <CODE>Alpha</CODE>. BBEdit is
my favorite: it comes in a commercial version but also in a
fully-functional free version <CODE>BBEdit Lite</CODE>. You can
download it from the <A HREF="http://www.barebones.com/">BareBones</A>
site.  The free version will probably provide all the functionality
you will ever need.  Besides the standard edit facilities it has
multi-file searches and many other goodies that can be very handy when
editing programs. <p>

After you have created your script in the editor of your choice you
drop it on the interpreter. This will start the interpreter executing
the script, again with a console window in which the output appears
and in which you can type input if the script requires it. Normally
the interpreter will close the window and quit as soon as the script
is done executing, see below under <A HREF="#startup">startup
options</A> for a way to change this. <p>

<blockquote>
There is a BBEdit extension available that allows you to run Python
scripts more-or-less straight from your bbedit source window. Check
out the <code>Mac:Tools:BBPy</code> folder.
</blockquote>

It is a good idea to have the names of all your scripts end in
<CODE>.py</CODE>. While this is not necessary for standalone scripts
it is needed for modules, and it is probably a good idea to start the
habit now. <p>

If you do not like to start the Python interpreter afresh for each
edit-run cycle you can use the <CODE>import</CODE> statement and
<CODE>reload()</CODE> function to speed things up in some cases.  Here
is Guido's original comment for how to do this, from the 1.1 release
notes: <P>

<BLOCKQUOTE>

Make sure the program is a module file (filename must be a Python
identifier followed by '<CODE>.py</CODE>').  You can then import it
when you test it for the first time.  There are now three
possibilities: it contains a syntax error; it gets a runtime error
(unhandled exception); or it runs OK but gives wrong results.  (If it
gives correct results, you are done testing and don't need to read the
rest of this paragraph. :-) Note that the following is not
Mac-specific -- it's just that on UNIX it's easier to restart the
entire script so it's rarely useful. <P>
  
Recovery from a syntax error is easy: edit the file and import it
again. <P>
  
Recovery from wrong output is almost as easy: edit the file and,
instead of importing it, call the function <CODE>reload()</CODE> with
the module name as argument (e.g., if your module is called
<CODE>foo</CODE>, type <CODE>reload(foo)</CODE>). <P>
  
Recovery from an exception is trickier.  Once the syntax is correct, a
'module' entry is placed in an internal table, and following import
statements will not re-read the file, even if the module's
initialization terminated with an error (one reason why this is done
is so that mutually recursive modules are initialized only once).  You
must therefore force re-reading the module with <CODE>reload()</CODE>,
however, if this happens the first time you try to import the module,
the import statement itself has not completed, and your workspace does
not know the module name (even though the internal table of moduesl
does!).  The trick is to first import the module again, then reload
it.  For instance, <CODE>import foo; reload(foo)</CODE>.  Because the
module object already exists internally, the import statement does not
attempt to execute the module again -- it just places it in your
workspace.  </BLOCKQUOTE>

<h2>Clickable python scripts</h2>

If you create your script with the correct creator and type, creator
<CODE>'Pyth'</CODE> and type <CODE>'TEXT'</CODE>, you can double-click
your script and it will automatically invoke the interpreter. If you
use BBEdit you can tell it about the Python file type by adding it to
the "file types" sections of the preferences. Then, if you save a file
for the first time you can tell BBEdit to save the file as a Python
script through the "options" choice of the save dialog. <p>

The <CODE>Scripts</CODE> folder contains a script
<CODE>fixfiletypes</CODE> that will recursively traverse a folder and
set the correct creator and type for all files ending in
<CODE>.py</CODE>. <p>

<BLOCKQUOTE>
Older releases of Python used the creator code
<CODE>'PYTH'</CODE> in stead of <CODE>'Pyth'</CODE>. If you still have
older Python sources on your system and named them with
<CODE>'.py'</CODE> extension the <CODE>fixfiletypes</CODE> script will
correct them.
</BLOCKQUOTE>

<h2>Interaction with the user</h2>

Normally, the interpreter will check for user input (mouse clicks,
keyboard input) every once in a while, so it is possible to switch to
other applications while a script runs. It is also possible to
interrupt the interpreter with the standard command-period keypress,
this will raise the <CODE>KeyboardInterrupt</CODE> exception. Scripts
may, however, turn off this behaviour to facilitate their own event
handling. Such scripts can only be killed with the
command-option-escape shortcut.

<h2><A NAME="startup">startup options</A></h2>

If the <EM>option</EM> key is depressed when Python starts executing
the interpreter will bring up an options dialog thru which you can
influence the way the interpreter behaves. Keep the option key
depressed until the dialog comes up. <p>

<img src="html.icons/options.gif"><p>

The options modify the interpreters behaviour in the following way: 
<ul>
<li> the interpreter goes to interactive mode (in stead of
exiting) after a script has terminated normally,
<li> for every module imported a line is printed telling you where the
module was loaded from,
<li> do not print the values of expressions executed as statements in
an interactive python (obsolete),
<li> do not buffer stdout and stderr,
<li> print some debugging output during the parsing phase,
<li> keep the output window open when a script terminates.
</ul>
In addition, you can enter a unix-style command line which is passed
to the script in <CODE>sys.argv</CODE>. Sys.argv[0] is always the name
of the script being executed, additional values can be passed
here. Quoting works as expected. <p>

<BLOCKQUOTE>
<EM>Warning:</EM> redirecting standard input or standard output in the
command-line dialog does not work. This is due to circumstances beyond my
control, hence I cannot say when this will be fixed.
</BLOCKQUOTE>

The default options are also settable on a system-wide basis, see the
section on <A HREF="#preferences">editing preferences</A>. <p>

<h2>Module search path</h2>

The module search path, <CODE>sys.path</CODE>, contains the folders
python will search when you import a module. The path is settable on a
system-wide basis (see the preferences section), and normally
comprises the current folder (where the script lives), the
<CODE>Lib</CODE> folder and some of its subfolders and possibly some
more. <p>

<h2>Working folder</h2>

The unix concept of a <I>working directory</I> does not translate
directly to a similar concept on the Macintosh.  To facilitate easy
porting and the use of relative pathnames in scripts the interpreter
simulates a working directory. When a script is started the initial
working directory is the folder where the script lives. In case of an
interactive interpreter the working directory is the folder where the
interpreter lives.  <P>

By the way: the "standard file" folder, the folder that is presented
to the user initially for an <I>open</I> or <I>save</I> dialog, does
<EM>not</EM> follow the Python working directory. Which folder is
initially shown to the user is usually one of (a) the application
folder, (b) the "Documents" folder or (c) the folder most recently
used for such a dialog (in any Python program). This is standard MacOS
behaviour, so don't blame Python for it. The exact behaviour is
settable through a control panel since System 7.5.

<h2>Interactive startup file</h2>

If the folder containing the interpreter contains a file named
<CODE>PythonStartup</CODE> this file is executed when you start an
interactive interpreter. In this file you could import modules you
often use and other such things. <p>


<h2>Compiled python scripts</h2>

Once a python module has been imported the interpreter creates a
compiled version which is stored in a file with the ".py" extension
replaced by ".pyc". These compiled files, with creator
<CODE>'Pyth'</CODE> and type <CODE>'PYC '</CODE> load faster when
imported (because they do not have to be parsed). The <CODE>Lib</CODE>
folder contains a script <CODE>compileall.py</CODE>, running this
script will cause all modules along the python search path to be
precompiled, which will speed up your programs.  Compiled files are
also double-clickable. <p>

<h2>Python resources</h2>

MacPython has the ability to collect a number of compiled modules
together in the resource fork of a single file. This feature is useful
if you distribute a python program and want to minimize clutter: you
can put all the needed modules in a single file (which could even be
the interpreter itself). <p>

If the module search path contains a filename as one of its entries
(as opposed to a folder name, which is the normal case) this file will
be searched for a resource with type <CODE>'PYC '</CODE> and a name
matching the module being imported. <p>

The <CODE>scripts</CODE> folder contains a script
<CODE>PackLibDir</CODE> which will convert a number of modules (or
possibly a complete subtree full of modules) into such a resource
file.

<h2><A NAME="preferences">Setting interpreter preferences</A></h2>

The python interpreter keeps a preferences file in the standard
location in the system folder. In this preferences file it remembers
the default module search path and the default settings for the
runtime options. The preferences are settable via
<CODE>EditPythonPrefs</CODE>. For PPC/cfm68k python this is a standalone
program living in the main Python folder, for 68K python it is a
script in the <CODE>Mac:Scripts</CODE> folder. <p>

The interface to edit the preferences is rather clunky for the current
release. <p>

<img src="html.icons/preferences.gif"><p>

In the editable text field at the top you enter the initial module
search path, using newline as a separator. There are two special
values you can use here: an initial substring <CODE>$(PYTHON)</CODE>
will expand to the Python home folder and a value of
<CODE>$(APPLICATION)</CODE> will expand to the the python application
itself. Note that the text field may extend "beyond the bottom" even
though it does not have a scroll bar. Using the arrow keys works,
though.<p>

The Python home folder $(PYTHON) is initially, when you install Python,
set to the folder where the interpreter lives. You can change it here. <p>

Finally, you can set the default startup options here, through a
sub-dialog.

<h2>Applets</h2>

An applet is a fullblown application written in Python, similar to an
AppleScript applet (and completely different from a Java
applet). Applets are currently supported on PowerPC macintoshes and on
68K macintoshes if you use the CFM68K version of the interpreter,
and are created using the <CODE>BuildApplet</CODE> program. You create an
applet by dropping the python source script onto BuildApplet.
<a href="example2.html">Example 2</a> is a more involved applet
with its own resource file, etc. <p>

Note that while an applet behaves as a fullblown Macintosh application
it is not self-sufficient, so distributing it to a machine without an
installed Python interpreter will not work: it needs the shared python
execution engine <CODE>PythonCore</CODE>, and probably various modules
from the Lib and PlugIns folders. Distributing it to a machine that does
have a Python system will work. <p>

<h2>Customizing applets</h2>

Applets can have their own settings for the startup options and module
search path. Dropping an applet on the <CODE>EditPythonPrefs</CODE>
application allows you to set these, in the same way as
double-clicking EditPythonPrefs allows you to set the system-wide
defaults. <p>

Actually, not only applets but also the interpreter itself can have
non-default settings for path and options. If you make a copy of the
interpreter and drop this copy onto EditPythonPrefs you will have an
interpreter that has a different set of default settings. <p>

<h2>Where to go from here</h2>

The previously mentioned <A
HREF="http://www.python.org/doc/tut/tut.html">Python Tutorial</A> is
an excellent place to start reading if you have never used Python
before. Other documentation such as the library reference manual is
indexed at the <A HREF="http://www.python.org/doc/">Python
Documentation</A> page. <p>

There are some <A HREF="index.html">annotated sample programs</A>
available that show some mac-specific issues, like use of various
toolboxes and creation of Python applets. <p>

The <CODE>Demo</CODE> and <CODE>Mac:Demo</CODE>
folders in the Macintosh distribution
contains a number of other example programs. Most of these are only
very lightly documented, but they may help you to understand some
aspects of using Python. <p>

Finally, there is a <code>Mac:Contrib</code> folder that contains
a few contributions to Python that I couldn't fit in the normal tree
but did want to distribute (many other contributions are contained
throughout the distribution, but you don't see them, really).

The best way to contact fellow Macintosh Python programmers is to join
the MacPython Special Interest Group mailing list. Send a message with
"info" in the body to <A
HREF="mailto:pythonmac-sig-request@python.org">pythonmac-sig-request@python.org</A>
or view the <A
HREF="http://www.python.org/sigs/pythonmac-sig/">Pythonmac SIG
page</A> on the <A HREF="http://www.python.org">www.python.org</A> WWW
server. <p>

<h2>Troubleshooting</h2>

A rather baffling error message can be "PythonCore not found" when you
start the interpreter and you are sure that PythonCore is available. The
message should actually say "Not enough memory in the system heap to
load PythonCore".
Blame Apple for the confusing message. <p>

There appear to be problems with QuickTime for the CFM68K version of the
interpreter. If you experience these please contact the SIG: some people
use quicktime without problems and some not, and we are still hunting for
the cause. <p>

Python is a rather safe language, and hence it should be difficult to
crash the interpreter of the system with a Python script. There is an
exception to this rule, though: the modules that interface to the
system toolboxes (windowing, quickdraw, etc) do very little error
checking and therefore a misbehaving program using these modules may
indeed crash the system. Such programs are unfortunately rather
difficult to debug, since the crash does not generate the standard
Python stack trace, obviously, and since debugging print statements
will often interfere with the operation of the program. There is
little to do about this currently. <p>

Probably the most common cause of problems with modules ported from
other systems is the Mac end-of-line convention. Where unix uses
linefeed, 0x0a, to separate lines the mac uses carriage return,
0x0d. To complicate matters more a lot of mac programming editors like
BBEdit and emacs will work happily with both conventions, so the file
will appear to be correct in the editor but cause strange errors when
imported. BBEdit has a popup menu which allows you to inspect (and
set) the end-of-line convention used in a file. <p>

Python attempts to keep its preferences file up-to-date even when you
move the Python folder around, etc. If this fails the effect will be
that Python cannot start or, worse, that it does work but it cannot find
any standard modules. In this case, start Python and examine <code>sys.path</code>.
If it is incorrect remove any Python preferences file from the system
folder and start the interpreter <em>while the interpreter sits in the main
Python folder</em>. This will regenerate the preferences file. You may also
have to run the ConfigurePython applet again. <p>

<h2>Your five minutes are up. Next!</h2>

The next section to check out is the <a href="index.html">annotated sample programs</a>.<p>

<HR>
<A HREF="http://www.cwi.nl/~jack">Jack Jansen</A>,
<A HREF="mailto:jack@cwi.nl">jack@cwi.nl</A>, 27-Apr-98.

</BODY>
</HTML>