[TIP] Why does tox use "pip install --pre" by default?

Donald Stufft donald at stufft.io
Mon Sep 29 12:27:21 PDT 2014

Resending since It wasn’t on the list and TIP apparently requires that.

On September 29, 2014 at 2:53:15 PM, Carl Meyer (carl at oddbird.net) wrote:
On 09/29/2014 12:32 PM, holger krekel wrote: 
> "consistency with pip" is a valid point in principle. 
> However, does anybody argue that "pip install --pre" was itself a good idea? 

I am not sure that `pip install --pre` is a very useful CLI API 
(probably the best argument for it is that it provides a way to easily 
say "make pip behave like it used to"), but I do think that pip's move 
to ignore non-final releases by default was a very good idea. I dealt 
with many complaints over the years from PyPI authors who assumed that 
if they had both 3.7 and 4.0a1 uploaded on PyPI, the toolchain would be 
smart enough somehow for their users to get 3.7 by default. 
The argument is that ``pip install --pre Django`` is easier to use than ``pip install Django>0.dev``. Perhaps --pre should only apply to the things named on the command line? I dunno!

> Are there many examples (besides Ned's) of people relying and using 
> that feature? 

I don't have numbers (Donald might; CCed him since I'm not sure he is on 
this list), but I have anecdotally heard from several different people 
who now upload pre-releases of their packages to PyPI based on pip's new 
I’m not on this list, so the CC is appreciated!

More people are using it, I’d need to do some queries to figure out the exact numbers but usage is increasing (one example of this is openstack).

> I doubt it because: 
> - you can't really depend on "--pre" because "easy_install" does not 
> support it and it's still producing some 20-25% of install actions 
> (https://caremad.io/blog/a-look-at-pypi-downloads/
Those numbers are a year old; it would be interesting to know how 
they've changed. I would expect that distribute is much lower now, at least. 
I’m actually working on a follow up blog post to that! Though I wasn’t planning on including that particular graph since I don’t think most people actually care, but I can at least generate it again.

I’m hesitant to share this here because it’s part of an in draft blog post and I haven’t actually verified the stuff that’s generating it to make sure my math and the code is correct, however here is the numbers filtered down to just pip: http://d.stufft.io/image/321U2U3r1g3t. This does not attempt to include setuptools in any way.

It would also be interesting to know how many of those easy_install 
downloads come from things like `setup_requires` or the 
auto-dependency-installation of `setup.py test`, as opposed to explicit 
installations. I'm not sure there's any way to get this information, though. 
There is not a way to determine setup_requires (or ``setup.py test``) vs ``easy_install``. For the record though, I have plans that will wrest control of setup_requires so that pip will install them instead of easy_install (when pip is the top level installer of course).

For better or worse, my experience is that many PyPI authors are already 
willing to ignore easy_install. With the advent of pip in the stdlib and 
wheels for binary distribution on Windows, I think it's safe to assume 
that its usage will continue to decrease. 

And if its usage did not decrease for whatever reason, now that 
setuptools is maintained by PyPA I would expect it to eventually follow 
pip's lead on this issue. I'd guess the only reason this hasn't been 
done already - and I'm making the assumption that it hasn't - is due to 
the assumption that easy_install is now only used for legacy reasons, 
and it's better to just leave legacy alone. 
I think usage might be lower right now though, I don’t believe it’s something you can really look at and say “that means nobody wants it”. Particularly even if you limit the things you care about to pip, the pre-release handling is only available in pip 1.4+, a lot of people use “whatever pip I get with ``apt-get install python-pip``” which for a lot of the distros is still a pre 1.4 pip. For instance 14.04 is the first ubuntu LTS to have a 1.4+ pip, and 13.10 was the first ubuntu at all. On the debian side of things you have to be using testing or unstable to get a 1.4+ pip.

The fact is, the pre-release handling is one of those things where you add the feature but folks can’t rely on it in general for awhile because they don’t have any control over what version of pip (or if pip is being used at all!) is being used so they have to wait until a version aware thing gains critical mass.

Of particular note though, is a nice little hack that authors *can* rely on today. pip 1.4 is both the version that introduced the pre-release handling, and the version that implemented support for Wheels. Authors of packages which are pure Python can distribute their pre-releases as Wheels but without sdists. Setuptools will ignore the Wheel files, pip prior to 1.4 will also, and pip 1.4+ won’t install it without —pre or a specifier that includes them.

Finally, setuptools 7.0 is currently slated to include PEP 440 however it hardcodes the —pre behavior so that it will always install pre-releases still. This is not a “setuptools wants to install pre-releases” decision though, Jason was on board with setuptools adopting the way pip (and now the PEP) treats pre-releases. This was a “I tried to implement —pre and got frustrated at the spaghetti that is setuptools and I gave up and just hardcoded to always allow pre-releases for now so that we can get the *other* PEP 440 stuff in”. I fully intend to go back and finish the job and unless Jason changes his mine it’ll have that behavior.

In summary: I think it's safe to say that "ignore non-final releases by 
default" is now the preferred and expected behavior for Python 
installers, and it will only become increasingly reasonable for authors 
to depend on that behavior. 
I agree with this.

> - it is too coarse grained: it will drag in non-stable versions from 
> the full dependency closure you are installing, not just one. So it's 
> usually better to have and maintain a "requirements.txt" with good 
> version specifiers if you want stability and "referential integrity" 
> between your tests and deployments. 

Yes, I agree. Note that this is not an argument against "ignore 
non-final releases by default". It is a good argument against `--pre` as 
the method for pulling in non-final releases. The better method is to 
specify the precise non-final release you want. 

I am not sure that arguments against `--pre` form arguments for 
continuing to use `--pre` in tox :-) 
Also with this, if their is better behavior for —pre please open a ticket!

>> I suppose it would be possible (though probably ugly) to implement this 
>> change with a deprecation-warning cycle. 
> If i'd go for it i'd suggest to directly change it in tox-1.9, adding a 
> "--pre" switch and a new default "install_command=pip install {opts} 
> {packages}" where the "tox --pre" switch changes the contents of 
> "{opts}". And i'd ask the people here on the ML pushing for the change 
> to submit a PR :) 

That's fair :-) If you approve the idea I will write the PR. 

Donald Stufft
PGP: 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/testing-in-python/attachments/20140929/2f1f0732/attachment.htm>

More information about the testing-in-python mailing list