[Python-checkins] python/dist/src/Doc/dist dist.tex,1.37,1.38

akuchling@sourceforge.net akuchling@sourceforge.net
Wed, 08 May 2002 06:39:05 -0700


Update of /cvsroot/python/python/dist/src/Doc/dist
In directory usw-pr-cvs1:/tmp/cvs-serv11593

Modified Files:
	dist.tex 
Log Message:
Updates and rewriting


Index: dist.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/dist/dist.tex,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -d -r1.37 -r1.38
*** dist.tex	8 Mar 2002 22:02:06 -0000	1.37
--- dist.tex	8 May 2002 13:39:03 -0000	1.38
***************
*** 4,7 ****
--- 4,12 ----
  % $Id$
  
+ % TODO
+ %   Document extension.read_setup_file
+ %   Document build_clib command
+ %
+ 
  \title{Distributing Python Modules}
  
***************
*** 34,53 ****
  \label{intro}
  
! In the past, Python module developers have not had much infrastructure
! support for distributing modules, nor have Python users had much support
! for installing and maintaining third-party modules.  With the
! introduction of the Python Distribution Utilities (Distutils for short)
! in Python 1.6, this situation should start to improve.
! 
! This document only covers using the Distutils to distribute your Python
! modules.  Using the Distutils does not tie you to Python 1.6, though:
! the Distutils work just fine with Python 1.5.2, and it is reasonable
! (and expected to become commonplace) to expect users of Python 1.5.2 to
! download and install the Distutils separately before they can install
! your modules.  Python 1.6 (or later) users, of course, won't have to add
! anything to their Python installation in order to use the Distutils to
! install third-party modules.
! 
! This document concentrates on the role of developer/distributor: if
  you're looking for information on installing Python modules, you
  should refer to the \citetitle[../inst/inst.html]{Installing Python
--- 39,44 ----
  \label{intro}
  
! This document covers using the Distutils to distribute your Python
! modules, concentrating on the role of developer/distributor: if
  you're looking for information on installing Python modules, you
  should refer to the \citetitle[../inst/inst.html]{Installing Python
***************
*** 86,98 ****
  The setup script is usually quite simple, although since it's written in
  Python, there are no arbitrary limits to what you can do with
! it.\footnote{But be careful about putting arbitrarily expensive
!   operations in your setup script; unlike, say, Autoconf-style configure
    scripts, the setup script may be run multiple times in the course of
    building and installing your module distribution.  If you need to
    insert potentially expensive processing steps into the Distutils
!   chain, see section~\ref{extending} on extending the Distutils.}  If
! all you want to do is distribute a module called \module{foo}, contained
! in a file \file{foo.py}, then your setup script can be as little as
! this:
  
  \begin{verbatim}
--- 77,90 ----
  The setup script is usually quite simple, although since it's written in
  Python, there are no arbitrary limits to what you can do with
! it, though you should be careful about putting arbitrarily expensive
!   operations in your setup script. Unlike, say, Autoconf-style configure
    scripts, the setup script may be run multiple times in the course of
    building and installing your module distribution.  If you need to
    insert potentially expensive processing steps into the Distutils
!   chain, see section~\ref{extending} on extending the Distutils.
! 
! If all you want to do is distribute a module called \module{foo},
! contained in a file \file{foo.py}, then your setup script can be as
! little as this:
  
  \begin{verbatim}
***************
*** 126,135 ****
  which will create an archive file (e.g., tarball on \UNIX, ZIP file on
  Windows) containing your setup script, \file{setup.py}, and your module,
! \file{foo.py}.  The archive file will be named \file{Foo-1.0.tar.gz} (or
! \file{.zip}), and will unpack into a directory \file{Foo-1.0}.
  
  If an end-user wishes to install your \module{foo} module, all she has
! to do is download \file{Foo-1.0.tar.gz} (or \file{.zip}), unpack it,
! and---from the \file{Foo-1.0} directory---run
  
  \begin{verbatim}
--- 118,127 ----
  which will create an archive file (e.g., tarball on \UNIX, ZIP file on
  Windows) containing your setup script, \file{setup.py}, and your module,
! \file{foo.py}.  The archive file will be named \file{foo-1.0.tar.gz} (or
! \file{.zip}), and will unpack into a directory \file{foo-1.0}.
  
  If an end-user wishes to install your \module{foo} module, all she has
! to do is download \file{foo-1.0.tar.gz} (or \file{.zip}), unpack it,
! and---from the \file{foo-1.0} directory---run
  
  \begin{verbatim}
***************
*** 159,169 ****
  \end{verbatim}
  
! will create an executable installer, \file{Foo-1.0.win32.exe}, in the
  current directory.
  
! Currently (Distutils 0.9.2), the only other useful built
! distribution format is RPM, implemented by the \command{bdist\_rpm}
! command.  For example, the following command will create an RPM file
! called \file{Foo-1.0.noarch.rpm}:
  
  \begin{verbatim}
--- 151,162 ----
  \end{verbatim}
  
! will create an executable installer, \file{foo-1.0.win32.exe}, in the
  current directory.
  
! Other useful built distribution formats are RPM, implemented by the
! \command{bdist\_rpm} command, Solaris \program{pkgtool}
! (\command{bdist\_pkgtool}, and HP-UX \program{swinstall} (\command{bdist_sdux}).
! For example, the following command will create an RPM file called
! \file{foo-1.0.noarch.rpm}:
  
  \begin{verbatim}
***************
*** 193,209 ****
    code imported by some other code.  Three types of modules concern us
    here: pure Python modules, extension modules, and packages.
  \item[pure Python module] a module written in Python and contained in a
    single \file{.py} file (and possibly associated \file{.pyc} and/or
    \file{.pyo} files).  Sometimes referred to as a ``pure module.''
  \item[extension module] a module written in the low-level language of
!   the Python implementation: C/C++ for Python, Java for JPython.
    Typically contained in a single dynamically loadable pre-compiled
    file, e.g. a shared object (\file{.so}) file for Python extensions on
    \UNIX, a DLL (given the \file{.pyd} extension) for Python extensions
!   on Windows, or a Java class file for JPython extensions.  (Note that
    currently, the Distutils only handles C/C++ extensions for Python.)
  \item[package] a module that contains other modules; typically contained
    in a directory in the filesystem and distinguished from other
    directories by the presence of a file \file{\_\_init\_\_.py}.
  \item[root package] the root of the hierarchy of packages.  (This isn't
    really a package, since it doesn't have an \file{\_\_init\_\_.py}
--- 186,206 ----
    code imported by some other code.  Three types of modules concern us
    here: pure Python modules, extension modules, and packages.
+ 
  \item[pure Python module] a module written in Python and contained in a
    single \file{.py} file (and possibly associated \file{.pyc} and/or
    \file{.pyo} files).  Sometimes referred to as a ``pure module.''
+ 
  \item[extension module] a module written in the low-level language of
!   the Python implementation: C/C++ for Python, Java for Jython.
    Typically contained in a single dynamically loadable pre-compiled
    file, e.g. a shared object (\file{.so}) file for Python extensions on
    \UNIX, a DLL (given the \file{.pyd} extension) for Python extensions
!   on Windows, or a Java class file for Jython extensions.  (Note that
    currently, the Distutils only handles C/C++ extensions for Python.)
+ 
  \item[package] a module that contains other modules; typically contained
    in a directory in the filesystem and distinguished from other
    directories by the presence of a file \file{\_\_init\_\_.py}.
+ 
  \item[root package] the root of the hierarchy of packages.  (This isn't
    really a package, since it doesn't have an \file{\_\_init\_\_.py}
***************
*** 227,242 ****
    \emph{en masse}.  Examples of some well-known module distributions are
    Numeric Python, PyXML, PIL (the Python Imaging Library), or
!   mxDateTime.  (This would be called a \emph{package}, except that term
    is already taken in the Python context: a single module distribution
    may contain zero, one, or many Python packages.)
  \item[pure module distribution] a module distribution that contains only
    pure Python modules and packages.  Sometimes referred to as a ``pure
    distribution.''
  \item[non-pure module distribution] a module distribution that contains
    at least one extension module.  Sometimes referred to as a ``non-pure
    distribution.''
  \item[distribution root] the top-level directory of your source tree (or 
!   source distribution); the directory where \file{setup.py} exists and
!   is run from
  \end{description}
  
--- 224,242 ----
    \emph{en masse}.  Examples of some well-known module distributions are
    Numeric Python, PyXML, PIL (the Python Imaging Library), or
!   mxBase.  (This would be called a \emph{package}, except that term
    is already taken in the Python context: a single module distribution
    may contain zero, one, or many Python packages.)
+ 
  \item[pure module distribution] a module distribution that contains only
    pure Python modules and packages.  Sometimes referred to as a ``pure
    distribution.''
+ 
  \item[non-pure module distribution] a module distribution that contains
    at least one extension module.  Sometimes referred to as a ``non-pure
    distribution.''
+ 
  \item[distribution root] the top-level directory of your source tree (or 
!   source distribution); the directory where \file{setup.py} exists.  Generally 
!   \file{setup.py} will be run from this directory.
  \end{description}
  
***************
*** 291,301 ****
  setup script portable across operating systems, which of course is one
  of the major goals of the Distutils.  In this spirit, all pathnames in
! this document are slash-separated (MacOS programmers should keep in
  mind that the \emph{absence} of a leading slash indicates a relative
! path, the opposite of the MacOS convention with colons).
  
  This, of course, only applies to pathnames given to Distutils functions.
! If you, for example, use standard python functions such as glob.glob
! or os.listdir to specify files, you should be careful to write portable
  code instead of hardcoding path separators:
  
--- 291,301 ----
  setup script portable across operating systems, which of course is one
  of the major goals of the Distutils.  In this spirit, all pathnames in
! this document are slash-separated.  (MacOS programmers should keep in
  mind that the \emph{absence} of a leading slash indicates a relative
! path, the opposite of the MacOS convention with colons.)
  
  This, of course, only applies to pathnames given to Distutils functions.
! If you, for example, use standard python functions such as \function{glob.glob}
! or \function{os.listdir} to specify files, you should be careful to write portable
  code instead of hardcoding path separators:
  
***************
*** 334,340 ****
  \end{verbatim}
  
! in your setup script.  (The keys to this dictionary are package names,
  and an empty package name stands for the root package.  The values are
! directory names relative to your distribution root.)  In this case, when
  you say \code{packages = ['foo']}, you are promising that the file
  \file{lib/foo/\_\_init\_\_.py} exists.
--- 334,340 ----
  \end{verbatim}
  
! in your setup script.  The keys to this dictionary are package names,
  and an empty package name stands for the root package.  The values are
! directory names relative to your distribution root.  In this case, when
  you say \code{packages = ['foo']}, you are promising that the file
  \file{lib/foo/\_\_init\_\_.py} exists.
***************
*** 401,409 ****
  
  \begin{verbatim}
! Extension("foo", ["foo.c"])
  \end{verbatim}
  
  The \class{Extension} class can be imported from
! \module{distutils.core}, along with \function{setup()}.  Thus, the setup
  script for a module distribution that contains only this one extension
  and nothing else might be:
--- 401,409 ----
  
  \begin{verbatim}
! uExtension("foo", ["foo.c"])
  \end{verbatim}
  
  The \class{Extension} class can be imported from
! \module{distutils.core} along with \function{setup()}.  Thus, the setup
  script for a module distribution that contains only this one extension
  and nothing else might be:
***************
*** 460,467 ****
  
  The second argument to the \class{Extension} constructor is a list of
! source files.  Since the Distutils currently only support C/C++
! extensions, these are normally C/C++ source files.  (Be sure to use
! appropriate extensions to distinguish C++ source files: \file{.cc} and
! \file{.cpp} seem to be recognized by both \UNIX{} and Windows compilers.)
  
  However, you can also include SWIG interface (\file{.i}) files in the
--- 460,468 ----
  
  The second argument to the \class{Extension} constructor is a list of
! source files.  Since the Distutils currently only support C, \Cpp, and
! Objective-C extensions, these are normally C/\Cpp/Objective-C source
! files.  (Be sure to use appropriate extensions to distinguish \Cpp\
! source files: \file{.cc} and \file{.cpp} seem to be recognized by both
! \UNIX{} and Windows compilers.)
  
  However, you can also include SWIG interface (\file{.i}) files in the
***************
*** 509,520 ****
  
  If you need to include header files from some other Python extension,
! you can take advantage of the fact that the Distutils install extension
! header files in a consistent way.  For example, the Numerical Python
! header files are installed (on a standard \UNIX{} installation) to
! \file{/usr/local/include/python1.5/Numerical}.  (The exact location will
! differ according to your platform and Python installation.)  Since the
! Python include directory---\file{/usr/local/include/python1.5} in this
! case---is always included in the search path when building Python
! extensions, the best approach is to include (e.g.)
  \code{<Numerical/arrayobject.h>}.  If you insist on putting the
  \file{Numerical} include directory right into your header search path,
--- 510,522 ----
  
  If you need to include header files from some other Python extension,
! you can take advantage of the fact that the Distutils installs
! extension header files in a consistent way.  For example, on a
! standard \UNIX{} installation the Numerical Python header files are
! installed to \file{/usr/local/include/python1.5/Numerical}.  (The
! exact location will differ according to your platform and Python
! installation.)  Since the Python include
! directory---\file{/usr/local/include/python1.5} in this case---is
! always included in the search path when building Python extensions,
! the best approach is to include (e.g.)
  \code{<Numerical/arrayobject.h>}.  If you insist on putting the
  \file{Numerical} include directory right into your header search path,
***************
*** 603,614 ****
  
  \option{extra\_compile\_args} and \option{extra\_link\_args} can be used
! to specify additional command line options for the compiler resp.
! the linker command line.
  
! \option{export\_symbols} is only useful on windows, it can contain a list
  of symbols (functions or variables) to be exported. This option
! is not needed when building compiled extensions: the \code{initmodule}
! function will automatically be added to the exported symbols list
! by Distutils.
  
  \subsection{Listing scripts}
--- 605,616 ----
  
  \option{extra\_compile\_args} and \option{extra\_link\_args} can be used
! to specify additional command line options for the respective compiler and
! linker command lines.
  
! \option{export\_symbols} is only useful on Windows.  It can contain a list
  of symbols (functions or variables) to be exported. This option
! is not needed when building compiled extensions: Distutils 
! will automatically add \code{initmodule}
! to the list of exported symbols.
  
  \subsection{Listing scripts}
***************
*** 616,625 ****
  which are usually not run by themselves but imported by scripts.
  
! Scripts are files containing Python source code, indended to be started
! from the command line.
! Distutils doesn't provide much functionality for the scripts: the only
! support Distutils gives is to adjust the first line of the script
! if it starts with \code{\#!} and contains the word ``python'' to refer
! to the current interpreter location.
  
  The \option{scripts} option simply is a list of files to be handled
--- 618,627 ----
  which are usually not run by themselves but imported by scripts.
  
! Scripts are files containing Python source code, indended to be
! started from the command line.  Scripts don't require Distutils to do
! anything very complicated.  The only clever feature is that if the
! first line of the script starts with \code{\#!} and contains the word
! ``python'', the Distutils will adjust the first line to refer to the
! current interpreter location.
  
  The \option{scripts} option simply is a list of files to be handled
***************
*** 676,684 ****
  override either on the command-line or by editing the config file.
  
! (If you have more advanced needs, such as determining which extensions
! to build based on what capabilities are present on the target system,
! then you need the Distutils ``auto-configuration'' facility.  This
! started to appear in Distutils 0.9 but, as of this writing, isn't mature 
! or stable enough yet for real-world use.)
  
  The setup configuration file is a useful middle-ground between the setup
--- 678,686 ----
  override either on the command-line or by editing the config file.
  
! % (If you have more advanced needs, such as determining which extensions
! % to build based on what capabilities are present on the target system,
! % then you need the Distutils ``auto-configuration'' facility.  This
! % started to appear in Distutils 0.9 but, as of this writing, isn't mature 
! % or stable enough yet for real-world use.)
  
  The setup configuration file is a useful middle-ground between the setup
***************
*** 709,718 ****
  
  where \var{command} is one of the Distutils commands (e.g.
! \command{build\_py}, \command{install}), and \var{option} is one of the
! options that command supports.  Any number of options can be supplied
! for each command, and any number of command sections can be included in
! the file.  Blank lines are ignored, as are comments (from a
! \character{\#} character to end-of-line).  Long option values can be
! split across multiple lines simply by indenting the continuation lines.
  
  You can find out the list of options supported by a particular command
--- 711,721 ----
  
  where \var{command} is one of the Distutils commands (e.g.
! \command{build\_py}, \command{install}), and \var{option} is one of
! the options that command supports.  Any number of options can be
! supplied for each command, and any number of command sections can be
! included in the file.  Blank lines are ignored, as are comments, which
! run from a \character{\#} character until the end of the line.  Long
! option values can be split across multiple lines simply by indenting
! the continuation lines.
  
  You can find out the list of options supported by a particular command
***************
*** 771,775 ****
  
  Another example: certain commands take a lot of options that don't
! change from run-to-run; for example, \command{bdist\_rpm} needs to know
  everything required to generate a ``spec'' file for creating an RPM
  distribution.  Some of this information comes from the setup script, and
--- 774,778 ----
  
  Another example: certain commands take a lot of options that don't
! change from run to run; for example, \command{bdist\_rpm} needs to know
  everything required to generate a ``spec'' file for creating an RPM
  distribution.  Some of this information comes from the setup script, and
***************
*** 815,819 ****
  (assuming you haven't specified any \command{sdist} options in the setup
  script or config file), \command{sdist} creates the archive of the
! default format for the current platform.  The default format is gzip'ed
  tar file (\file{.tar.gz}) on \UNIX, and ZIP file on Windows.
  \XXX{no MacOS support here}
--- 818,822 ----
  (assuming you haven't specified any \command{sdist} options in the setup
  script or config file), \command{sdist} creates the archive of the
! default format for the current platform.  The default format is a gzip'ed
  tar file (\file{.tar.gz}) on \UNIX, and ZIP file on Windows.
  \XXX{no MacOS support here}
***************
*** 831,835 ****
    \lineiii{zip}{zip file (\file{.zip})}{(1),(3)}
    \lineiii{gztar}{gzip'ed tar file (\file{.tar.gz})}{(2),(4)}
!   \lineiii{bztar}{bzip2'ed tar file (\file{.tar.gz})}{(4)}
    \lineiii{ztar}{compressed tar file (\file{.tar.Z})}{(4)}
    \lineiii{tar}{tar file (\file{.tar})}{(4)}
--- 834,838 ----
    \lineiii{zip}{zip file (\file{.zip})}{(1),(3)}
    \lineiii{gztar}{gzip'ed tar file (\file{.tar.gz})}{(2),(4)}
!   \lineiii{bztar}{bzip2'ed tar file (\file{.tar.bz2})}{(4)}
    \lineiii{ztar}{compressed tar file (\file{.tar.Z})}{(4)}
    \lineiii{tar}{tar file (\file{.tar})}{(4)}
***************
*** 867,870 ****
--- 870,874 ----
    you called your setup script), and \file{setup.cfg}
  \end{itemize}
+ 
  Sometimes this is enough, but usually you will want to specify
  additional files to distribute.  The typical way to do this is to write
***************
*** 960,967 ****
    \file{MANIFEST.in} and create the manifest
  \item if neither \file{MANIFEST} nor \file{MANIFEST.in} exist, create a
!   manifest with just the default file set\footnote{In versions of the
!     Distutils up to and including 0.9.2 (Python 2.0b1), this feature was
!     broken; use the \programopt{-f} (\longprogramopt{force-manifest})
!     option to work around the bug.}
  \item if either \file{MANIFEST.in} or the setup script (\file{setup.py})
    are more recent than \file{MANIFEST}, recreate \file{MANIFEST} by
--- 964,968 ----
    \file{MANIFEST.in} and create the manifest
  \item if neither \file{MANIFEST} nor \file{MANIFEST.in} exist, create a
!   manifest with just the default file set
  \item if either \file{MANIFEST.in} or the setup script (\file{setup.py})
    are more recent than \file{MANIFEST}, recreate \file{MANIFEST} by
***************
*** 972,980 ****
  There are a couple of options that modify this behaviour.  First, use
  the \longprogramopt{no-defaults} and \longprogramopt{no-prune} to
! disable the standard ``include'' and ``exclude'' sets.\footnote{Note
!   that if you have no manifest template, no manifest, and use the
!   \longprogramopt{no-defaults}, you will get an empty manifest.  Another
!   bug in Distutils 0.9.2 and earlier causes an uncaught exception in
!   this case.  The workaround is: Don't Do That.}
  
  Second, you might want to force the manifest to be regenerated---for
--- 973,977 ----
  There are a couple of options that modify this behaviour.  First, use
  the \longprogramopt{no-defaults} and \longprogramopt{no-prune} to
! disable the standard ``include'' and ``exclude'' sets.
  
  Second, you might want to force the manifest to be regenerated---for
***************
*** 1018,1022 ****
  designed to enable module developers to concentrate on their
  specialty---writing code and creating source distributions---while an
! intermediary species of \emph{packager} springs up to turn source
  distributions into built distributions for as many platforms as there
  are packagers.
--- 1015,1019 ----
  designed to enable module developers to concentrate on their
  specialty---writing code and creating source distributions---while an
! intermediary species called \emph{packagers} springs up to turn source
  distributions into built distributions for as many platforms as there
  are packagers.
***************
*** 1027,1031 ****
  software periodically grabbing new source distributions and turning them
  into built distributions for as many platforms as the software has
! access to.  Regardless of the nature of the beast, a packager uses the
  setup script and the \command{bdist} command family to generate built
  distributions.
--- 1024,1028 ----
  software periodically grabbing new source distributions and turning them
  into built distributions for as many platforms as the software has
! access to.  Regardless of who they are, a packager uses the
  setup script and the \command{bdist} command family to generate built
  distributions.
***************
*** 1042,1051 ****
  directory), and creates the default type of built distribution for my
  platform.  The default format for built distributions is a ``dumb'' tar
! file on \UNIX, and an simple executable installer on Windows.  (That tar
  file is considered ``dumb'' because it has to be unpacked in a specific
  location to work.)
  
  Thus, the above command on a \UNIX{} system creates
! \file{Distutils-0.9.1.\filevar{plat}.tar.gz}; unpacking this tarball
  from the right place installs the Distutils just as though you had
  downloaded the source distribution and run \code{python setup.py
--- 1039,1048 ----
  directory), and creates the default type of built distribution for my
  platform.  The default format for built distributions is a ``dumb'' tar
! file on \UNIX, and a simple executable installer on Windows.  (That tar
  file is considered ``dumb'' because it has to be unpacked in a specific
  location to work.)
  
  Thus, the above command on a \UNIX{} system creates
! \file{Distutils-1.0.\filevar{plat}.tar.gz}; unpacking this tarball
  from the right place installs the Distutils just as though you had
  downloaded the source distribution and run \code{python setup.py
***************
*** 1055,1064 ****
  distributions relative to \filevar{prefix}.)  
  
! Obviously, for pure Python distributions, this isn't a huge win---but
! for non-pure distributions, which include extensions that would need to
! be compiled, it can mean the difference between someone being able to
! use your extensions or not.  And creating ``smart'' built distributions,
! such as an RPM package or an executable installer for Windows, is a big
! win for users even if your distribution doesn't include any extensions.
  
  The \command{bdist} command has a \longprogramopt{formats} option,
--- 1052,1063 ----
  distributions relative to \filevar{prefix}.)  
  
! Obviously, for pure Python distributions, this isn't any simpler than
! just running \code{python setup.py install}---but for non-pure
! distributions, which include extensions that would need to be
! compiled, it can mean the difference between someone being able to use
! your extensions or not.  And creating ``smart'' built distributions,
! such as an RPM package or an executable installer for Windows, is far
! more convenient for users even if your distribution doesn't include
! any extensions.
  
  The \command{bdist} command has a \longprogramopt{formats} option,
***************
*** 1071,1075 ****
  
  would, when run on a \UNIX{} system, create
! \file{Distutils-0.8.\filevar{plat}.zip}---again, this archive would be
  unpacked from the root directory to install the Distutils.
  
--- 1070,1074 ----
  
  would, when run on a \UNIX{} system, create
! \file{Distutils-1.0.\filevar{plat}.zip}---again, this archive would be
  unpacked from the root directory to install the Distutils.
  
***************
*** 1082,1086 ****
    \lineiii{zip}{zip file (\file{.zip})}{(4)}
    \lineiii{rpm}{RPM}{(5)}
!   \lineiii{srpm}{source RPM}{(5) \XXX{to do!}}
    \lineiii{wininst}{self-extracting ZIP file for Windows}{(2),(4)}
  \end{tableiii}
--- 1081,1088 ----
    \lineiii{zip}{zip file (\file{.zip})}{(4)}
    \lineiii{rpm}{RPM}{(5)}
!   \lineiii{pkgtool}{Solaris \program{pkgtool}}{}
!   \lineiii{sdux}{HP-UX \program{swinstall}}{}
!   \lineiii{rpm}{RPM}{(5)}
! %  \lineiii{srpm}{source RPM}{(5) \XXX{to do!}}
    \lineiii{wininst}{self-extracting ZIP file for Windows}{(2),(4)}
  \end{tableiii}
***************
*** 1128,1132 ****
  \label{creating-rpms}
  
! The RPM format is used by many of popular Linux distributions, including
  Red Hat, SuSE, and Mandrake.  If one of these (or any of the other
  RPM-based Linux distributions) is your usual environment, creating RPM
--- 1130,1134 ----
  \label{creating-rpms}
  
! The RPM format is used by many popular Linux distributions, including
  Red Hat, SuSE, and Mandrake.  If one of these (or any of the other
  RPM-based Linux distributions) is your usual environment, creating RPM
***************
*** 1245,1254 ****
  
  
! \subsection{Creating Windows installers}
  \label{creating-wininst}
  
! Executable Windows installers are the natural format for binary
  distributions on Windows.  They display a nice graphical user interface,
! display some information of the module distribution to be installed, taken
  from the meta-data in the setup script, let the user select a few
  (currently maybe too few) options, and start or cancel the installation.
--- 1247,1256 ----
  
  
! \subsection{Creating Windows Installers}
  \label{creating-wininst}
  
! Executable installers are the natural format for binary
  distributions on Windows.  They display a nice graphical user interface,
! display some information about the module distribution to be installed taken
  from the meta-data in the setup script, let the user select a few
  (currently maybe too few) options, and start or cancel the installation.
***************
*** 1269,1279 ****
  If you have a pure module distribution (only containing pure
  Python modules and packages), the resulting installer will be
! version independent and have a name like \file{Foo-1.0.win32.exe}.
  These installers can even be created on \UNIX{} or MacOS platforms.
  
  If you have a non-pure distribution, the extensions can only be
! created on a Windows platform, and will be Python version dependend.
  The installer filename will reflect this and now has the form
! \file{Foo-1.0.win32-py2.0.exe}. You have to create a separate installer
  for every Python version you want to support.
  
--- 1271,1281 ----
  If you have a pure module distribution (only containing pure
  Python modules and packages), the resulting installer will be
! version independent and have a name like \file{foo-1.0.win32.exe}.
  These installers can even be created on \UNIX{} or MacOS platforms.
  
  If you have a non-pure distribution, the extensions can only be
! created on a Windows platform, and will be Python version dependent.
  The installer filename will reflect this and now has the form
! \file{foo-1.0.win32-py2.0.exe}. You have to create a separate installer
  for every Python version you want to support.