[Distutils] easy_install should consider the development status of packages

Phillip J. Eby pje at telecommunity.com
Thu Sep 27 18:34:35 CEST 2007

At 08:30 AM 9/15/2007 +0200, Stefan Behnel wrote:
>currently, lxml has both a stable release series (1.3.x) and an unstable alpha
>release series (2.0alphaX) on PyPI. When you "easy_install lxml", you get the
>2.0alpha version. I don't think that's what users expect and it's definitely
>not what most users want, but at the same time I would like to keep 2.0
>visible and easy_install-able to make people aware of it and to let them
>decide by themselves.
>I would like to have easy_install changed to either consider the Trove
>development status of a package and prefer the highest one (or at least those
>from 5 up), and/or to check the version string for the typical alpha/beta
>substrings and ignore them by default. It would then be easy to add a command
>line option like "--unstable" for those who know better.
>Any comments on that?

Patches welcome.  I would prefer to see it implemented as the ability 
to specify a level of stability, so that for example I could specify 
that beta is an okay stability level.

The main place where you should be looking for the patch to work is 
in the fetch_distribution method of the PackageIndex class in 
setuptools.package_index.  There is only one call to this method from 
the easy_install command class, so the hookup should be straightforward.

You'll need to scan the distribution object's "parsed_version" to 
determine its compliance with a particular stability level.  And, to 
get the stability level in the first place, you'll need to use 
pkg_resources.parse_version and take the zeroth element for 
comparison purposes:

 >>> from pkg_resources import parse_version as pv
 >>> pv('a')
('*a', '*final')
 >>> pv('b')
('*b', '*final')
 >>> pv('rc')
('*c', '*final')
 >>> pv('dev')
('*@', '*final')
 >>> pv('final')
('*final', '*final')

The parsed_version of a package will look something like:

 >>> pv('2.0a5')
('00000002', '*a', '00000005', '*final')

 >>> pv('1.3.2')
('00000001', '00000003', '00000002', '*final')

So, to look for stable packages, you want to look for a stability of 
'final'.  A package should be disqualified if it contains any 
non-numeric part that is < the acceptable stability.  Thus, if you 
set a stability of "a", 2.0a6dev-r15435 should fail because:

 >>> pv('2.0a6dev-r15435')
('00000002', '*a', '00000006', '*@', '*final-', '*r', '00015435', '*final')

As you can see, it contains a '*@' to represent the 'dev' part, so it 
lacks alpha stability.

Oh, and don't forget that this stability rejection should be a 
*preference*, i.e. if there is no version matching the stability 
setting and the version requirements, the stability requirement 
should be dropped.

More information about the Distutils-SIG mailing list