[Checkins] SVN: zc.recipe.testrunner/trunk/ update to zc.buildout 1.5.0 support. Development works with system Python.

Gary Poster gary.poster at canonical.com
Fri Aug 27 22:44:24 EDT 2010


Log message for revision 115978:
  update to zc.buildout 1.5.0 support.  Development works with system Python.

Changed:
  U   zc.recipe.testrunner/trunk/CHANGES.txt
  U   zc.recipe.testrunner/trunk/bootstrap.py
  U   zc.recipe.testrunner/trunk/setup.py
  U   zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/README.txt
  U   zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/__init__.py
  U   zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/tests.py

-=-
Modified: zc.recipe.testrunner/trunk/CHANGES.txt
===================================================================
--- zc.recipe.testrunner/trunk/CHANGES.txt	2010-08-28 02:18:57 UTC (rev 115977)
+++ zc.recipe.testrunner/trunk/CHANGES.txt	2010-08-28 02:44:24 UTC (rev 115978)
@@ -5,6 +5,10 @@
 1.4.0 (unreleased)
 ==================
 
+- Update to using zc.buildout 1.5.0 script generation.  This adds the
+  following options: include-site-packages, allowed-eggs-from-site-packages,
+  extends, and exec-sitecustomize.
+
 - Merge fixes from 1.2.1 (svn://svn.zope.org/repos/main/zc.recipe.testrunner/tags/1.2.1)
   Excluding nailing zope.testing version. That fixes a bunch of windows issues
 
@@ -13,7 +17,7 @@
 
 - Updated tests to run with the last versions of all modules.
 
-- Removed the usage of the deprecated zope.testing.doctest, therby also
+- Removed the usage of the deprecated zope.testing.doctest, thereby also
   dropping Python 2.3 support.
 
 - Started using zope.testrunner instead of zope.testing.testrunner.

Modified: zc.recipe.testrunner/trunk/bootstrap.py
===================================================================
--- zc.recipe.testrunner/trunk/bootstrap.py	2010-08-28 02:18:57 UTC (rev 115977)
+++ zc.recipe.testrunner/trunk/bootstrap.py	2010-08-28 02:44:24 UTC (rev 115978)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2006 Zope Corporation and Contributors.
+# Copyright (c) 2006 Zope Foundation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -16,37 +16,243 @@
 Simply run this script in a directory containing a buildout.cfg.
 The script accepts buildout command-line options, so you can
 use the -c option to specify an alternate configuration file.
-
-$Id$
 """
 
-import os, shutil, sys, tempfile, urllib2
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
 
-tmpeggs = tempfile.mkdtemp()
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
 
-ez = {}
-exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
-                     ).read() in ez
-ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
 
-import pkg_resources
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if (hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
 
-cmd = 'from setuptools.command.easy_install import main; main()'
-if sys.platform == 'win32':
-    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+is_jython = sys.platform.startswith('java')
 
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
 ws = pkg_resources.working_set
-assert os.spawnle(
-    os.P_WAIT, sys.executable, sys.executable,
-    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
-    dict(os.environ,
-         PYTHONPATH=
-         ws.find(pkg_resources.Requirement.parse('setuptools')).location
-         ),
-    ) == 0
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
 
-ws.add_entry(tmpeggs)
-ws.require('zc.buildout')
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
 import zc.buildout.buildout
-zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
-shutil.rmtree(tmpeggs)
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Modified: zc.recipe.testrunner/trunk/setup.py
===================================================================
--- zc.recipe.testrunner/trunk/setup.py	2010-08-28 02:18:57 UTC (rev 115977)
+++ zc.recipe.testrunner/trunk/setup.py	2010-08-28 02:44:24 UTC (rev 115978)
@@ -32,10 +32,10 @@
     extras_require = {
         'tests': ['zope.testing'],
         },
-    install_requires = ['zc.buildout >=1.2.0',
+    install_requires = ['zc.buildout >=1.5.0',
                         'zope.testrunner',
                         'setuptools',
-                        'zc.recipe.egg  >=1.2.0',
+                        'z3c.recipe.scripts  >=1.0.0',
                         ],
     tests_require = ['zope.testing'],
     test_suite = name+'.tests.test_suite',

Modified: zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/README.txt
===================================================================
--- zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/README.txt	2010-08-28 02:18:57 UTC (rev 115977)
+++ zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/README.txt	2010-08-28 02:44:24 UTC (rev 115978)
@@ -40,6 +40,53 @@
 relative-paths
     Use egg, test, and working-directory paths relative to the test script.
 
+include-site-packages
+    You can choose to have the site-packages of the underlying Python
+    available to your script or interpreter, in addition to the packages
+    from your eggs.  See `the z3c.recipe.scripts documentation`_ for
+    motivations and warnings.
+
+allowed-eggs-from-site-packages
+    Sometimes you need or want to control what eggs from site-packages are
+    used. The allowed-eggs-from-site-packages option allows you to specify a
+    whitelist of project names that may be included from site-packages.  You
+    can use globs to specify the value.  It defaults to a single value of '*',
+    indicating that any package may come from site-packages.
+
+    Here's a usage example::
+
+        [buildout]
+        ...
+
+        allowed-eggs-from-site-packages =
+            demo
+            bigdemo
+            zope.*
+
+    This option interacts with the ``include-site-packages`` option in the
+    following ways.
+
+    If ``include-site-packages`` is true, then
+    ``allowed-eggs-from-site-packages`` filters what eggs from site-packages
+    may be chosen.  Therefore, if ``allowed-eggs-from-site-packages`` is an
+    empty list, then no eggs from site-packages are chosen, but site-packages
+    will still be included at the end of path lists.
+
+    If ``include-site-packages`` is false, the value of
+    ``allowed-eggs-from-site-packages`` is irrelevant.
+
+extends
+    You can extend another section using this value.  It is intended to help
+    you avoid repeating yourself.
+
+exec-sitecustomize
+    Normally the Python's real sitecustomize module is not processed.
+    If you want it to be processed, set this value to 'true'.  This will
+    be honored irrespective of the setting for include-site-packages.
+
+.. _`the z3c.recipe.scripts documentation`:
+    http://pypi.python.org/pypi/z3c.recipe.scripts#including-site-packages-and-sitecustomize
+
 (Note that, at this time, due to limitations in the Zope test runner, the
 distributions cannot be zip files. TODO: Fix the test runner!)
 
@@ -155,20 +202,27 @@
     -  buildout
     -  test
 
-We also get a part directory for the tests to run in:
+We also get a "testdemo" parts directory:
 
     >>> ls(sample_buildout, 'parts')
+    d  buildout
     d  testdemo
 
+The testdemo directory has a "working-directory," in which tests are run.
+(The site-packages directory is support for the test script.)
 
-And updating leaves its contents intact:
+    >>> ls(sample_buildout, 'parts', 'testdemo')
+    d  site-packages
+    d  working-directory
 
+Updating leaves its contents intact:
+
     >>> _ = system(os.path.join(sample_buildout, 'bin', 'test') +
     ...            ' -q --coverage=coverage')
-    >>> ls(sample_buildout, 'parts', 'testdemo')
+    >>> ls(sample_buildout, 'parts', 'testdemo', 'working-directory')
     d  coverage
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
-    >>> ls(sample_buildout, 'parts', 'testdemo')
+    >>> ls(sample_buildout, 'parts', 'testdemo', 'working-directory')
     d  coverage
 
 We can run the test script to run our demo test:
@@ -235,30 +289,22 @@
 
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
-    >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    >>> cat(sample_buildout, 'parts', 'testdemo', 'site-packages', 'site.py')
+    ... # doctest: +ELLIPSIS
+    "...
+    def addsitepackages(known_paths):
+        """Add site packages, as determined by zc.buildout.
     <BLANKLINE>
-    import sys
-    sys.path[0:0] = [
-      '/sample-buildout/demo',
-      '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
-      '/sample-buildout/eggs/zope.interface-3.4.1-py2.4.egg',
-      '/sample-buildout/eggs/zope.exceptions-3.5.2-py2.4.egg',
-      '/sample-buildout/eggs/setuptools-0.6-py1.3.egg',
-      '/usr/local/zope/lib/python',
-      ]
-    <BLANKLINE>
-    import os
-    sys.argv[0] = os.path.abspath(sys.argv[0])
-    os.chdir('/sample-buildout/parts/testdemo')
-    <BLANKLINE>
-    <BLANKLINE>
-    import zope.testrunner
-    <BLANKLINE>
-    if __name__ == '__main__':
-        zope.testrunner.run([
-            '--test-path', '/sample-buildout/demo',
-            ])
+        See original_addsitepackages, below, for the original version."""
+        buildout_paths = [
+            '/sample-buildout/demo',
+            '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
+            '/sample-buildout/eggs/zope.interface-3.4.1-py2.4.egg',
+            '/sample-buildout/eggs/zope.exceptions-3.5.2-py2.4.egg',
+            '/sample-buildout/eggs/setuptools-0.6-py1.3.egg',
+            '/usr/local/zope/lib/python'
+            ]
+    ...
 
 We can use the working-directory option to specify a working
 directory:
@@ -280,23 +326,24 @@
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
     >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    #!/usr/local/bin/python2.4 -S
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
-      '/sample-buildout/demo',
-      '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
-      '/sample-buildout/eggs/zope.interface-3.4.1-py2.4.egg',
-      '/sample-buildout/eggs/zope.exceptions-3.5.2-py2.4.egg',
-      '/sample-buildout/eggs/setuptools-0.6-py1.3.egg',
-      '/usr/local/zope/lib/python',
-      ]
+        '/sample-buildout/parts/testdemo/site-packages',
+        ]
     <BLANKLINE>
+    <BLANKLINE>
     import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
     sys.argv[0] = os.path.abspath(sys.argv[0])
     os.chdir('/foo/bar')
     <BLANKLINE>
-    <BLANKLINE>
     import zope.testrunner
     <BLANKLINE>
     if __name__ == '__main__':
@@ -304,11 +351,13 @@
             '--test-path', '/sample-buildout/demo',
             ])
 
-Now that out tests use a specified working directory, their designated
+Now that our tests use a specified working directory, their designated
 part directory is gone:
 
-    >>> ls(sample_buildout, 'parts')
+    >>> ls(sample_buildout, 'parts', 'testdemo')
+    d  site-packages
 
+
 If we need to specify default options, we can use the defaults
 option. For example, Zope 3 applications typically define test suites
 in modules named ftests or tests.  The default test runner behaviour
@@ -336,23 +385,24 @@
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
     >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    #!/usr/local/bin/python2.4 -S
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
-      '/sample-buildout/demo',
-      '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
-      '/sample-buildout/eggs/zope.interface-3.4.1-py2.4.egg',
-      '/sample-buildout/eggs/zope.exceptions-3.5.2-py2.4.egg',
-      '/sample-buildout/eggs/setuptools-0.6-py1.3.egg',
-      '/usr/local/zope/lib/python',
-      ]
+        '/sample-buildout/parts/testdemo/site-packages',
+        ]
     <BLANKLINE>
+    <BLANKLINE>
     import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
     sys.argv[0] = os.path.abspath(sys.argv[0])
-    os.chdir('/sample-buildout/parts/testdemo')
+    os.chdir('/sample-buildout/parts/testdemo/working-directory')
     <BLANKLINE>
-    <BLANKLINE>
     import zope.testrunner
     <BLANKLINE>
     if __name__ == '__main__':
@@ -362,6 +412,7 @@
             '--test-path', '/sample-buildout/demo',
             ])
 
+
 Some things to note from this example:
 
 - Parentheses are placed around the given expression.
@@ -434,23 +485,25 @@
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
     >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    #!/usr/local/bin/python2.4 -S
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
-      '/sample-buildout/demo',
-      '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
-      '/sample-buildout/eggs/zope.interface-3.4.1-py2.4.egg',
-      '/sample-buildout/eggs/zope.exceptions-3.5.2-py2.4.egg',
-      '/sample-buildout/eggs/setuptools-0.6-py1.3.egg',
-      ]
+        '/sample-buildout/parts/testdemo/site-packages',
+        ]
     <BLANKLINE>
+    <BLANKLINE>
     import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
     sys.argv[0] = os.path.abspath(sys.argv[0])
-    os.chdir('/sample-buildout/parts/testdemo')
+    os.chdir('/sample-buildout/parts/testdemo/working-directory')
     os.environ['zc.recipe.testrunner'] = '42'
     <BLANKLINE>
-    <BLANKLINE>
     import zope.testrunner
     <BLANKLINE>
     if __name__ == '__main__':
@@ -491,21 +544,23 @@
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
     >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    #!/usr/local/bin/python2.4 -S
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
-      '/sample-buildout/demo',
-      '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
-      '/sample-buildout/eggs/zope.interface-3.4.1-py2.4.egg',
-      '/sample-buildout/eggs/zope.exceptions-3.5.2-py2.4.egg',
-      '/sample-buildout/eggs/setuptools-0.6-py1.3.egg',
-      '/usr/local/zope/lib/python',
-      ]
+        '/sample-buildout/parts/testdemo/site-packages',
+        ]
     <BLANKLINE>
+    <BLANKLINE>
     import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
     sys.argv[0] = os.path.abspath(sys.argv[0])
-    os.chdir('/sample-buildout/parts/testdemo')
+    os.chdir('/sample-buildout/parts/testdemo/working-directory')
     print 'Hello all you egg-laying pythons!'
     <BLANKLINE>
     import zope.testrunner
@@ -540,21 +595,23 @@
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
     >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    #!/usr/local/bin/python2.4 -S
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
-      '/sample-buildout/demo',
-      '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
-      '/sample-buildout/eggs/zope.interface-3.4.1-py2.4.egg',
-      '/sample-buildout/eggs/zope.exceptions-3.5.2-py2.4.egg',
-      '/sample-buildout/eggs/setuptools-0.6-py1.3.egg',
-      '/usr/local/zope/lib/python',
-      ]
+        '/sample-buildout/parts/testdemo/site-packages',
+        ]
     <BLANKLINE>
+    <BLANKLINE>
     import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
     sys.argv[0] = os.path.abspath(sys.argv[0])
-    os.chdir('/sample-buildout/parts/testdemo')
+    os.chdir('/sample-buildout/parts/testdemo/working-directory')
     print 'Hello all you egg-laying pythons!'
     print 'I thought pythons were live bearers?'
     <BLANKLINE>
@@ -588,7 +645,7 @@
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
     >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    #!/usr/local/bin/python2.4 -S
     <BLANKLINE>
     import os
     <BLANKLINE>
@@ -598,20 +655,20 @@
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
-      join(base, 'demo'),
-      join(base, 'eggs/zope.testrunner-4.0.0-py2.4.egg'),
-      join(base, 'eggs/zope.interface-3.5.1-py2.4-linux-i686.egg'),
-      join(base, 'eggs/zope.exceptions-3.5.2-linux-i686.egg'),
-      join(base, 'eggs/setuptools-0.6c9-py2.4.egg'),
-      '/usr/local/zope/lib/python',
-      join(base, 'sources'),
-      ]
+        join(base, 'parts/testdemo/site-packages'),
+        ]
     <BLANKLINE>
+    <BLANKLINE>
     import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
     sys.argv[0] = os.path.abspath(sys.argv[0])
-    os.chdir(join(base, 'parts/testdemo'))
+    os.chdir(join(base, 'parts/testdemo/working-directory'))
     <BLANKLINE>
-    <BLANKLINE>
     import zope.testrunner
     <BLANKLINE>
     if __name__ == '__main__':
@@ -619,6 +676,29 @@
             '--test-path', join(base, 'demo'),
             ])
 
+    >>> cat(sample_buildout, 'parts', 'testdemo', 'site-packages', 'site.py')
+    ... # doctest: +ELLIPSIS
+    "...
+    def addsitepackages(known_paths):
+        """Add site packages, as determined by zc.buildout.
+    <BLANKLINE>
+        See original_addsitepackages, below, for the original version."""
+        join = os.path.join
+        base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
+        base = os.path.dirname(base)
+        base = os.path.dirname(base)
+        base = os.path.dirname(base)
+        buildout_paths = [
+            join(base, 'demo'),
+            join(base, 'eggs/zope.testrunner-4.0.0-py2.4.egg'),
+            join(base, 'eggs/zope.interface-3.5.1-py2.4-linux-i686.egg'),
+            join(base, 'eggs/zope.exceptions-3.5.2-linux-i686.egg'),
+            join(base, 'eggs/setuptools-0.6c9-py2.4.egg'),
+            '/usr/local/zope/lib/python',
+            join(base, 'sources')
+            ]
+    ...
+
 The relative-paths option can be specified at the buildout level:
 
     >>> write(sample_buildout, 'buildout.cfg',
@@ -639,7 +719,7 @@
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
 
     >>> cat(sample_buildout, 'bin', 'testdemo')
-    #!/usr/local/bin/python2.4
+    #!/usr/local/bin/python2.4 -S
     <BLANKLINE>
     import os
     <BLANKLINE>
@@ -649,20 +729,20 @@
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
-      join(base, 'demo'),
-      join(base, 'eggs/zope.testrunner-4.0.0-py2.4.egg'),
-      join(base, 'eggs/zope.interface-3.5.1-py2.4-linux-i686.egg'),
-      join(base, 'eggs/zope.exceptions-3.5.2-linux-i686.egg'),
-      join(base, 'eggs/setuptools-0.6c9-py2.4.egg'),
-      '/usr/local/zope/lib/python',
-      join(base, 'sources'),
-      ]
+        join(base, 'parts/testdemo/site-packages'),
+        ]
     <BLANKLINE>
+    <BLANKLINE>
     import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
     sys.argv[0] = os.path.abspath(sys.argv[0])
-    os.chdir(join(base, 'parts/testdemo'))
+    os.chdir(join(base, 'parts/testdemo/working-directory'))
     <BLANKLINE>
-    <BLANKLINE>
     import zope.testrunner
     <BLANKLINE>
     if __name__ == '__main__':
@@ -670,3 +750,368 @@
             '--test-path', join(base, 'demo'),
             ])
 
+-------------------------
+Support for system Python
+-------------------------
+
+zc.recipe.testrunner 1.4.0 added support for zc.buildout 1.5's system Python
+support.
+
+By default, this means that, if the buildout is set up as described in the
+`pertinent section of the zc.buildout documentation`_ then the scripts
+generated by this recipe will be safe to use with a system Python.
+
+You can also use the same options as provided by z3c.recipe.scripts (and
+the functionality is delegated to code from this package).  That package
+is well-tested, so this merely quickly demonstrates usage.
+
+include-site-packages
+---------------------
+
+Use this to include site-packages from the Python you are using.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... parts = testdemo
+    ... offline = true
+    ...
+    ... [testdemo]
+    ... recipe = zc.recipe.testrunner
+    ... eggs = demo
+    ... include-site-packages = true
+    ... """)
+
+.. ReST comment: Hide the rest of the test from PyPI readers.
+
+    >>> ignore = system(
+    ...     os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
+
+    >>> cat(sample_buildout, 'parts', 'testdemo', 'site-packages', 'site.py')
+    ... # doctest: +ELLIPSIS
+    "...
+    def addsitepackages(known_paths):
+        """Add site packages, as determined by zc.buildout.
+    <BLANKLINE>
+        See original_addsitepackages, below, for the original version."""
+        setuptools_path = '...'
+        sys.path.append(setuptools_path)
+        known_paths.add(os.path.normcase(setuptools_path))
+        import pkg_resources
+        buildout_paths = [
+            '/sample-buildout/demo',
+            '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
+            '/sample-buildout/eggs/zope.exceptions-3.4.1-py2.4.egg'
+            ]
+        for path in buildout_paths:
+            sitedir, sitedircase = makepath(path)
+            if not sitedircase in known_paths and os.path.exists(sitedir):
+                sys.path.append(sitedir)
+                known_paths.add(sitedircase)
+                pkg_resources.working_set.add_entry(sitedir)
+        sys.__egginsert = len(buildout_paths) # Support distribute.
+        original_paths = [
+            ...
+            ]
+        for path in original_paths:
+            if path == setuptools_path or path not in known_paths:
+                addsitedir(path, known_paths)
+        return known_paths
+    ...
+
+Note that a setting in the buildout section will also be honored, if it is
+not overridden locally.
+
+.. ReST comment: Hide the test from PyPI readers.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... parts = testdemo
+    ... offline = true
+    ... include-site-packages = true
+    ...
+    ... [testdemo]
+    ... recipe = zc.recipe.testrunner
+    ... eggs = demo
+    ... """)
+
+    >>> ignore = system(
+    ...     os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
+
+    >>> cat(sample_buildout, 'parts', 'testdemo', 'site-packages', 'site.py')
+    ... # doctest: +ELLIPSIS
+    "...
+    def addsitepackages(known_paths):
+        """Add site packages, as determined by zc.buildout.
+    <BLANKLINE>
+        See original_addsitepackages, below, for the original version."""
+        setuptools_path = '...'
+        sys.path.append(setuptools_path)
+        known_paths.add(os.path.normcase(setuptools_path))
+        import pkg_resources
+        buildout_paths = [
+            '/sample-buildout/demo',
+            '/sample-buildout/eggs/zope.testrunner-4.0-py2.3.egg',
+            '/sample-buildout/eggs/zope.exceptions-3.4.1-py2.4.egg'
+            ]
+        for path in buildout_paths:
+            sitedir, sitedircase = makepath(path)
+            if not sitedircase in known_paths and os.path.exists(sitedir):
+                sys.path.append(sitedir)
+                known_paths.add(sitedircase)
+                pkg_resources.working_set.add_entry(sitedir)
+        sys.__egginsert = len(buildout_paths) # Support distribute.
+        original_paths = [
+            ...
+            ]
+        for path in original_paths:
+            if path == setuptools_path or path not in known_paths:
+                addsitedir(path, known_paths)
+        return known_paths
+    ...
+
+allowed-eggs-from-site-packages
+-------------------------------
+
+allowed-eggs-from-site-packages is described at the start of this document.
+It is a whitespace-delineated list of eggs that may be obtained from the
+filesystem.  It may use wildcards, and it defaults to "*", accepting all
+eggs.
+
+Here's a demonstration of how you would use
+allowed-eggs-from-sitepackages to allow no eggs to come from the
+filesystem, but still let you import other packages (like PIL) from the
+filesystem. (Note that the eggs-directory and the executable are only
+part of making this documentation testable, and not necessary to use
+this option.)
+
+Imagine that the system Python has demo installed.  If
+allowed-eggs-from-site-packages were its default value of '*', an
+installation would succeed, because it would be found in site-packages.
+However, this example would fail, because the site-packages version
+would not be allowed.
+
+.. ReST comment: unimportant for PyPI (comment ends at next "..")
+
+    >>> py_path, site_packages_path = make_py(initialization='''\
+    ... import os
+    ... os.environ['zc.buildout'] = 'foo bar baz shazam'
+    ... ''')
+    >>> from zc.buildout.tests import create_sample_sys_install
+    >>> create_sample_sys_install(site_packages_path)
+    >>> new_buildout = tmpdir('new_buildout')
+    >>> cd(new_buildout)
+    >>> mkdir(new_buildout, 'altdemo')
+    >>> mkdir(new_buildout, 'altdemo', 'demo')
+    >>> write(new_buildout, 'altdemo', 'demo', '__init__.py', '')
+    >>> write(new_buildout, 'altdemo', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ...
+    ... setup(name = "altdemo")
+    ... """)
+    >>> write(new_buildout, 'altdemo', 'README.txt', '')
+    >>> from zc.buildout.testing import install_develop, make_buildout
+    >>> make_buildout()
+    >>> install_develop(
+    ...     'zc.recipe.testrunner', os.path.join(new_buildout, 'develop-eggs'))
+    >>> install_develop(
+    ...     'zope.testrunner', os.path.join(new_buildout, 'develop-eggs'))
+    >>> install_develop(
+    ...     'zope.interface', os.path.join(new_buildout, 'develop-eggs'))
+    >>> install_develop(
+    ...     'zope.exceptions', os.path.join(new_buildout, 'develop-eggs'))
+    >>> install_develop(
+    ...     'zc.recipe.egg', os.path.join(new_buildout, 'develop-eggs'))
+    >>> install_develop(
+    ...     'z3c.recipe.scripts', os.path.join(new_buildout, 'develop-eggs'))
+
+..
+
+    >>> write(new_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = altdemo
+    ... parts = testdemo
+    ... eggs-directory = tmpeggs
+    ... executable = %(py_path)s
+    ...
+    ... [testdemo]
+    ... recipe = zc.recipe.testrunner
+    ... eggs = demo
+    ... include-site-packages = true
+    ... allowed-eggs-from-site-packages =
+    ... """ % dict(py_path=py_path))
+
+.. ReST comment: Hide the rest of the test from PyPI readers.
+
+   This will fail, because we cannot find demo anywhere (notice we are no
+   longer developing it in the buildout configuration above):
+
+    >>> print system(
+    ...     os.path.join(new_buildout, 'bin', 'buildout') + ' -q'),
+    While:
+      Installing testdemo.
+      Getting distribution for 'demo'.
+    Error: Couldn't find a distribution for 'demo'.
+
+   However, if we allow all eggs through, it works, because demo has been
+   installed in the "system Python".
+
+    >>> write(new_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = altdemo
+    ... parts = testdemo
+    ... eggs-directory = tmpeggs
+    ... executable = %(py_path)s
+    ... offline = true
+    ...
+    ... [testdemo]
+    ... recipe = zc.recipe.testrunner
+    ... eggs = demo
+    ... include-site-packages = true
+    ... """ % dict(py_path=py_path))
+
+    >>> print system(
+    ...     os.path.join(new_buildout, 'bin', 'buildout') + ' -q'),
+
+
+Like include-site-packages, it is also honored in the main buildout
+section if it is not overridden.
+
+.. ReST comment: hide from PyPI.  This will fail again, showing we have
+   blocked the eggs.
+
+    >>> write(new_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = testdemo
+    ... eggs-directory = tmpeggs
+    ... allowed-eggs-from-site-packages =
+    ... executable = %(py_path)s
+    ... offline = true
+    ...
+    ... [testdemo]
+    ... recipe = zc.recipe.testrunner
+    ... eggs = demo
+    ... include-site-packages = true
+    ... """ % dict(py_path=py_path))
+
+    >>> print system(
+    ...     os.path.join(new_buildout, 'bin', 'buildout') + ' -q'),
+    While:
+      Installing testdemo.
+      Getting distribution for 'demo'.
+    Error: Couldn't find a distribution for 'demo'.
+
+extends
+-------
+
+The extends option lets you inherit options from other sections.  This can
+keep you from repeating yourself.  For instance, in this example, the
+testdemo section gets all of its configuration from the source section, except
+it overrides the initialization.
+
+.. ReST comment: we'll move back to the sample_buildout.
+
+    >>> cd(sample_buildout)
+
+..
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... parts = testdemo
+    ... offline = true
+    ...
+    ... [source]
+    ... eggs = demo
+    ... extra-paths = /usr/local/zope/lib/python
+    ... defaults = ['--tests-pattern', '^f?tests$',
+    ...             '-v'
+    ...            ]
+    ... initialization = print 'Hello all you egg-laying pythons!'
+    ...
+    ... [testdemo]
+    ... recipe = zc.recipe.testrunner
+    ... extends = source
+    ... initialization = print 'Hello all you egg-laying pythons!'
+    ...                  print 'I thought pythons were live bearers?'
+    ... """)
+
+.. ReST comment: PyPI readers don't need to see the proof, but here it is.
+
+    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') + ' -q'),
+
+    >>> cat(sample_buildout, 'bin', 'testdemo')
+    #!/usr/local/bin/python2.4 -S
+    <BLANKLINE>
+    import sys
+    sys.path[0:0] = [
+        '/sample-buildout/parts/testdemo/site-packages',
+        ]
+    <BLANKLINE>
+    <BLANKLINE>
+    import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    import os
+    sys.argv[0] = os.path.abspath(sys.argv[0])
+    os.chdir('/sample-buildout/parts/testdemo/working-directory')
+    print 'Hello all you egg-laying pythons!'
+    print 'I thought pythons were live bearers?'
+    <BLANKLINE>
+    import zope.testrunner
+    <BLANKLINE>
+    if __name__ == '__main__':
+        zope.testrunner.run((['--tests-pattern', '^f?tests$',
+    '-v'
+    ]) + [
+            '--test-path', '/sample-buildout/demo',
+            ])
+
+exec-sitecustomize
+------------------
+
+This option lets you choose to execute the sitecustomize file of the Python
+you are using.  It is usually false.
+
+.. ReST comment: here's the demo.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... parts = testdemo
+    ... executable = %(py_path)s
+    ...
+    ... [testdemo]
+    ... recipe = zc.recipe.testrunner
+    ... eggs = demo
+    ... exec-sitecustomize = true
+    ... """ % dict(py_path=py_path))
+
+    >>> ignored = system(buildout),
+
+    >>> cat(sample_buildout, 'parts', 'testdemo', 'site-packages',
+    ...     'sitecustomize.py') # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+    <BLANKLINE>
+    # The following is from
+    # /executable_buildout/parts/py/sitecustomize.py
+    ...
+    import os
+    os.environ['zc.buildout'] = 'foo bar baz shazam'
+
+.. _`pertinent section of the zc.buildout documentation`:
+    http://pypi.python.org/pypi/zc.buildout/1.5.0#working-with-a-system-python
+
+
+

Modified: zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/__init__.py
===================================================================
--- zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/__init__.py	2010-08-28 02:18:57 UTC (rev 115977)
+++ zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/__init__.py	2010-08-28 02:44:24 UTC (rev 115978)
@@ -11,9 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""A few built-in recipes
-
-$Id$
+"""A recipe for a zope.testrunner-based testrunner.
 """
 
 import os
@@ -21,7 +19,7 @@
 import pkg_resources
 import sys
 import zc.buildout.easy_install
-import zc.recipe.egg
+import z3c.recipe.scripts.scripts
 
 class TestRunner:
 
@@ -29,18 +27,23 @@
         self.buildout = buildout
         self.name = name
         self.options = options
+        # We do this early so the "extends" functionality works before we get
+        # to the other options below.
+        self._delegated = z3c.recipe.scripts.scripts.Base(
+            buildout, name, options)
+
         options['script'] = os.path.join(buildout['buildout']['bin-directory'],
                                          options.get('script', self.name),
                                          )
         if not options.get('working-directory', ''):
             options['location'] = os.path.join(
-                buildout['buildout']['parts-directory'], name)
-        self.egg = zc.recipe.egg.Egg(buildout, name, options)
+                buildout['buildout']['parts-directory'], name,
+                'working-directory')
 
     def install(self):
         options = self.options
-        dest = []
-        eggs, ws = self.egg.working_set(('zope.testrunner', ))
+        generated = []
+        eggs, ws = self._delegated.working_set(('zope.testrunner', ))
 
         test_paths = [ws.find(pkg_resources.Requirement.parse(spec)).location
                       for spec in eggs]
@@ -49,19 +52,27 @@
         if defaults:
             defaults = '(%s) + ' % defaults
 
+        if not os.path.exists(options['parts-directory']):
+            os.mkdir(options['parts-directory'])
+            generated.append(options['parts-directory'])
+        site_py_dest = os.path.join(options['parts-directory'],
+                                    'site-packages')
+        if not os.path.exists(site_py_dest):
+            os.mkdir(site_py_dest)
+            generated.append(site_py_dest)
         wd = options.get('working-directory', '')
         if not wd:
             wd = options['location']
             if os.path.exists(wd):
                 assert os.path.isdir(wd)
             else:
-                os.mkdir(wd)
-            dest.append(wd)
+                os.mkdir(wd) # makedirs
+                generated.append(wd)
         wd = os.path.abspath(wd)
 
-        if self.egg._relative_paths:
-            wd = _relativize(self.egg._relative_paths, wd)
-            test_paths = [_relativize(self.egg._relative_paths, p)
+        if self._delegated._relative_paths:
+            wd = _relativize(self._delegated._relative_paths, wd)
+            test_paths = [_relativize(self._delegated._relative_paths, p)
                           for p in test_paths]
         else:
             wd = repr(wd)
@@ -79,21 +90,23 @@
         if initialization_section:
             initialization += initialization_section
 
-        dest.extend(zc.buildout.easy_install.scripts(
-            [(options['script'], 'zope.testrunner', 'run')],
-            ws, options['executable'],
-            self.buildout['buildout']['bin-directory'],
-            extra_paths=self.egg.extra_paths,
-            arguments = defaults + (
+        generated.extend(zc.buildout.easy_install.sitepackage_safe_scripts(
+            self.buildout['buildout']['bin-directory'], ws,
+            options['executable'], site_py_dest,
+            reqs=[(options['script'], 'zope.testrunner', 'run')],
+            extra_paths=self._delegated.extra_paths,
+            include_site_packages=self._delegated.include_site_packages,
+            exec_sitecustomize=self._delegated.exec_sitecustomize,
+            relative_paths=self._delegated._relative_paths,
+            script_arguments=defaults + (
                     '[\n'+
                     ''.join(("        '--test-path', %s,\n" % p)
                             for p in test_paths)
                     +'        ]'),
-            initialization = initialization,
-            relative_paths = self.egg._relative_paths,
+            script_initialization=initialization,
             ))
 
-        return dest
+        return generated
 
     update = install
 

Modified: zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/tests.py
===================================================================
--- zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/tests.py	2010-08-28 02:18:57 UTC (rev 115977)
+++ zc.recipe.testrunner/trunk/src/zc/recipe/testrunner/tests.py	2010-08-28 02:44:24 UTC (rev 115978)
@@ -25,6 +25,7 @@
     zc.buildout.testing.buildoutSetUp(test)
     zc.buildout.testing.install_develop('zc.recipe.testrunner', test)
     zc.buildout.testing.install_develop('zc.recipe.egg', test)
+    zc.buildout.testing.install_develop('z3c.recipe.scripts', test)
     zc.buildout.testing.install('zope.testing', test)
     zc.buildout.testing.install('zope.testrunner', test)
     zc.buildout.testing.install('zope.interface', test)



More information about the checkins mailing list