[Distutils] Support for condition to include or exclude a buildout sections based on a Python expression

Philippe Ombredanne pombredanne at nexb.com
Tue Jan 29 15:02:39 CET 2013


I prepared a pull request https://github.com/buildout/buildout/pull/51
to add support in Buildout 2 for conditional sections expressions.

The gist of this is explained here:

Sections headers can contain an optional arbitrary Python expression.
When the expression evaluates to false the whole section is skipped.

Several sections can have the same name with different expressions, enabling
conditional exclusion of sections.  For instance using simple
expressions you can get this done:

  # this expression is true, so the section is included
  [s1: 2 + 2 == 4]
  a = 1

  # this expression is false, so the section s2 is skipped
  [s2 : 2 + 2 == 5 ]
  long = a

  # Complex expressions are possible, though they should not be abused
:) and they need to fit on a single line
  [s3:2 in map(lambda i:i*2, [i for i in range(10)])]
  long = c

One of the typical usage is to have buildout parts that are operating
system or plaform specific, such as defining eggs that may run only on
one os (such as readline only for  Macosx and pyreadline only for
Windows.). There some convenience defaults conditionals pre-computed
as well as some default modules available to an expression to support

[install_eggs: windows]
recipe = zc.recipe.egg
eggs = pyreadline


[install_eggs: macosx]
recipe = zc.recipe.egg
eggs = readline

... become possible and only the right section will be included.

The limited (but hopefully sane and sufficient)  set of default
modules and precomputed common expressions are:

  # available modules sys, re, os and platfrom should cover most of
the  common cases
  [s1: sys and re and os and platform]

  # major and minor python versions, yes even python 3.5 and 3.6 are
there, prospectively
  [s2: any([python2, python3, python24 , python25 , python26 ,
python27 , python30 , python31 , python32 , python33 , python34 ,
python35 , python36]) ]

  # common python interpreter types
  [s3: cpython or pypy or jython or ironpython]

  # common operating systems
  [s4: linux or windows or cygwin or macosx or solaris or posix ]

  # common bitness and endianness
  [s5: bits32 or bits64 or little_endian or big_endian]

Some other points:

 - expression are evaluated _during parsing_ of a cfg file, so before
interpolation, hence variable substitution are not possible... we
could populate the expression context with a copy of the current state
of the buildout object to provide some limited access to some of the
buildout options and sections that are already known at the parsing

- security could be a concern, but hey if you are running buildout you
are already letting run arbitrary code and recipes downloaded live
from unknown sources, so I do not think this is a big concern.

- if you do not use expressions in your buildout, there is no impact at all.

Feedback on the code and features is welcomed... ATM the code is ready
to pull in and all the tests are passing

Philippe Ombredanne

+1 650 799 0949 | pombredanne at nexB.com
DejaCode Enterprise at http://www.dejacode.com
nexB Inc. at http://www.nexb.com

More information about the Distutils-SIG mailing list