Make sure the bootstrap script actually works:: >>> import os, sys >>> from os.path import dirname, join >>> import zc.buildout >>> bootstrap_py = join( ... dirname( ... dirname( ... dirname( ... dirname(zc.buildout.__file__) ... ) ... ) ... ), ... 'bootstrap', 'bootstrap.py') >>> sample_buildout = tmpdir('sample') >>> os.chdir(sample_buildout) >>> write('buildout.cfg', ... ''' ... [buildout] ... parts = ... ''') >>> write('bootstrap.py', open(bootstrap_py).read()) >>> print_('X'); print_(system( ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+ ... 'bootstrap.py')); print_('X') # doctest: +ELLIPSIS X... Creating directory '/sample/eggs'. Creating directory '/sample/bin'. Creating directory '/sample/parts'. Creating directory '/sample/develop-eggs'. Generated script '/sample/bin/buildout'. ... >>> ls(sample_buildout) d bin - bootstrap.py - buildout.cfg d develop-eggs d eggs d parts >>> ls(sample_buildout, 'bin') - buildout >>> print_('X'); ls(sample_buildout, 'eggs') # doctest: +ELLIPSIS X... d zc.buildout-...egg By default it gets the latest version: >>> buildout_script = join(sample_buildout, 'bin', 'buildout') >>> if sys.platform.startswith('win'): ... buildout_script += '-script.py' >>> print_(open(buildout_script).read()) # doctest: +ELLIPSIS #... sys.path[0:0] = [ '/sample/eggs/setuptools-...egg', '/sample/eggs/zc.buildout-22.0.0...egg', ]... Now trying the `--buildout-version` option, that let you define a version for `zc.buildout`. Let's try with an unknown version:: >>> print_('X'); print_(system( ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+ ... 'bootstrap.py --buildout-version UNKNOWN')); print_('X') # doctest: +ELLIPSIS ... X ... No local packages or...download links found for zc.buildout==UNKNOWN ... Now let's try with `2.0.0`, which happens to exist:: >>> print_('X'); print_(system( ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+ ... 'bootstrap.py --buildout-version 2.0.0')); print_('X') ... # doctest: +ELLIPSIS X...Generated script '/sample/bin/buildout'...X Let's make sure the generated `buildout` script uses it:: >>> print_(open(buildout_script).read()) # doctest: +ELLIPSIS #... sys.path[0:0] = [ '/sample/eggs/setuptools-...egg', '/sample/eggs/zc.buildout-2.0.0...egg', ]... Now trying the `--setuptools-version` option, that let you define a version for `setuptools`. Now let's try with `8.0`, which happens to exist:: >>> print_('X'); print_(system( ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+ ... 'bootstrap.py --setuptools-version 8.0')); print_('X') ... # doctest: +ELLIPSIS X...Generated script '/sample/bin/buildout'...X Let's make sure the generated `buildout` script uses it:: >>> print_(open(buildout_script).read()) # doctest: +ELLIPSIS #... sys.path[0:0] = [ '/sample/eggs/setuptools-8.0...egg', '/sample/eggs/zc.buildout-...egg', ]... Now let's try specifying both `zc.buildout` and `setuptools` to versions which happens to exist:: >>> print_('X'); print_(system( ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+ ... 'bootstrap.py --setuptools-version 8.0 --buildout-version 2.0.0')); print_('X') ... # doctest: +ELLIPSIS X...Generated script '/sample/bin/buildout'...X Let's make sure the generated `buildout` script uses it:: >>> print_(open(buildout_script).read()) # doctest: +ELLIPSIS #... sys.path[0:0] = [ '/sample/eggs/setuptools-8.0...egg', '/sample/eggs/zc.buildout-2.0.0...egg', ]... For a completely offline install we want to avoid downloading ez_setup.py, specify the setuptools version, and to reuse the setuptools zipfile. >>> try: ... from urllib.request import urlopen ... except ImportError: ... from urllib2 import urlopen >>> ez_setup = urlopen('https://bootstrap.pypa.io/ez_setup.py').read() >>> write('ez_setup.py', ... '''print("Using local ez_setup.py") ... ''' + ez_setup.decode('ascii')) >>> os.path.exists('setuptools-14.3.zip') False >>> print_('X'); print_(system( ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+ ... 'bootstrap.py --setuptools-version 14.3 --buildout-version 2.0.0 '+ ... '--setuptools-to-dir .')); print_('X') ... # doctest: +ELLIPSIS X...Using local ez_setup.py...Generated script '/sample/bin/buildout'...X >>> os.path.exists('setuptools-14.3.zip') True >>> print_(open(buildout_script).read()) # doctest: +ELLIPSIS #... sys.path[0:0] = [ '/sample/eggs/setuptools-14.3...egg', '/sample/eggs/zc.buildout-2.0.0...egg', ]... You can ask bootstrap.py for its version. This is really the day the last change was made. A date leads to less confusion than a version number separate from buildout's own version number. Similarly, tracking buildout's version number leads to bootstraps with a new version number but without changes or to bootstraps with version number from an already-older buildout. So: a date is best. >>> print_('X'); print_(system( ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+ ... 'bootstrap.py --version')); print_('X') ... # doctest: +ELLIPSIS X...2015...X