Python Distutils-SIG: Proposed User Interface
Python Distutils-SIG
Proposed User Interface
In addition to identifying the common tasks
and division of labour involved in developing, distributing, and
installing Python modules, the "Extension Building Considered
Painful" Developer's Day Session also came up with a proposed user
interface. The core idea of the interface is that the module
developer would provide a small Python script, called
setup.py
for purposes of illustration (although it is
hoped that this convention catches on!). This script would have two
components: meta-data about the module distribution (name, version
number, description, etc.), written as Python code of some sort; and
optional code to inspect the target system and carry out any needed
pre-build configuration operations. Only the meta-data will be
required, and indeed it is anticipated that most module distributions
(especially those written purely in Python) will have only the
meta-data component. Some ideas for how to represent the meta-data
will be presented below.
This document describes an interface based on what we agreed upon at the Developer's Day session, but with a lot more detail. (Some of that detail could be construed as implementation rather than interface, but it's important to specify it somewhere.)
Once the setup.py
script is written, developers,
packagers, and installers alike will use it to carry out all of
their tasks that can be automated (i.e. everything except actually
writing the modules, documentation, and test suite). This will be
done by running setup.py
with a mandatory "command"
argument corresponding to the task to be accomplished. (By sheer
coincidence, many of these commands will look a lot like traditional
makefile
targets.)
For example, the command to initiate a build is
build
. The developer, packager, and installer (at
least an installer working from a source distribution) will all have
to build the module(s), using the following command:
./setup.py buildAfter building, everyone should run the test suite, using the
test
command:
./setup.py testWhen he's happy with the state of the code, the developer will want to put on his first packager hat and create a source distribution:
./setup.py distor he might want to put on his other packager hat and make a built distribution (or this could be done by a packager for some other platform):
./setup.py bdistIf the packager is making build distributions for a system that supports a "smart installer" (which the distutils also support!), he could make a "smart" built distribution, e.g. an RPM for the Linux distributions that use it:
./setup.py bdist -rpm(Note the use of a command-specific option here; for instance, the
bdist
command should also have options to enable
generating "smart" distributions for Windows and Macintosh, assuming
suitable smart install tools can be found for those platforms.)
By now, you're probably wondering what's really
happening behind each of those commands. It could be argued that
that is an implementation detail that doesn't belong in an interface
proposal, but I think that most developers, many packagers, and a
few curious users will be inclined to look "under the hood" and see
what's really going on as they build and install module
distributions. (And the unlucky ones will have to understand the
process if things go wrong!) So, here is a list of commands to be
supported by setup.py
(through cooperation with the
distutils modules) and the actions corresponding to
each command:
make_blib
- If it doesn't already exist, create a mockup installation
tree,
blib/
, under the current directory.blib/
would contain directories for pure Python code (non-architecture-specific, or shared) and compiled code (architecture-specific), modelled after the directories in the system Python library on the current machine (which are determined when Python itself is built). For instance,make_blib
might createblib/share/
(shared files) andblib/plat-i86-linux/
(architecture-specific files). There might also be directories for documentation, e.g.blib/man/
for Unix-style man pages,blib/info/
for GNU info documentation, and/orblib/html/
for (you guessed it) HTML documenation. build_py
- Do
make_blib
; copy.py
files into the "shared"blib
directory (or subdirectories of it, if they belong to packages), and compile them to.pyc
and.pyo
form. build_extensions
- Do
make_blib
; compile ancillary C files (those that don't provide extension modules themselves, but are needed for the extension(s) being built to work); compile extension C files; link ancillary and extension C files (along with any external libraries needed) to create dynamic libraries (e.g..so
files for Unix, DLLs for Windows, etc.) in the architecture-specificblib
directory build_doc
- process documentation to an installable form somewhere under
./blib
e.g. *roff-formatted man pages, GNU Info, HTML, Windows help, etc. Perhaps the desired documentation format(s) could be determined when Python itself is built (and, naturally, the Python documentation would be available in that format, in the same place that module documentation accumulates)? build
- Do
build_py
,build_extensions
, andbuild_doc
. (Of course, any one of these operations does nothing if the appropriate inputs are not there.) dist
- Create a source distribution ...
bdist
- Create a built distribution ...
test
- Look for the test suite and run it. One possible way to
define a test suite: put a bunch of scripts in a predefined
subdirectory of the source distribution; they will then be
executed with the shared and architecture-specific
blib
directories added to Python's library search path. For instance, thetest
command might search fortest/*.t
, executing each script in turn and interpreting its output to determine whether that series of tests succeeded or failed. install
- Copy
.py
,.pyc
, and.pyo
files into the shared installation directory (which would default to the site-specific area of the Python system library tree); copy dynamic libraries (shared objects or DLLs) to the architecture-specific installation directory; copy processed documentation (man pages, Info files, whatever) to the documentation installation directory. (Perhaps this should be split up intoinstall_py
,install_extensions
, andinstall_doc
?)