[Distutils] I browsed through the distutils source!

Greg Ward gward@cnri.reston.va.us
Wed, 31 Mar 1999 13:38:00 -0500


Quoth Michel Sanner, on 30 March 1999:
> sorry , didn't have time to look at this yet .. just a
> question/suggestion What I really like about Makefiles is the -n mode
> where I can see what it would do before it actually does it. Is duch
> an option available in setup.py and if not could it be added.

Yes, the option is there, but support for it is rather spotty.  The idea 
is something like this (from the top distutils directory):

   ./setup.py -nv build

or, equivalently,

   ./setup.py --dry-run --verbose build

But the "dry run" option is ignored at the moment -- I'll explain below.

Currently, verbose mode is *not* the default, even if you specify
"dry-run" mode.  (Thus "./setup.py -n build" will do nothing silently.)
This is probably wrong, and trivial to fix; but first I need to figure
out just how much information the default verbosity level should give.
Currently it reports every filesystem interaction (just copying and
compiling so far), which might be a bit much for the default but must be
available as an option.  Hence some notion of "verbosity level" is
probably needed.

The other tricky thing is to make sure that all command classes respect
both the "verbose" and "dry run" options.  Verbosity is handled by the
'announce()' method in the 'Distribution' and 'Command' classes; "dry
run" mode is not currently handled very well.  (It's the responsibility
of each command class to get the "dry_run" flag from the Distribution
object and obey it, which I think is too much to ask.  For instance, if
you look at the build_py command, you'll note that I seem to have
completely forgotten about handling "dry run" mode, which is why the
above commands don't work -- they go right ahead and build Distutils
anyways, despite the -n option.)

I see two ways to do this nicely, both of which involve bundling up a
"filesystem operation" as a couple of discrete objects -- function to to
call, arguments for it, and descriptive string to print.  The simpler
way is to pass this bundle to a function which prints the message if the
current verbosity level is high enough, and calls the supplied function
if we're not in dry-run mode.  The 'make_file()' function (in
distutils.util) is vaguely in this direction, except it doesn't have
access to the verbose and dry_run flags (needs the Distribution instance
for that).  Also, it adds the notion of input and output files and
simple timestamp dependency checking -- which is why it's called
"make_file"!  Handy, but it adds excess functionality to the simple
notion of "do this thing now, respecting the verbose and dry-run flags".

The other, somewhat less obvious, way to handle the dry-run (and
verbose) flag is to save all these "do this thing now" bundles in a
list.  Then, when we have run *all* commands, walk through the list and
carry out the planned operations.  I don't think this extra complication
is really needed in the Distutils, where most runs should be over in a
second or two, and even the biggest builds/installs should only take a
few minutes.  It's a very useful scheme when you're writing glorified
shell scripts that will run for many many hours, cranking through the
analysis of large datasets (which is what I did a lot of in a previous
life -- I know a thing or two about writing glorified shell scripts, and
some of that knowledge seems applicable in the Distutils).

        Greg
-- 
Greg Ward - software developer                    gward@cnri.reston.va.us
Corporation for National Research Initiatives    
1895 Preston White Drive                      voice: +1-703-620-8990 x287
Reston, Virginia, USA  20191-5434               fax: +1-703-620-0913