[Python-Dev] Keyword meanings [was: Accept just PEP-0426]

PJ Eby pje at telecommunity.com
Wed Dec 5 22:10:14 CET 2012

On Wed, Dec 5, 2012 at 2:46 AM, Donald Stufft <donald.stufft at gmail.com> wrote:
> There's nothing preventing an installer from, during it's attempt to
> install B, see it Obsoletes A, looking at what depends on A and
> warning the user what is going to happen and prompt it.

Unless the user wrote those things that depend on A, they aren't going
to be in a position to do anything about it.  (Contrast with a distro,
where dependencies are indirect - the other package will depend on an
abstraction provided by both A and B, rather than directly depending
on A *or* B.)

(Also note that all the user knows at this point is that the author of
B *claims* to obsolete A, not that the authority managing the
repository as a whole has decreed B to obsolete A.)

> You can automatically uninstall A from B in an automatic dependency
management system

My point is that this can only work if the "obsoleting" is effectively
just a rename, in which case the field should be "renames", or better
still, "renamed-to" on the originating package.

As I've mentioned repeatedly, Obsoleted-By handles more use cases than
Obsoletes, and has at least one practical automated use case
(notifying a developer that their project is depending on something
that's obsolete).

Also, the example given as a use case in the PEP (Gorgon to Torqued)
is not just wrong, it's *actively misleading*.  Gorgon and Torqued are
transparent renames of Medusa and Twisted, which do not share a common
API and thus cannot be used as the subject of any automated processing
(in the case of Obsoletes) without doing some kind of PyPI metadata
search for every package installed every time a package is installed.

> I think Obsoletes as is an alright bit of information.

1. It cannot be used to prevent the installation of an obsolete
package without a PyPI metadata search, since you must examine every
*other* package on PyPI to find out whether some package obsoletes the
one you're trying to install.

2. Unlike RPM, where metadata is provided by a trusted third party,
Obsoletes can be specified by any random forker (no pun intended),
which makes this information a mere advertisement... and an
advertisement to the wrong audience at that, because they must have
*already* found B in order to discover that it replaces A!

3. Nobody has yet supplied a use case where Obsoletes would not be
strictly improved upon by Obsoleted-By.  (Note that "the author of
package X no longer maintains it" does not equal "package Y is
entitled to name itself the successor and enforce this upon all users"
-- this can work in RPM only because it is a third party Z who
declares Y the successor to X, and there is no such party Z in the
Python world.)

> I don't see this in this thread, could you link it again?


These posts also address why a "Conflicts" field is *also* unlikely to
be particularly useful in practice, in part for reasons that relate to
differences between RPM-land and Python-land.  (For example, RPMs can
conflict over things besides files, due to runtime and configuration
issues that are out-of-scope for a Python installer tool.)

While it's certainly desirable to not invent wheels, it's important to
understand that the Python community does not work the same way as a
Linux distribution.  We are not a single organization shipping a
fully-functional and configured machine, we are hundreds of individual
authors shipping our own stuff.  Conflict resolution and package
replacement (and even deciding what it is that things "provide" or
"require") are primarily *human* processes, not technical ones.
Relationship and support "contracts", IOW, rather than software

That's why, in the distro world, a package manager can use simple
fields to carry out the will of the human organization that made those
support and compatibility decisions.  For Python, the situation is a
bit more complicated, which is why clear thinking is needed.  Simply
copying fields blindly from other packaging systems just isn't going
to cut it.

Now, if the will of the community is to turn PyPI into a distro-style
repository, that's fine... but even if you completely ignore the human
issues, there are still technical ones.  Generally, distro-style
repositories work by downloading the full metadata set (or at least an
index) to a user's machine.  And that's the sort of architecture you'd
need in order for these type of fields to be technically feasible
(e.g., doing an index search for Obsoletes), without grinding the PyPI
servers into dust.

More information about the Python-Dev mailing list