[Distutils] install_recommends proposal

Martijn Faassen faassen at startifact.com
Wed Sep 26 15:11:08 CEST 2007


Hi there,

Currently setup.py allows install_requires to specify the dependencies, 
possibly including exact version numbers of a package.

It is however beneficial to only specify the *minimum* of expected 
requirements in there, to retain maximum flexibility of use. This means 
you'd typically say:

   install_requires = [
      'foo',
      'bar >= 1.3',
   ]

if you know you need some version of foo, and at least version 1.3 of 
your package. This allows developers who use your package to choose 
themselves which version of foo and bar they want to use, without 
getting version conflicts as long as you stay within the stated constraints.

If you write a framework, or a library that uses other libraries, you 
sometimes want to do something more. You'd like to ensure that if 
someone uses version X of your framework, they use a list of *exact* 
dependencies, that is, exactly foo 1.2 and bar 1.4.3. This makes all 
installations of framework X bug for bug compatible. New releases of 
packages you depend on don't break your framework install, as the 
framework install will ensure those versions.

I'd therefore like to propose a new setup.py section where these can be 
specified:

    install_recommends = [
      'foo == 1.2',
      'bar == 1.4.3',
    ]

The person or tool installing the package is entirely free to ignore 
this information; it's a recommendation, not a requirement. The only 
specifications that can be made are *exact*; there is no support for 
anything but '=='. Distutils at most needs to be taught that 
install_recommends cannot directly conflict with install_requires. This 
would be a conflict:

   install_requires = [
      'bar > 1.3'
   ],
   install_recommends = [
      'bar == 1.2',
   ]

By default, distutils and setuptools would otherwise ignore this 
information. I do presume setuptools would include this information in 
egg-info so that external tools can make use of it.

This information can then be (optionally) used by a tool like buildout 
to ensure exact dependencies are installed (once zc.buildout is taught 
to use this information, of course). This means I can release a 
framework that allows flexibility to knowledgable developers, but also, 
in its default install, doesn't have the chance of breaking the moment 
someone releases a new version of some dependency.

For an extensive article where I describe what led me to look for this 
read this:

http://faassen.n--tree.net/blog/view/weblog/2007/09/26/0

It goes into much detail on the concerns and reasoning behind this in 
the context of the development of Zope 3, and Grok, a framework based on 
many Zope 3 packages. This isn't a theoretical problem but is currently 
biting us regularly. I'll also note that it looks like zc.buildout 
doesn't appear to need much work to start using this information (but 
Jim will correct me if I'm wrong).

Regards,

Martijn



More information about the Distutils-SIG mailing list