On Wed, Jul 10, 2013 at 9:09 PM, Richard Jones <richard@python.org> wrote:
On 11 July 2013 06:50, Paul Moore <p.f.moore@gmail.com> wrote:
> I think "python -m pip" should be the canonical form (used in documentation,
> examples, etc). The unittest module has taken this route, as has timeit.
> Traditionally, python-dev have been lukewarm about the -m interface, but its
> key advantage is that it bypasses all the issues around versioned
> executables, cross-platform issues, the general dreadfulness of script
> wrappers on Windows, etc, in one fell swoop.

"python -m pip" does make the bootstrapping a more complex proposition
- the stdlib would have to have something called "pip" that could be
overridden (while it is actually *running*) by something installed in
site-packages. Not easy.

It's also fraught with historical baggage; remember xmlplus? That was extremely painful and something I believe everyone was glad to see go away.

Having said that, there are two solutions to this.

The compatible solution with older Python versions is to have the bootstrap download pip and have it installed as piplib or some other alternative name that is not masked by a pip stub in the stdlib.

The dead-simple, extremely elegant solution (starting in Python 3.4) is to make pip a namespace package in the stdlib with nothing more than a __main__.py file that installs pip; no checking if it's installed and then running it, etc, just blindly install pip. Then, if you install pip as a regular package, it takes precedence and what's in the stdlib is completely ignored (this helps with any possible staleness with the stdlib's bootstrap script vs. what's in pip, etc.). You don't even need to change the __main__.py in pip as it stands today since namespace packages only work if no regular package is found.

In case that didn't make sense, here is the file structure:

        __main__.py  # Install pip, nothing more
        pip  # Literally a shebang and two lines of Python; see below
        pip/  # As it stands today

This also means pip3 literally becomes ``import runpy; runpy.run_module('pip')``, so that is even easier to maintain (assuming pip's bin/ stub isn't already doing that because of backwards-compatibility concerns or something with __main__.py or runpy not existing far enough back, otherwise it should =).