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

PJ Eby pje at telecommunity.com
Fri Dec 7 06:47:25 CET 2012

On Thu, Dec 6, 2012 at 8:39 AM, Daniel Holth <dholth at gmail.com> wrote:
> It will be Obsoleted-By:. The "drop in replacement" requirement will be
> removed. The package manager will say "you are using these obsolete
> packages; check out these non-obsolete ones" but will not automatically pull
> the replacement without a Requires tag.

Sounds fine to me.

> I will probably add the unambiguous Conflicts: tag "uninstall this other
> package if I am installed".

Please don't.  See my lengthy posts from the previous PEP 345 retread
discussion for why, or ask MRAB to succinctly summarize them as he did
so brilliantly with the obsoletes/obsoleted-by issue.  ;-)

I'll take a stab at a short version, though: a conflict (other than
filename conflict) is not an installation-time property of a single
project, but rather a *runtime* property of an overall system to which
the projects are being installed, including configuration that is out
of scope for a Python-specific installation tool to manage.  In
addition, even declaring overall conflicts as a *mere shorthand* for
an existing file conflict creates the possibility of stale conflict

For example, RuleDispatch vs. PyDispatcher: at one time both provided
a "dispatch" package, but if RuleDispatch declared PyDispatcher
conflicting, the declaration would quickly have become outdated:
PyDispatcher soon renamed its provided package to resolve the
conflict.  A file-based system can both detect and resolve this
conflict (or lack thereof) automatically, whereas a manual "Conflicts"
notation must be maintained by the author(s) of one or both packages
and removed when out of date.

In effect, a "conflicts" field actually *creates* conflicts and
maintenance burdens where they did not previously exist, because even
after the conflict no longer really existed, an automated tool would
have prevented PyDispatch from being installed, or, per your
suggestion above, unnecessarily *uninstalled* it after a user
installed RuleDispatch.

And unlike the Obsoletes->Obsoleted-By change, I do not know of any
similar way to salvage the idea of a Conflicts field, without
reference to some mediating authority that manages the information on
behalf of an overall system into which the projects are being fitted.
But in that case, neither of the projects really owns the declaration
- it's more like Zope (say) would need a list of plugins that conflict
with each other, or they could declare that they conflict when
activated in the same instance.

A generic Python installer, however, that doesn't know about Zope
instances or Apache vhosts or Django apps or any other "environment of
conflict", can't assume that *mere installation* constitutes a
conflict!  It doesn't know, for example, whether code from two
simultaneously-installed packages will ever even be *imported* in the
same process, let alone whether their specific conflicting features
will be used in that process.

This effectively ensures that in general, Python installation tools
can *only* rely on file-based conflicts as being denotable by project
metadata -- and even then, it's better to stick with *actual* file
conflicts rather than predicted ones, to avoid the type of logjam
described above.

P.S. Sorry once again to drag you through all this at the last minute;
I just sort of assumed you picked up where Alexis left off on the
previous attempt at an update to PEP 345 and didn't pay close enough
attention to earlier drafts.

More information about the Python-Dev mailing list