Haaa, made the same mistake, wanted to send to the list, not just to Greg!
:) apparently it's not *too* big a burden.) And what modifications do you
:) want to distribute? I like most of your patches/ideas, so if there are
:) some you're holding back, please share them!
Ok, here is a list what I have done, patches will follow (and if you have
some ideas, they will be applied):
(1) I implemented an uninstall option. Currently this is a Python script
with a list of installed files. I like more the idea of separating the
uninstall script and just write the list of files in a file because with
my previous attempt you can not delete the Python uninstall script itself
since its running (well, under Linux this actually works - a script that
deletes itself, but not under Windows).
So I better store just a list of installed files.
(2) There is a --destdir option to install in another directory. This is
not the same as supplying the --prefix and --exec-prefix options.
I need this to generate Debian packages easily with
./setup.py install --destdir=`pwd`/debian/tmp
(3) Very crude script support. You supply a list of 'scripts' and
'programs' and they will be installed in effective_prefix/bin
(effective_prefix is either sys.prefix or sys.exec_prefix)
for Unix and in effective_prefix for Windows. You can customize this with
Why is the install directory effective_prefix under Windows? On my Win98
box this is the directory where python.exe is and I assume the user has
the python executable in his/her PATH.
If you supply a 'script', the string @INSTALL_BIN@ gets replaced with
the value of install_bin.
(4) As you see from (3) the install command handles now systems with
os.name=='nt' where the default install_lib and install_platlib are
:) I will ask, though, that you *not* install the distutils into anyone's
:) Python installation: I want to reserve that privilege for myself and,
:) ultimately, the Python 1.6 makefile.
I will fix that in my distribution.
My program where I use the distutils is a link checker and located at
[oops! meant to send this to the list, not to Bastian personally...
On 19 March 2000, Bastian Kleineidam said:
> I have implemented an uninstall option. If you specify -c or
> --create-uninstall to the install command, an uninstall script named
> <package name>_uninstall.py will be built and it will be installed in
> install-lib resp. install-platlib.
> To uninstall your package, execute this script with python.
Hmmm, good idea. I've idly mused about how to uninstall module
distributions, and this option hadn't occurred to me. So now I can see
*two* good ways to do uninstallation:
* keep track of the files installed (eg. using Michael Muller's
"pkginfo" patch), and have a universal uninstall script that
digs up the list of files for a particular distribution
* generate a custom uninstall script for each installed
In terms of correctness -- do we uninstall exactly the right files? --
they're equivalent; you write a list of files to the disk at
installation time and retrieve it later.
For user convenience, I *think* that Bastian's "custom script" approach
would have a slight edge: as long as people know to type (eg.)
"/usr/local/lib/python1.6/site-packages/uninstall_foo", they're fine.
On the other hand, a single global uninstall script could go in a
central location, so just "pymod_uninstall foo" might do the trick.
Also strikes me that the code might be a tad cleaner for a global
uninstall script: no need to generate Python code, you just need to
generate a list of filenames somewhere in the pkginfo.
Greg Ward - Unix bigot gward(a)python.net
BE ALERT!!!! (The world needs more lerts ...)
I think it would be extremly helpfull for developing Python Extensions
to be ditributed using Distutils to have an option "--additional-flags"
where I could give addional flags for the C compiler, e.g. to ask for
specific compiling or optimization flags. What do you think about it?
C[_] These opinions might be mine, but never those of my employer.
I have implemented an uninstall option. If you specify -c or
--create-uninstall to the install command, an uninstall script named
<package name>_uninstall.py will be built and it will be installed in
install-lib resp. install-platlib.
To uninstall your package, execute this script with python.
Note that the uninstall option requires you to supply a package name
The patch is against the latest CVS snapshot.
Second try, this time only the clean command with suggestions from Greg.
Options for 'clean' command:
--build-base (-b) base directory for build library
--build-lib build directory for all distribution (defaults to
either build-purelib or build-platlib
--build-temp (-t) temporary build directory
--all (-a) clean all files, not only temporary files
I refactored the sdist.nuke_release_tree() function into
util.remove_tree(directory, verbose=0, dry_run=0).
I grabbed the latest CVS version of distutils, as of 3/15/2000.
I'm building C Python extensions under Solaris and Linux. Under
Solaris, I need to specify the
'-R' options. 'rpath' is documented to do this, but doesn't have any
In ccompiler.py, I notice the _fix_link_args() routine manipulates
libraries and library_dirs, but doesn't use rpath.
I suspect _fix_link_args() is part of what needs to be fixed.
Anyone else using 'rpath'?
National Center for Atmospheric Research
I have questions rather than answers:
We would like to use Distutils
for installation of our Python front end to IRAF (an astronomical data
reduction program). Our front end is called PyRAF. Upon reading the Distutil
documentation, I can figure out how to do a basic installation but there
are some files that do not seem to install easily with the current version
of Distutil (or I am missing something).
First, we need to install several data files and scripts. One is named
"pyraf" and is a python script. Another is a database file called
pyraf.Database, which is created specifically for each platform by executing a
python script mkpyraf.Database.py. Some other data files need to be copied
Lastly, we have three modules written in C that need to be compiled plus
a C library package that also needs to be compiled. I can set up the include
directories and library directories for each platform, but we would like to
have a platform-independent script that probes the platform type and checks
to see where the include and library files are located and then assigns the
include and library directories before the compile and link.
Is there any way to do these things with the current Distutil without
essentially writing my own python scripts. I have seen some discussion about
adding provisions for scripts and data files. What is the consensus on that?
We want to have a working installation procedure by April 15th.
I subscribe to the list, so any response to the list would be fine.
Thanks a lot,
[cc'd to the distutils-sig, since this deserves a public airing]
On 13 March 2000, Bastian Kleineidam said:
> this patch is against the CVS version of March 13th.
> It implements a "clean" command which cleans everything
> generated with the "build" and "sdist" commands.
Useful addition, and definitely something I've been putting off.
However, there's no need to clean up after "sdist", since it
automatically does so itself! (You can tell it not to with the
"--keep-tree" option.) If "sdist" is *not* cleaning up after itself on
some platform, that's a bug. (See the last statement of
'make_distribution()' in the "sdist" command class.)
> Additionally, I implemented the sdist option --list-only.
Procedural point: in future, please try to submit distinct changes like
this as separate patches. I might like one change right away, but send
another back for revisions. Bundling them together makes this hard.
As it happens, your "clean" command has a few problems, and I don't see
the point of the --list-only option. (Partly my fault: I probably
should have taken it out when I revamped the "dist" command and turned
it into "sdist" -- I'm pretty sure it's vestigial.)
> + class clean(Command):
> + # Hmm, split this up into clean_py,clean_ext,clean_clib,clean_sdist?
> + # Or just clean_build,clean_sdist?
Good gravy! No need to go overboard here; cleaning is simple enough
that it can be handled by one command.
> + description = "clean everything we built"
> + user_options = [
> + ('build-base=', 'b',
> + "base directory for build library"),
> + ]
> + def initialize_options(self):
> + self.build_base = 'build'
No: 'initialize_options()' should almost always initialize everything to
None; otherwise, we have no way of knowing if the user supplied a value
when we get to 'finalize_options()'.
> + def finalize_options(self):
> + self.base_dir = self.distribution.name or "UNKNOWN"
> + if self.distribution.version:
> + self.base_dir = self.base_dir+"-"+self.distribution.version
Not necessary, since "sdist" cleans up after itself. And it's *very*
naughty to generate a filename or directory name that's generated by
another command; if "sdist" doesn't provide a way to get that
information, add it (eg. a 'get_release_tree()' method). But it's not
But you do need to select a final value for 'build_base', and it should
come from the "build" command's 'build_base'. Canonically:
> + def run(self):
> + # remove the build directory
> + self._nuke_tree(self.build_base)
Oh wait, there are two kinds of things I might want to clean in the
build base: temporary build by-products (foo.o, libbar.a, etc. -- all in
build/temp.<plat>) and the real products of the build (in build/lib or
build/platlib). This probably should be a user option to the clean
command. I'm not sure what the default should be: clean everything with
"--temp-only" option, or clean temp only with an "--all" option. The
latter is safer and less typing in the "exceptional" case.
> + def _nuke_tree(self, directory):
> + try:
> + self.execute (shutil.rmtree, (directory,),
> + "removing "+directory)
> + except (IOError, OSError), exc:
> + if exc.filename:
> + msg = "error removing %s: %s (%s)" % \
> + (directory, exc.strerror, exc.filename)
> + else:
> + msg = "error removing %s: %s" % (directory, exc.strerror)
> + self.warn (msg)
This looks suspiciously as though it was cut 'n pasted from the
'nuke_release_tree()' method in "sdist". I hereby ban reuse by cut 'n
paste. Since "nuke a directory tree" is now needed in two places, it
should be factored out into a convenience function in util.py. (And it
should take 'verbose' and 'dry_run' flags... just follow the
I'll happily accept a second patch! Just keep it distinct from any
Now the "sdist" business...
Why is the "--list-only" option needed? I'm pretty sure it should be
dropped, because you can achieve everything it provided (and more) with
the new "sdist" command. Eg:
setup.py sdist --manifest-only
generates MANIFEST from MANIFEST.in, giving you the list of files that
will be distributed. It even tells you what's going on as it processes
the MANIFEST.in file; right now this is debugging output, but I'm
starting to think it should be preserved. It's handy!
setup.py -n sdist --manifest-only
This does the same, only it doesn't create MANIFEST -- just tells you
what it would have done while processing MANIFEST.in.
setup.py -n sdist
And this tells you what "sdist" would have done in creating a
distributable archive (tarball or zip or whatever).
Is anything else needed? Does your patch (which I haven't read closely)
provide anything extra that's not handled by these options?
Greg Ward - "always the quiet one" gward(a)python.net
Think honk if you're a telepath.