[Distutils] PEP 376, Uninstallation and interoperability

Vinay Sajip vinay_sajip at yahoo.co.uk
Tue Feb 19 11:18:56 CET 2013

Daniel Holth <dholth <at> gmail.com> writes:

> If you want eby-style uninstall to be fast, index record in sqlite in a
> post-install hook.

I'm not sure what you mean by Eby-style uninstall, but uninstalling is already
fast enough, AFAIK.

> I'm horrified that "overwrite any file on my system" is a feature. I think
> gem and npm get along without it, if you want to write into /etc then you
> should be building rpms.

Sure, but it's an imperfect world that we're stuck with. The genie is out of
the bottle.

> Bento (used to?) optionally write the install scheme to a .py file named by
> the package author. Just lines of variable assignments path name =
> "some-path". And only if your program needs it at run time.
> It doesn't have to be another all capital letters filename in dist-info
> either. In the old system all the egg-info metadata was lowercase file names
> except PKG-INFO. Somehow uppercase has become the new style. I am guilty of
> it as well with WHEEL.

Are you serious, or just indulging in some lighthearted bikeshe- I mean,
banter? You're forgetting MANIFEST (distutils) and SOURCES.txt (setuptools).
Whatever the aesthetics of it, I suggested SHARED to be consistent with the
other names in PEP 376. I've implemented it now in distlib, and it seems to
work as far as it goes (no consideration has been given to namespace packages

> For the uninstall, recording created directory names in record is the most
> potentially sensible thing. It feels very wrong for the uninstaller to care

I did that with distlib, but it doesn't go far enough. A shared location (e.g.
bin) might be created when installing Foo, and added to when Bar is installed;
whichever of these gets uninstalled first, the behaviour should be the same in
terms of how to handle a non-empty bin. See below for more detail on what I
mean when I say "behaviour".

> about which folders are scripts and docs. You will have to explain more
> clearly to convince me.

I'll try - the longish explanation is in aid of clarity :-) It all depends on
your outlook. I believe it should be possible for packaging tools, while
uninstalling a distribution, to detect if there are any differences in state
from when it was installed. Sometimes it will be different, but differences
will be expected; in other cases, the differences will be unexpected. Ideally,
a packaging tool should be able to discern between these two categories of
difference. Even if *you* have no interest in writing such a tool or
exploiting this capability, someone else might want to; the idea of distlib is
to provide a decent underpinning for packaging tools that might comebalong in
the future.

Detecting differences between states at installation/uninstallation might seem
unimportant - it could be argued that disk space is cheap, and a bit of cruft
lying around doesn't really matter. But I think spotting unexpected occurrences
helps to produce more reliable software. For me, a good experience when
uninstalling something would be facilitated if the uninstaller tool had the
ability to tell me when:

(a) Some files were installed, but don't seem to be there any more.
(b) Some files were installed, but have been changed.
(c) Some directories were created, and files written to them, but now there
    are some additional files in there which the installer didn't put there.

So, I would like distlib to support the ability to do this, in case I ever want
to write such an uninstaller tool.

The (a) and (b) scenarios are already handled by comparing entries in RECORD
with the state of the filesystem.

The (c) scenario divides into two - sometimes you want to tell the user about
it, and at other times you don't. An extraneous file could just be a .bak file
created by an inadvertent save of a file you'd just meant to read in an editor,
or it could be some important data your program created but just put in the
wrong place. The uninstalling tool couldn't know which of these it is, so it
should tell the user about the discrepancy and let them decide what to do.
However, there are some situations where a directory you created and put files
into would be *expected* to be different at uninstallation time, so that you
don't need to bother the user by telling them about differences.


I install nose in the user site. I have a ~/.local but no ~/.local/bin or
~/.local/lib/pythonX.Y/site-packages, so these are created during installation.
The installation puts the "nosetests" script into ~/.local/bin. It also creates
the ~/.local/man directory, and writes a man page for the nosetests command
under there.

I then install Babel in the user site. This doesn't create ~/.local/bin as it's
already there, but puts "pybabel" into it.

Later, when looking at the nosetests an page in an editor, I inadvertently save
a backup nosetests.1.bak in the same directory as the man page.

Still later, I uninstall nose. With respect to directories touched by the nose
installation, there are two differences in state between installation and
uninstallation : The nosetests.1.bak file has appeared under ~/.local/man, and
the pybabel file has appeared in ~/.local/bin.

I would argue that it's worth telling the user about the .bak file - an
unexpected difference, harmless in this specific scenario but perhaps
indicative of a bug and/or important if the file were to consist of
expensively produced data just put in the wrong place because of a bug.

I would also argue that it's not worth telling the user about the pybabel file,
because it's in a location where you would expect differences, because it's
potentially a location shared between distributions.

My idea of recording the shared locations would allow distinguishing between
these two cases. If you don't care, you don't have to use them - but others
might want to.

Still here? Thanks for your patience :-)


Vinay Sajip

More information about the Distutils-SIG mailing list