[Checkins] SVN: zc.buildout/branches/python-3/ checkpoint

Jim Fulton jim at zope.com
Wed Mar 16 09:51:30 EDT 2011


Log message for revision 120975:
  checkpoint

Changed:
  U   zc.buildout/branches/python-3/bootstrap/bootstrap.py
  U   zc.buildout/branches/python-3/buildout.cfg
  U   zc.buildout/branches/python-3/dev.py
  U   zc.buildout/branches/python-3/src/zc/buildout/__init__.py
  U   zc.buildout/branches/python-3/src/zc/buildout/allowhosts.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/bootstrap.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/buildout.py
  U   zc.buildout/branches/python-3/src/zc/buildout/buildout.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/debugging.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/dependencylinks.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/download.py
  U   zc.buildout/branches/python-3/src/zc/buildout/download.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/downloadcache.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/easy_install.py
  U   zc.buildout/branches/python-3/src/zc/buildout/easy_install.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/extends-cache.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/repeatable.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/rmtree.py
  U   zc.buildout/branches/python-3/src/zc/buildout/runsetup.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/setup.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/testing.py
  U   zc.buildout/branches/python-3/src/zc/buildout/testrecipes.py
  U   zc.buildout/branches/python-3/src/zc/buildout/tests.py
  U   zc.buildout/branches/python-3/src/zc/buildout/testselectingpython.py
  U   zc.buildout/branches/python-3/src/zc/buildout/update.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/virtualenv.txt
  U   zc.buildout/branches/python-3/src/zc/buildout/windows.txt
  U   zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py
  U   zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py
  U   zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/custom.py
  U   zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/egg.py

-=-
Modified: zc.buildout/branches/python-3/bootstrap/bootstrap.py
===================================================================
--- zc.buildout/branches/python-3/bootstrap/bootstrap.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/bootstrap/bootstrap.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -18,7 +18,9 @@
 use the -c option to specify an alternate configuration file.
 """
 
-import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+import os, shutil, sys, tempfile, textwrap
+import urllib.request, urllib.parse, urllib.error, urllib.request
+import urllib.error, urllib.parse, subprocess
 from optparse import OptionParser
 
 if sys.platform == 'win32':
@@ -32,13 +34,13 @@
 
 # See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
 stdout, stderr = subprocess.Popen(
-    [sys.executable, '-Sc',
+    [sys.executable, '-S', '-c',
      'try:\n'
-     '    import ConfigParser\n'
+     '    import pickle\n'
      'except ImportError:\n'
-     '    print 1\n'
+     '    print(1)\n'
      'else:\n'
-     '    print 0\n'],
+     '    print(0)\n'],
     stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
 has_broken_dash_S = bool(int(stdout.strip()))
 
@@ -50,8 +52,9 @@
     # We will restart with python -S.
     args = sys.argv[:]
     args[0:0] = [sys.executable, '-S']
-    args = map(quote, args)
+    args = list(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
@@ -59,7 +62,7 @@
 clean_path = sys.path[:]
 import site
 sys.path[:] = clean_path
-for k, v in sys.modules.items():
+for k, v in list(sys.modules.items()):
     if k in ('setuptools', 'pkg_resources') or (
         hasattr(v, '__path__') and
         len(v.__path__)==1 and
@@ -77,7 +80,7 @@
     if value:
         if '://' not in value: # It doesn't smell like a URL.
             value = 'file://%s' % (
-                urllib.pathname2url(
+                urllib.request.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.
@@ -103,7 +106,8 @@
 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,
+                   action="store_true", dest="use_distribute",
+                   default= sys.version_info[0] >= 3,
                    help="Use Distribute rather than Setuptools.")
 parser.add_option("--setup-source", action="callback", dest="setup_source",
                   callback=normalize_to_url, nargs=1, type="string",
@@ -160,10 +164,10 @@
     if not hasattr(pkg_resources, '_distribute'):
         raise ImportError
 except ImportError:
-    ez_code = urllib2.urlopen(
+    ez_code = urllib.request.urlopen(
         options.setup_source).read().replace('\r\n', '\n')
     ez = {}
-    exec ez_code in ez
+    exec(ez_code, ez)
     setup_args = dict(to_dir=eggs_dir, download_delay=0)
     if options.download_base:
         setup_args['download_base'] = options.download_base
@@ -247,9 +251,9 @@
 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.")
+    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)

Modified: zc.buildout/branches/python-3/buildout.cfg
===================================================================
--- zc.buildout/branches/python-3/buildout.cfg	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/buildout.cfg	2011-03-16 13:51:30 UTC (rev 120975)
@@ -1,9 +1,9 @@
 [buildout]
-develop = zc.recipe.egg_ z3c.recipe.scripts_ .
-parts = test oltest py
+develop = zc.recipe.egg_ z3c.recipe.scripts_ . testing
+parts = py test oltest
 
 [py]
-recipe = z3c.recipe.scripts
+recipe = zc.recipe.egg
 eggs = zc.buildout
        zope.testing
 interpreter = py

Modified: zc.buildout/branches/python-3/dev.py
===================================================================
--- zc.buildout/branches/python-3/dev.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/dev.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -15,11 +15,10 @@
 
 This is different from a normal bootstrapping process because the
 buildout egg itself is installed as a develop egg.
-
-$Id$
 """
 
-import os, shutil, sys, subprocess, urllib2, subprocess
+import os, shutil, sys, subprocess
+import urllib.request, urllib.error, urllib.parse
 from optparse import OptionParser
 
 if sys.platform == 'win32':
@@ -33,7 +32,7 @@
 
 # Detect https://bugs.launchpad.net/virtualenv/+bug/572545 .
 has_broken_dash_S = subprocess.call(
-    [sys.executable, '-Sc', 'import ConfigParser'])
+    [sys.executable, '-S', '-c', 'import pickle'])
 
 # 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
@@ -43,7 +42,7 @@
     # We will restart with python -S.
     args = sys.argv[:]
     args[0:0] = [sys.executable, '-S']
-    args = map(quote, args)
+    args = list(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
@@ -52,7 +51,7 @@
 clean_path = sys.path[:]
 import site
 sys.path[:] = clean_path
-for k, v in sys.modules.items():
+for k, v in list(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'))):
@@ -75,11 +74,11 @@
 
 parser = OptionParser(usage=usage)
 parser.add_option("-d", "--distribute",
-                   action="store_true", dest="use_distribute", default=False,
-                   help="Use Distribute rather than Setuptools.")
+                  action="store_true", dest="use_distribute",
+                  default=sys.version_info[0] >= 3,
+                  help="Use Distribute rather than Setuptools.")
 
 options, args = parser.parse_args()
-
 if args:
     parser.error('This script accepts no arguments other than its options.')
 
@@ -102,9 +101,10 @@
         raise ImportError
     import setuptools # A flag.  Sometimes pkg_resources is installed alone.
 except ImportError:
-    ez_code = urllib2.urlopen(setup_source).read().replace('\r\n', '\n')
+    ez_code = urllib.request.urlopen(setup_source).read().replace(
+        '\r\n'.encode(), '\n'.encode())
     ez = {}
-    exec ez_code in ez
+    exec(ez_code, ez)
     setup_args = dict(to_dir='eggs', download_delay=0)
     if options.use_distribute:
         setup_args['no_fake'] = True

Modified: zc.buildout/branches/python-3/src/zc/buildout/__init__.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/__init__.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/__init__.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -12,13 +12,8 @@
 #
 ##############################################################################
 """Buildout package
-
-$Id$
 """
 
 class UserError(Exception):
     """Errors made by a user 
     """
-
-    def __str__(self):
-        return " ".join(map(str, self))

Modified: zc.buildout/branches/python-3/src/zc/buildout/allowhosts.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/allowhosts.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/allowhosts.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -55,7 +55,7 @@
 
 Now we can run the buildout and make sure all attempts to dist.plone.org fails::
 
-    >>> print system(buildout) # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/allowdemo'
     ...
     Link to http://dist.plone.org ***BLOCKED*** by --allow-hosts
@@ -64,7 +64,6 @@
       Installing eggs.
       Getting distribution for 'kss.core'.
     Error: Couldn't find a distribution for 'kss.core'.
-    <BLANKLINE>
 
 That's what we wanted : this will prevent any attempt to access
 unwanted domains. For instance, some packages are listing in their
@@ -88,7 +87,7 @@
 
 Now we can run the buildout and make sure all attempts to dist.plone.org fails::
 
-    >>> print system(buildout) # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/allowdemo'
     ...
     Link to http://dist.plone.org ***BLOCKED*** by --allow-hosts
@@ -97,7 +96,6 @@
       Installing eggs.
       Getting distribution for 'kss.core'.
     Error: Couldn't find a distribution for 'kss.core'.
-    <BLANKLINE>
 
 Test for issues
 ---------------
@@ -115,12 +113,11 @@
     ... eggs=zc.buildout
     ... interpreter=python
     ... ''')
-    >>> print system(buildout)
+    >>> run(buildout)
     Unused options for buildout: 'foo'.
     Installing python.
     Generated script '/sample-buildout/bin/buildout'.
     Generated interpreter '/sample-buildout/bin/python'.
-    <BLANKLINE>
 
 The bug 239212 above would have got us an *AttributeError* on *buildout._allow_hosts*.
 This was fixed in this changeset:

Modified: zc.buildout/branches/python-3/src/zc/buildout/bootstrap.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/bootstrap.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/bootstrap.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -20,9 +20,9 @@
     ... parts =
     ... ''')
     >>> write('bootstrap.py', open(bootstrap_py).read())
-    >>> print 'X'; print system(
+    >>> print('X'); run(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py'); print 'X' # doctest: +ELLIPSIS
+    ...     'bootstrap.py'); print('X') # doctest: +ELLIPSIS
     X...
     Creating directory '/sample/bin'.
     Creating directory '/sample/parts'.
@@ -43,7 +43,7 @@
     >>> ls(sample_buildout, 'bin')
     -  buildout
 
-    >>> print 'X'; ls(sample_buildout, 'eggs') # doctest: +ELLIPSIS
+    >>> print('X'); ls(sample_buildout, 'eggs') # doctest: +ELLIPSIS
     X...
     d  zc.buildout-...egg
 
@@ -53,7 +53,7 @@
     >>> buildout_script = join(sample_buildout, 'bin', 'buildout')
     >>> if sys.platform.startswith('win'):
     ...     buildout_script += '-script.py'
-    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_script).read()) # doctest: +ELLIPSIS
     #...
     <BLANKLINE>
     import sys
@@ -82,7 +82,7 @@
 
     >>> buildout_site_py = join(
     ...     sample_buildout, 'parts', 'buildout', 'site.py')
-    >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_site_py).read()) # doctest: +ELLIPSIS
     "...
         buildout_paths = [
             '/sample/eggs/setuptools-...egg',
@@ -102,7 +102,7 @@
     >>> ignored = system(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
     ...     'bootstrap.py --accept-buildout-test-releases')
-    >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_site_py).read()) # doctest: +ELLIPSIS
     "...
         buildout_paths = [
             '/sample/eggs/setuptools-...egg',
@@ -115,7 +115,7 @@
 The buildout script remembers the decision to accept early releases, and
 alerts the user.
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     ... # doctest: +NORMALIZE_WHITESPACE
     NOTE: Accepting early releases of build system packages.  Rerun bootstrap
           without --accept-buildout-test-releases (-t) to return to default
@@ -123,11 +123,11 @@
 
 This is accomplished within the script itself.
 
-    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_script).read()) # doctest: +ELLIPSIS
     #...
     sys.argv.insert(1, 'buildout:accept-buildout-test-releases=true')
-    print ('NOTE: Accepting early releases of build system packages.  Rerun '
-           'bootstrap without --accept-buildout-test-releases (-t) to return to '
+    print('NOTE: Accepting early releases of build system packages.  Rerun '
+          'bootstrap without --accept-buildout-test-releases (-t) to return to '
            'default behavior.')
     ...
 
@@ -137,7 +137,7 @@
     >>> ignored = system(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
     ...     'bootstrap.py')
-    >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_site_py).read()) # doctest: +ELLIPSIS
     "...
         buildout_paths = [
             '/sample/eggs/setuptools-...egg',
@@ -153,9 +153,9 @@
 
 Let's try with an unknown version::
 
-    >>> print 'XX'; print system(
+    >>> print('XX'); run(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py --version UNKNOWN'); print 'X' # doctest: +ELLIPSIS
+    ...     'bootstrap.py --version UNKNOWN'); print('X') # doctest: +ELLIPSIS
     ...
     X...
     No local packages or download links found for zc.buildout==UNKNOWN...
@@ -163,9 +163,9 @@
 
 Now let's try with `1.1.2`, which happens to exist::
 
-    >>> print 'X'; print system(
+    >>> print('X'); run(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py --version 1.1.2'); print 'X'
+    ...     'bootstrap.py --version 1.1.2'); print('X')
     ...
     X
     Generated script '/sample/bin/buildout'.
@@ -175,7 +175,7 @@
 Versions older than 1.5.0 put their egg dependencies in the ``buildout`` script.
 Let's make sure it was generated as we expect::
 
-    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_script).read()) # doctest: +ELLIPSIS
     #...
     <BLANKLINE>
     import sys
@@ -192,9 +192,9 @@
 
 Let's try with `1.2.1`::
 
-    >>> print 'X'; print system(
+    >>> print('X'); run(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py --version 1.2.1'); print 'X' # doctest: +ELLIPSIS
+    ...     'bootstrap.py --version 1.2.1'); print('X') # doctest: +ELLIPSIS
     ...
     X
     Generated script '/sample/bin/buildout'.
@@ -203,7 +203,7 @@
 
 Let's make sure the generated ``buildout`` script uses it::
 
-    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_script).read()) # doctest: +ELLIPSIS
     #...
     <BLANKLINE>
     import sys
@@ -221,9 +221,9 @@
 ``zc.buildout`` now can also run with `Distribute` with the `--distribute`
 option::
 
-    >>> print 'X'; print system(
+    >>> print('X'); run(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py --distribute'); print 'X' # doctest: +ELLIPSIS
+    ...     'bootstrap.py --distribute'); print('X') # doctest: +ELLIPSIS
     ...
     X
     ...
@@ -231,7 +231,7 @@
     X
 
 Let's make sure the generated ``site.py`` uses it::
-    >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_site_py).read()) # doctest: +ELLIPSIS
     "...
         buildout_paths = [
             '/sample/eggs/distribute-...egg',
@@ -241,9 +241,9 @@
 
 Make sure both options can be used together::
 
-    >>> print 'X'; print system(
+    >>> print('X'); run(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py --distribute --version 1.2.1'); print 'X'
+    ...     'bootstrap.py --distribute --version 1.2.1'); print('X')
     ... # doctest: +ELLIPSIS
     ...
     X
@@ -254,7 +254,7 @@
 Let's make sure the old-style generated ``buildout`` script uses
 ``Distribute`` *and* ``zc.buildout-1.2.1``::
 
-    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_script).read()) # doctest: +ELLIPSIS
     #...
     <BLANKLINE>
     import sys
@@ -275,9 +275,10 @@
     >>> f = open(conf_file, 'w')
     >>> f.write('[buildout]\nparts=\n\n')
     >>> f.close()
-    >>> print 'X'; print system(
+    >>> print('X'); run(
     ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py -c %s --distribute' % conf_file); print 'X' # doctest: +ELLIPSIS
+    ...     'bootstrap.py -c %s --distribute' % conf_file); print('X')
+    ...     # doctest: +ELLIPSIS
     ...
     X
     ...
@@ -294,32 +295,27 @@
     ...     pprint.pprint(kwargs, width=40)
     ...     sys.exit()
     ... ''')
-    >>> print system(
-    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+    >>> run(zc.buildout.easy_install._safe_arg(sys.executable)+' '+
     ...     'bootstrap.py --setup-source=./ez_setup.py')
     ... # doctest: +ELLIPSIS
     {'download_delay': 0,
      'to_dir': '...'}
-    <BLANKLINE>
 
 You can also pass a download-cache, and a place in which eggs should be stored
 (they are normally stored in a temporary directory).
 
-    >>> print system(
-    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+    >>> run(zc.buildout.easy_install._safe_arg(sys.executable)+' '+
     ...     'bootstrap.py --setup-source=./ez_setup.py '+
     ...     '--download-base=./download-cache --eggs=eggs')
     ... # doctest: +ELLIPSIS
     {'download_base': '/sample/download-cache/',
      'download_delay': 0,
      'to_dir': '/sample/eggs'}
-    <BLANKLINE>
 
 Here's the entire help text.
 
-    >>> print system(
-    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py --help'),
+    >>> run(zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+    ...     'bootstrap.py --help')
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     Usage: [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
     <BLANKLINE>

Modified: zc.buildout/branches/python-3/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/buildout.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/buildout.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -14,14 +14,23 @@
 """Buildout main script
 """
 
-from rmtree import rmtree
+from .rmtree import rmtree
 try:
     from hashlib import md5
 except ImportError:
     # Python 2.4 and older
     from md5 import md5
 
-import ConfigParser
+try:
+    from UserDict import DictMixin
+except ImportError:
+    import collections
+    class DictMixin(collections.MutableMapping):
+        def __iter__(self):
+            return iter(self.keys())
+        def __len__(self):
+            return len(self.keys())
+
 import copy
 import distutils.errors
 import glob
@@ -33,7 +42,6 @@
 import shutil
 import sys
 import tempfile
-import UserDict
 import warnings
 import subprocess
 import zc.buildout
@@ -43,8 +51,10 @@
 
 realpath = zc.buildout.easy_install.realpath
 
+setuptools_key = zc.buildout.easy_install.setuptools_key
+
 pkg_resources_loc = pkg_resources.working_set.find(
-    pkg_resources.Requirement.parse('setuptools')).location
+    pkg_resources.Requirement.parse(setuptools_key)).location
 
 _isurl = re.compile('([a-zA-Z0-9+.-]+)://').match
 
@@ -57,6 +67,9 @@
     """A required option was missing.
     """
 
+    def __str__(self):
+        return zc.buildout.UserError.__str__(self)
+
 class MissingSection(zc.buildout.UserError, KeyError):
     """A required section is missing.
     """
@@ -76,20 +89,20 @@
     return data
 
 def _print_annotate(data):
-    sections = data.keys()
+    sections = list(data.keys())
     sections.sort()
-    print
-    print "Annotated sections"
-    print "="*len("Annotated sections")
+    print()
+    print("Annotated sections")
+    print("="*len("Annotated sections"))
     for section in sections:
-        print
-        print '[%s]' % section
-        keys = data[section].keys()
+        print()
+        print('[%s]' % section)
+        keys = list(data[section].keys())
         keys.sort()
         for key in keys:
             value, notes = data[section][key]
             keyvalue = "%s= %s" % (key, value)
-            print keyvalue
+            print(keyvalue)
             line = '   '
             for note in notes.split():
                 if note == '[+]':
@@ -97,9 +110,9 @@
                 elif note == '[-]':
                     line = '-= '
                 else:
-                    print line, note
+                    print(line, note)
                     line = '   '
-    print
+    print()
 
 
 def _unannotate_section(section):
@@ -141,7 +154,7 @@
     }, 'DEFAULT_VALUE')
 
 
-class Buildout(UserDict.DictMixin):
+class Buildout(DictMixin):
 
     def __init__(self, config_file, cloptions,
                  user_defaults=True, windows_restart=False, command=None):
@@ -159,7 +172,7 @@
             base = os.path.dirname(config_file)
             if not os.path.exists(config_file):
                 if command == 'init':
-                    print 'Creating %r.' % config_file
+                    print('Creating %r.' % config_file)
                     open(config_file, 'w').write('[buildout]\nparts = \n')
                 elif command == 'setup':
                     # Sigh. This model of a buildout instance
@@ -191,7 +204,8 @@
                                        '.buildout', 'default.cfg')
             if os.path.exists(user_config):
                 _update(data, _open(os.path.dirname(user_config), user_config,
-                                    [], data['buildout'].copy(), override, set()))
+                                    [], data['buildout'].copy(), override,
+                                    set()))
 
         # load configuration files
         if config_file:
@@ -344,7 +358,7 @@
 
         # Get a base working set for our distributions that corresponds to the
         # stated desires in the configuration.
-        distributions = ['setuptools', 'zc.buildout']
+        distributions = [setuptools_key, 'zc.buildout']
         if options.get('offline') == 'true':
             ws = zc.buildout.easy_install.working_set(
                 distributions, options['executable'],
@@ -366,7 +380,7 @@
 
         # Now copy buildout and setuptools eggs, and record destination eggs:
         entries = []
-        for name in 'setuptools', 'zc.buildout':
+        for name in setuptools_key, 'zc.buildout':
             r = pkg_resources.Requirement.parse(name)
             dist = ws.find(r)
             if dist.precedence == pkg_resources.DEVELOP_DIST:
@@ -470,13 +484,12 @@
         if self._log_level < logging.DEBUG:
             sections = list(self)
             sections.sort()
-            print
-            print 'Configuration data:'
+            print()
+            print('Configuration data:')
             for section in self._data:
                 _save_options(section, self[section], sys.stdout)
-            print
+            print()
 
-
         # compute new part recipe signatures
         self._compute_part_signatures(install_parts)
 
@@ -621,7 +634,7 @@
         installed = self['buildout']['installed']
         f = open(installed, 'a')
         f.write('\n[buildout]\n')
-        for option, value in buildout_options.items():
+        for option, value in list(buildout_options.items()):
             _save_option(option, value, f)
         f.close()
 
@@ -637,7 +650,7 @@
                 recipe, 'zc.buildout.uninstall', entry, self)
             self._logger.info('Running uninstall recipe.')
             uninstaller(part, installed_part_options[part])
-        except (ImportError, pkg_resources.DistributionNotFound), v:
+        except (ImportError, pkg_resources.DistributionNotFound) as v:
             pass
 
         # remove created files and directories
@@ -727,17 +740,16 @@
     def _read_installed_part_options(self):
         old = self['buildout']['installed']
         if old and os.path.isfile(old):
-            parser = ConfigParser.RawConfigParser()
-            parser.optionxform = lambda s: s
-            parser.read(old)
+            fp = open(old)
+            sections = _read(fp, old)
+            fp.close()
             result = {}
-            for section in parser.sections():
-                options = {}
-                for option, value in parser.items(section):
+            for section, options in sections.items():
+                for option, value in options.items():
                     if '%(' in value:
                         for k, v in _spacey_defaults:
                             value = value.replace(k, v)
-                    options[option] = value
+                        options[option] = value
                 result[section] = Options(self, section, options)
 
             return result, True
@@ -777,7 +789,7 @@
         installed = recipe_class(self, part, options).install()
         if installed is None:
             installed = []
-        elif isinstance(installed, basestring):
+        elif isinstance(installed, str):
             installed = [installed]
         base = self._buildout_path('')
         installed = [d.startswith(base) and d[len(base):] or d
@@ -792,7 +804,7 @@
         f = open(installed, 'w')
         _save_options('buildout', installed_options['buildout'], f)
         for part in installed_options['buildout']['parts'].split():
-            print >>f
+            print(file=f)
             _save_options(part, installed_options[part], f)
         f.close()
 
@@ -845,10 +857,7 @@
         options = self['buildout']
 
         specs = ['zc.buildout']
-        if zc.buildout.easy_install.is_distribute:
-            specs.append('distribute')
-        else:
-            specs.append('setuptools')
+        specs.append(setuptools_key)
         ws = zc.buildout.easy_install.install(
             [
             (spec + ' ' + options.get(spec+'-version', '')).strip()
@@ -863,7 +872,7 @@
             )
 
         upgraded = []
-        for project in 'zc.buildout', 'setuptools':
+        for project in 'zc.buildout', setuptools_key:
             req = pkg_resources.Requirement.parse(project)
             project_location = pkg_resources.working_set.find(req).location
             if ws.find(req).location != project_location:
@@ -889,7 +898,7 @@
             return
 
         if sys.platform == 'win32' and not self.__windows_restart:
-            args = map(zc.buildout.easy_install._safe_arg, sys.argv)
+            args = list(map(zc.buildout.easy_install._safe_arg, sys.argv))
             args.insert(1, '-W')
             if not __debug__:
                 args.insert(0, '-O')
@@ -939,7 +948,7 @@
             )
 
         # Restart
-        args = map(zc.buildout.easy_install._safe_arg, sys.argv)
+        args = list(map(zc.buildout.easy_install._safe_arg, sys.argv))
         if not __debug__:
             args.insert(0, '-O')
         args.insert(0, zc.buildout.easy_install._safe_arg(sys.executable))
@@ -1005,12 +1014,12 @@
         fd, tsetup = tempfile.mkstemp()
         exe = zc.buildout.easy_install._safe_arg(sys.executable)
         try:
-            os.write(fd, zc.buildout.easy_install.runsetup_template % dict(
+            os.write(fd, (zc.buildout.easy_install.runsetup_template % dict(
                 setuptools=pkg_resources_loc,
                 setupdir=os.path.dirname(setup),
                 setup=setup,
                 __file__ = setup,
-                ))
+                )).encode())
             if is_jython:
                 arg_list = list()
 
@@ -1056,11 +1065,13 @@
         raise NotImplementedError('__delitem__')
 
     def keys(self):
-        return self._raw.keys()
+        return list(self._raw.keys())
 
     def __iter__(self):
         return iter(self._raw)
 
+    def __len__(self):
+        return len(self._raw)
 
 def _install_and_load(spec, group, entry, buildout):
     __doing__ = 'Loading recipe %r.', spec
@@ -1093,7 +1104,7 @@
         return pkg_resources.load_entry_point(
             req.project_name, group, entry)
 
-    except Exception, v:
+    except Exception as v:
         buildout._logger.log(
             1,
             "Could't load %s entry point %s\nfrom %s:\n%s.",
@@ -1101,7 +1112,7 @@
         raise
 
 
-class Options(UserDict.DictMixin):
+class Options(DictMixin):
 
     def __init__(self, buildout, section, data):
         self.buildout = buildout
@@ -1118,7 +1129,7 @@
             self._raw = self._do_extend_raw(name, self._raw, [])
 
         # force substitutions
-        for k, v in self._raw.items():
+        for k, v in list(self._raw.items()):
             if '${' in v:
                 self._dosub(k, v)
 
@@ -1269,7 +1280,7 @@
         elif key in self._data:
             del self._data[key]
         else:
-            raise KeyError, key
+            raise KeyError(key)
 
     def keys(self):
         raw = self._raw
@@ -1371,11 +1382,11 @@
         value = '%(__buildout_space_n__)s' + value[2:]
     if value.endswith('\n\t'):
         value = value[:-2] + '%(__buildout_space_n__)s'
-    print >>f, option, '=', value
+    print(option, '=', value, file=f)
 
 def _save_options(section, options, f):
-    print >>f, '[%s]' % section
-    items = options.items()
+    print('[%s]' % section, file=f)
+    items = list(options.items())
     items.sort()
     for option, value in items:
         _save_option(option, value, f)
@@ -1421,25 +1432,17 @@
     root_config_file = not seen
     seen.append(filename)
 
-    result = {}
-
-    parser = ConfigParser.RawConfigParser()
-    parser.optionxform = lambda s: s
-    parser.readfp(fp)
+    result = _read(fp, filename)
+    fp.close()
     if is_temp:
-        fp.close()
         os.remove(path)
 
-    extends = None
-    for section in parser.sections():
-        options = dict(parser.items(section))
-        if section == 'buildout':
-            extends = options.pop('extends', extends)
-            if 'extended-by' in options:
-                raise zc.buildout.UserError(
-                    'No-longer supported "extended-by" option found in %s.' %
-                    filename)
-        result[section] = options
+    options = result.get('buildout', {})
+    extends = options.pop('extends', None)
+    if 'extended-by' in options:
+        raise zc.buildout.UserError(
+            'No-longer supported "extended-by" option found in %s.' %
+            filename)
 
     result = _annotate(result, filename)
 
@@ -1472,11 +1475,11 @@
                         if (not (f.endswith('pyc') or f.endswith('pyo'))
                             and os.path.exists(os.path.join(dirpath, f)))
                         ]
-        hash.update(' '.join(dirnames))
-        hash.update(' '.join(filenames))
+        hash.update(' '.join(dirnames).encode())
+        hash.update(' '.join(filenames).encode())
         for name in filenames:
-            hash.update(open(os.path.join(dirpath, name)).read())
-    _dir_hashes[dir] = dir_hash = hash.digest().encode('base64').strip()
+            hash.update(open(os.path.join(dirpath, name)).read().encode())
+    _dir_hashes[dir] = dir_hash = hash.hexdigest()
     return dir_hash
 
 def _dists_sig(dists):
@@ -1491,7 +1494,7 @@
 
 def _update_section(s1, s2):
     s2 = s2.copy() # avoid mutating the second argument, which is unexpected
-    for k, v in s2.items():
+    for k, v in list(s2.items()):
         v2, note2 = v
         if k.endswith('+'):
             key = k.rstrip(' +')
@@ -1565,9 +1568,9 @@
 
 _early_release_initialization_code = """\
 sys.argv.insert(1, 'buildout:accept-buildout-test-releases=true')
-print ('NOTE: Accepting early releases of build system packages.  Rerun '
-       'bootstrap without --accept-buildout-test-releases (-t) to return to '
-       'default behavior.')
+print('NOTE: Accepting early releases of build system packages.  Rerun '
+      'bootstrap without --accept-buildout-test-releases (-t) to return to '
+      'default behavior.')
 """
 
 _usage = """\
@@ -1690,7 +1693,7 @@
 
 """
 def _help():
-    print _usage
+    print(_usage)
     sys.exit(0)
 
 def main(args=None):
@@ -1754,7 +1757,7 @@
                         _error("No timeout value must be numeric", orig_op)
 
                     import socket
-                    print 'Setting socket time out to %d seconds' % timeout
+                    print('Setting socket time out to %d seconds' % timeout)
                     socket.setdefaulttimeout(timeout)
 
             elif op:
@@ -1801,7 +1804,7 @@
             buildout = Buildout(config_file, options,
                                 user_defaults, windows_restart, command)
             getattr(buildout, command)(args)
-        except Exception, v:
+        except Exception as v:
             _doing()
             exc_info = sys.exc_info()
             import pdb, traceback
@@ -1811,7 +1814,7 @@
                 pdb.post_mortem(exc_info[2])
             else:
                 if isinstance(v, (zc.buildout.UserError,
-                                  distutils.errors.DistutilsError,
+                                  distutils.errors.DistutilsError
                                   )
                               ):
                     _error(str(v))
@@ -1829,3 +1832,153 @@
         result = list(iterable);
         result.reverse()
         return result
+
+# The following copied from Python 2 config parser because:
+# - The py3 configparser isn't backward compatible
+# - Both strip option values in undesireable ways
+# - dict of dicts is a much simpler api
+
+
+class Error(Exception):
+    """Base class for ConfigParser exceptions."""
+
+    def _get_message(self):
+        """Getter for 'message'; needed only to override deprecation in
+        BaseException."""
+        return self.__message
+
+    def _set_message(self, value):
+        """Setter for 'message'; needed only to override deprecation in
+        BaseException."""
+        self.__message = value
+
+    # BaseException.message has been deprecated since Python 2.6.  To prevent
+    # DeprecationWarning from popping up over this pre-existing attribute, use
+    # a new property that takes lookup precedence.
+    message = property(_get_message, _set_message)
+
+    def __init__(self, msg=''):
+        self.message = msg
+        Exception.__init__(self, msg)
+
+    def __repr__(self):
+        return self.message
+
+class ParsingError(Error):
+    """Raised when a configuration file does not follow legal syntax."""
+
+    def __init__(self, filename):
+        Error.__init__(self, 'File contains parsing errors: %s' % filename)
+        self.filename = filename
+        self.errors = []
+
+    def append(self, lineno, line):
+        self.errors.append((lineno, line))
+        self.message += '\n\t[line %2d]: %s' % (lineno, line)
+
+class MissingSectionHeaderError(ParsingError):
+    """Raised when a key-value pair is found before any section header."""
+
+    def __init__(self, filename, lineno, line):
+        Error.__init__(
+            self,
+            'File contains no section headers.\nfile: %s, line: %d\n%r' %
+            (filename, lineno, line))
+        self.filename = filename
+        self.lineno = lineno
+        self.line = line
+
+SECTCRE = re.compile(
+    r'\['                                 # [
+    r'(?P<header>[^]]+)'                  # very permissive!
+    r'\]'                                 # ]
+    )
+OPTCRE = re.compile(
+    r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
+    r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab,
+                                          # followed by separator
+                                          # (either : or =), followed
+                                          # by any # space/tab
+    r'(?P<value>.*)$'                     # everything up to eol
+    )
+
+def _read(fp, fpname):
+    """Parse a sectioned setup file.
+
+    The sections in setup file contains a title line at the top,
+    indicated by a name in square brackets (`[]'), plus key/value
+    options lines, indicated by `name: value' format lines.
+    Continuations are represented by an embedded newline then
+    leading whitespace.  Blank lines, lines beginning with a '#',
+    and just about everything else are ignored.
+    """
+    _sections = {}
+    cursect = None                            # None, or a dictionary
+    optname = None
+    lineno = 0
+    e = None                                  # None, or an exception
+    while True:
+        line = fp.readline()
+        if not line:
+            break
+        lineno = lineno + 1
+        # comment or blank line?
+        if line.strip() == '' or line[0] in '#;':
+            continue
+        if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
+            # no leading whitespace
+            continue
+        # continuation line?
+        if line[0].isspace() and cursect is not None and optname:
+            value = line.strip()
+            if value:
+                cursect[optname] = "%s\n%s" % (cursect[optname], value)
+        # a section header or option header?
+        else:
+            # is it a section header?
+            mo = SECTCRE.match(line)
+            if mo:
+                sectname = mo.group('header')
+                if sectname in _sections:
+                    cursect = _sections[sectname]
+                else:
+                    cursect = {}
+                    _sections[sectname] = cursect
+                # So sections can't start with a continuation line
+                optname = None
+            # no section header in the file?
+            elif cursect is None:
+                raise MissingSectionHeaderError(fpname, lineno, line)
+            # an option line?
+            else:
+                mo = OPTCRE.match(line)
+                if mo:
+                    optname, vi, optval = mo.group('option', 'vi', 'value')
+                    # This check is fine because the OPTCRE cannot
+                    # match if it would set optval to None
+                    if optval is not None:
+                        if vi in ('=', ':') and ';' in optval:
+                            # ';' is a comment delimiter only if it follows
+                            # a spacing character
+                            pos = optval.find(';')
+                            if pos != -1 and optval[pos-1].isspace():
+                                optval = optval[:pos]
+                        optval = optval.strip()
+                    # allow empty values
+                    if optval == '""':
+                        optval = ''
+                    optname = optname.rstrip()
+                    cursect[optname] = optval
+                else:
+                    # a non-fatal parsing error occurred.  set up the
+                    # exception but keep going. the exception will be
+                    # raised at the end of the file and will contain a
+                    # list of all bogus lines
+                    if not e:
+                        e = ParsingError(fpname)
+                    e.append(lineno, repr(line))
+    # if any parsing errors occurred, raise an exception
+    if e:
+        raise e
+
+    return _sections

Modified: zc.buildout/branches/python-3/src/zc/buildout/buildout.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/buildout.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/buildout.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -289,7 +289,7 @@
     >>> import os
     >>> os.chdir(sample_buildout)
     >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing data-dir.
     data-dir: Creating directory mystuff
@@ -338,7 +338,7 @@
     ... path = mydata
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling data-dir.
     Installing data-dir.
@@ -358,7 +358,7 @@
 the part will be reinstalled:
 
     >>> rmdir(sample_buildout, 'mydata')
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling data-dir.
     Installing data-dir.
@@ -389,7 +389,7 @@
 
 We'll get a user error, not a traceback.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     data-dir: Cannot create /xxx/mydata. /xxx is not a directory.
     While:
@@ -454,7 +454,7 @@
     ... path = foo bin
     ... """)
 
-    >>> print system(buildout), # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/recipes'
     Uninstalling data-dir.
     Installing data-dir.
@@ -488,7 +488,7 @@
     ... path = foo bins
     ... """)
 
-    >>> print system(buildout), # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/recipes'
     Installing data-dir.
     data-dir: Creating directory foo
@@ -564,7 +564,7 @@
 
 When we rerun the buildout:
 
-    >>> print system(buildout), # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/recipes'
     Installing data-dir.
     data-dir: Creating directory foo
@@ -636,7 +636,8 @@
 
 ..
 
-    >>> remove(sample_buildout, 'recipes', 'mkdir.pyc')
+    >>> for (d, _, f) in os.walk(join(sample_buildout, 'recipes')):
+    ...     if f == 'mkdir.pyc': rermove(join(d, f))
 
 We returned by calling created, taking advantage of the fact that it
 returns the registered paths.  We did this for illustrative purposes.
@@ -645,7 +646,7 @@
 If we rerun the buildout, again, we'll get the error and no
 directories will be created:
 
-    >>> print system(buildout), # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/recipes'
     Installing data-dir.
     data-dir: Creating directory foo
@@ -675,7 +676,7 @@
     ... path = foo bins
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing data-dir.
     data-dir: Creating directory foo
@@ -722,7 +723,7 @@
 the origin of the value (file name or COMPUTED_VALUE, DEFAULT_VALUE,
 COMMAND_LINE_VALUE).
 
-    >>> print system(buildout+ ' annotate'),
+    >>> run(buildout+ ' annotate')
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     <BLANKLINE>
     Annotated sections
@@ -808,10 +809,10 @@
     ...         self.options = options
     ...
     ...     def install(self):
-    ...         items = self.options.items()
+    ...         items = list(self.options.items())
     ...         items.sort()
     ...         for option, value in items:
-    ...             print option, value
+    ...             print(option, value)
     ...         return ()
     ...
     ...     update = install
@@ -867,7 +868,7 @@
 Now, if we run the buildout, we'll see the options with the values
 substituted.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling data-dir.
     Installing data-dir.
@@ -886,7 +887,7 @@
 recipe, so it assumed it could and reinstalled mydata.  If we rerun
 the buildout:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Updating data-dir.
     Updating debug.
@@ -925,7 +926,7 @@
     ... path = mydata
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Updating data-dir.
@@ -963,7 +964,7 @@
 
 It will still be treated as a part:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Updating data-dir.
@@ -1002,7 +1003,7 @@
 
 It will still be treated as a part:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Updating data-dir.
     Updating debug.
@@ -1051,7 +1052,7 @@
     ... path = mydata
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Uninstalling data-dir.
@@ -1143,8 +1144,8 @@
     >>> write(sample_buildout, 'demo', 'demo.py',
     ... """
     ... def ext(buildout):
-    ...     print [part['option'] for name, part in buildout.items() \
-    ...           if name.startswith('part')]
+    ...     print([part['option'] for name, part in buildout.items() \
+    ...           if name.startswith('part')])
     ... """)
 
     >>> write(sample_buildout, 'demo', 'setup.py',
@@ -1167,7 +1168,7 @@
     ... """)
 
     >>> os.chdir(sample_buildout)
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout'))
     Develop: '/sample-buildout/demo'
     Uninstalling myfiles.
     Getting distribution for 'recipes'.
@@ -1185,14 +1186,14 @@
     ... extends = extension2.cfg
     ... """)
 
-    >>> print system(os.path.join('bin', 'buildout')),
+    >>> run(os.path.join('bin', 'buildout'))
     ['a1 a2/na3 a4/na5', 'b1 b2 b3 b4', 'c1 c2/nc3 c4 c5', 'h1 h2']
     Develop: '/sample-buildout/demo'
 
 Annotated sections output shows which files are responsible for which
 operations.
 
-    >>> print system(os.path.join('bin', 'buildout') + ' annotate'),
+    >>> run(os.path.join('bin', 'buildout') + ' annotate')
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     <BLANKLINE>
     Annotated sections
@@ -1268,7 +1269,7 @@
     ... op = base
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing debug.
     op buildout
@@ -1338,7 +1339,7 @@
     ... name = base
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing debug.
@@ -1400,7 +1401,7 @@
     ... """ % dict(url=server_url))
 
 
-    >>> print system(buildout+ ' -c client.cfg'),
+    >>> run(buildout+ ' -c client.cfg')
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing debug.
@@ -1431,7 +1432,7 @@
     ... name = remote
     ... """)
 
-    >>> print system(buildout + ' -c ' + server_url + '/remote.cfg'),
+    >>> run(buildout + ' -c ' + server_url + '/remote.cfg')
     While:
       Initializing.
     Error: Missing option: buildout:directory
@@ -1441,10 +1442,9 @@
 files loaded from URLs.  In this case, the buildout directory would
 normally be defined on the command line:
 
-    >>> print system(buildout
-    ...              + ' -c ' + server_url + '/remote.cfg'
+    >>> run(buildout + ' -c ' + server_url + '/remote.cfg'
     ...              + ' buildout:directory=' + sample_buildout
-    ...              ),
+    ...              )
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing debug.
@@ -1473,7 +1473,7 @@
     ... """)
 
     >>> os.environ['HOME'] = home
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing debug.
@@ -1490,7 +1490,7 @@
 A buildout command-line argument, -U, can be used to suppress reading
 user defaults:
 
-    >>> print system(buildout + ' -U'),
+    >>> run(buildout + ' -U')
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing debug.
@@ -1519,7 +1519,7 @@
     ... extends = b1.cfg b2.cfg
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     name base
     op1 b1 1
     op2 b2 2
@@ -1562,7 +1562,7 @@
     ...         self.options = options
     ...
     ...     def install(self):
-    ...         print "chkconfig --add %s" % self.options['script']
+    ...         print("chkconfig --add %s" % self.options['script'])
     ...         return ()
     ...
     ...     def update(self):
@@ -1570,7 +1570,7 @@
     ...
     ...
     ... def uninstall_service(name, options):
-    ...     print "chkconfig --del %s" % options['script']
+    ...     print("chkconfig --del %s" % options['script'])
     ... """)
 
 To use these recipes we must register them using entry points. Make
@@ -1609,20 +1609,18 @@
 
 When the buildout is run the service will be installed
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing service.
     chkconfig --add /path/to/script
-    <BLANKLINE>
 
 The service has been installed. If the buildout is run again with no
 changes, the service shouldn't be changed.
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Updating service.
-    <BLANKLINE>
 
 Now we change the service part to trigger uninstallation and
 re-installation.
@@ -1638,14 +1636,13 @@
     ... script = /path/to/a/different/script
     ... """)
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling service.
     Running uninstall recipe.
     chkconfig --del /path/to/script
     Installing service.
     chkconfig --add /path/to/a/different/script
-    <BLANKLINE>
 
 Now we remove the service part, and add another part.
 
@@ -1659,14 +1656,13 @@
     ... recipe = recipes:debug
     ... """)
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling service.
     Running uninstall recipe.
     chkconfig --del /path/to/a/different/script
     Installing debug.
     recipe recipes:debug
-    <BLANKLINE>
 
 Uninstall recipes don't have to take care of removing all the files
 and directories created by the part. This is still done automatically,
@@ -1684,7 +1680,7 @@
     ... def backup_directory(name, options):
     ...     path = options['path']
     ...     size = len(os.listdir(path))
-    ...     print "backing up directory %s of size %s" % (path, size)
+    ...     print("backing up directory %s of size %s" % (path, size))
     ... """)
 
 It must be registered with the zc.buildout.uninstall entry
@@ -1726,14 +1722,13 @@
 
 Run the buildout to install the part.
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing dir.
     dir: Creating directory my_directory
     Installing debug.
     recipe recipes:debug
-    <BLANKLINE>
 
 Now we remove the part from the configuration file.
 
@@ -1750,14 +1745,13 @@
 When the buildout is run the part is removed, and the uninstall recipe
 is run before the directory is deleted.
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling dir.
     Running uninstall recipe.
     backing up directory /sample-buildout/my_directory of size 0
     Updating debug.
     recipe recipes:debug
-    <BLANKLINE>
 
 Now we will return the registration to normal for the benefit of the
 rest of the examples.
@@ -1855,7 +1849,7 @@
 Note that we used the installed buildout option to specify an
 alternate file to store information about installed parts.
 
-    >>> print system(buildout+' -c other.cfg debug:op1=foo -v'),
+    >>> run(buildout+' -c other.cfg debug:op1=foo -v')
     Develop: '/sample-buildout/recipes'
     Installing debug.
     name other
@@ -1868,7 +1862,7 @@
 
 Options can also be combined in the usual Unix way, as in:
 
-    >>> print system(buildout+' -vcother.cfg debug:op1=foo'),
+    >>> run(buildout+' -vcother.cfg debug:op1=foo')
     Develop: '/sample-buildout/recipes'
     Updating debug.
     name other
@@ -1909,7 +1903,7 @@
     ... recipe = recipes:debug
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling debug.
     Installing debug.
@@ -1993,7 +1987,7 @@
 
 and run the buildout specifying just d3 and d4:
 
-    >>> print system(buildout+' install d3 d4'),
+    >>> run(buildout+' install d3 d4')
     Develop: '/sample-buildout/recipes'
     Uninstalling d3.
     Installing d3.
@@ -2064,7 +2058,7 @@
 
 Now, if we run the buildout without the install command:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling d2.
     Uninstalling d1.
@@ -2121,7 +2115,7 @@
     ...    work = os.path.join(alt, 'work'),
     ... ))
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Creating directory '/sample-alt/scripts'.
     Creating directory '/sample-alt/work'.
     Creating directory '/sample-alt/basket'.
@@ -2157,7 +2151,7 @@
     ...    recipes=os.path.join(sample_buildout, 'recipes'),
     ...    ))
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Creating directory '/sample-alt/bin'.
     Creating directory '/sample-alt/parts'.
     Creating directory '/sample-alt/eggs'.
@@ -2209,7 +2203,7 @@
 configuration file.  Because the verbosity is subtracted from the log
 level, we get a final log level of 20, which is the INFO level.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     INFO Develop: '/sample-buildout/recipes'
 
 Predefined buildout options
@@ -2227,7 +2221,7 @@
     ... parts =
     ... """)
 
-    >>> print system(buildout+' -vv'), # doctest: +NORMALIZE_WHITESPACE
+    >>> run(buildout+' -vv') # doctest: +NORMALIZE_WHITESPACE
     Installing 'zc.buildout', 'setuptools'.
     We have a develop egg: zc.buildout X.X.
     We have the best distribution that satisfies 'setuptools'.
@@ -2410,9 +2404,8 @@
 
     >>> sample_bootstrapped = tmpdir('sample-bootstrapped')
 
-    >>> print system(buildout
-    ...              +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
-    ...              +' init'),
+    >>> run(buildout +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
+    ...              +' init')
     Creating '/sample-bootstrapped/setup.cfg'.
     Creating directory '/sample-bootstrapped/bin'.
     Creating directory '/sample-bootstrapped/parts'.
@@ -2451,16 +2444,15 @@
     ... parts =
     ... ''')
 
-    >>> print system(buildout
-    ...              +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
-    ...              +' bootstrap'),
+    >>> run(buildout +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
+    ...              +' bootstrap')
     Generated script '/sample-bootstrapped/bin/buildout'.
 
     >>> buildout_script = join(sample_bootstrapped, 'bin', 'buildout')
     >>> import sys
     >>> if sys.platform.startswith('win'):
     ...     buildout_script += '-script.py'
-    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_script).read()) # doctest: +ELLIPSIS
     #!... -S
     <BLANKLINE>
     import os
@@ -2500,9 +2492,8 @@
 
     >>> sample_bootstrapped2 = tmpdir('sample-bootstrapped2')
 
-    >>> print system(buildout
-    ...              +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
-    ...              +' bootstrap'),
+    >>> run(buildout +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
+    ...              +' bootstrap')
     While:
       Initializing.
     Error: Couldn't open /sample-bootstrapped2/setup.cfg
@@ -2513,9 +2504,8 @@
     ... parts =
     ... """)
 
-    >>> print system(buildout
-    ...              +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
-    ...              +' bootstrap'),
+    >>> run(buildout +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
+    ...              +' bootstrap')
     Creating directory '/sample-bootstrapped2/bin'.
     Creating directory '/sample-bootstrapped2/parts'.
     Creating directory '/sample-bootstrapped2/eggs'.
@@ -2653,7 +2643,7 @@
     ... recipe = recipes:debug
     ... """)
 
-    >>> print system(buildout+' buildout:installed=inst.cfg'),
+    >>> run(buildout+' buildout:installed=inst.cfg')
     Develop: '/sample-buildout/recipes'
     Installing debug.
     recipe recipes:debug
@@ -2675,7 +2665,7 @@
 buildout installed option:
 
     >>> os.remove('inst.cfg')
-    >>> print system(buildout+' buildout:installed='),
+    >>> run(buildout+' buildout:installed=')
     Develop: '/sample-buildout/recipes'
     Installing debug.
     recipe recipes:debug
@@ -2701,7 +2691,7 @@
     ... parts =
     ... """)
 
-    >>> print system(buildout+' buildout:installed=inst.cfg'),
+    >>> run(buildout+' buildout:installed=inst.cfg')
 
     >>> ls(sample_buildout)
     -  b1.cfg
@@ -2738,9 +2728,9 @@
     >>> write(sample_bootstrapped, 'demo', 'demo.py',
     ... """
     ... def ext(buildout):
-    ...     print 'ext', list(buildout)
+    ...     print('ext', list(buildout))
     ... def unload(buildout):
-    ...     print 'unload', list(buildout)
+    ...     print('unload', list(buildout))
     ... """)
 
     >>> write(sample_bootstrapped, 'demo', 'setup.py',
@@ -2770,7 +2760,7 @@
     ... """)
 
     >>> os.chdir(sample_bootstrapped)
-    >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_bootstrapped, 'bin', 'buildout'))
     Develop: '/sample-bootstrapped/demo'
 
 Now we can add the extensions option.  We were a bit tricky and ran
@@ -2790,7 +2780,7 @@
 
 We see that our extension is loaded and executed:
 
-    >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_bootstrapped, 'bin', 'buildout'))
     ext ['buildout']
     Develop: '/sample-bootstrapped/demo'
     unload ['buildout']

Modified: zc.buildout/branches/python-3/src/zc/buildout/debugging.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/debugging.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/debugging.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -56,7 +56,7 @@
 
 If we run the buildout, we'll get an error:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing data-dir.
     While:
@@ -67,11 +67,11 @@
 If we want to debug the error, we can add the -D option. Here's we'll
 supply some input:
 
-    >>> print system(buildout+" -D", """\
+    >>> run(buildout+" -D", """\
     ... up
     ... p self.options.keys()
     ... q
-    ... """),
+    ... """)
     Develop: '/sample-buildout/recipes'
     Installing data-dir.
     > /zc/buildout/buildout.py(925)__getitem__()

Modified: zc.buildout/branches/python-3/src/zc/buildout/dependencylinks.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/dependencylinks.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/dependencylinks.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -54,14 +54,13 @@
 
 Now we can run the buildout.
 
-    >>> print system(buildout)
+    >>> run(buildout)
     GET 200 /
     GET 200 /demoneeded-1.2c1.zip
     Develop: '/sample-buildout/depdemo'
     Installing eggs.
     Getting distribution for 'demoneeded'.
     Got demoneeded 1.2c1.
-    <BLANKLINE>
 
 Notice that the egg was retrieved from the logging server.
 
@@ -83,7 +82,7 @@
     ...     for egg in glob(join(sample_buildout, 'eggs', 'demoneeded*.egg')):
     ...         remove(sample_buildout, 'eggs', egg)
     >>> remove_demoneeded_egg()
-    >>> print system(buildout) # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/depdemo'
     ...
     Getting distribution for 'demoneeded'.
@@ -91,7 +90,6 @@
       Updating eggs.
       Getting distribution for 'demoneeded'.
     Error: Couldn't find a distribution for 'demoneeded'.
-    <BLANKLINE>
 
 Now it can't find the dependency since neither the buildout
 configuration nor setup specifies where to look.
@@ -111,12 +109,11 @@
     ... eggs = depdemo
     ... ''' % link_server)
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/depdemo'
     Installing eggs.
     Getting distribution for 'demoneeded'.
     Got demoneeded 1.2c1.
-    <BLANKLINE>
 
 This time the dependency egg was found on the server without logging
 configured.
@@ -133,13 +130,12 @@
     ... '''  % link_server2)
 
     >>> remove_demoneeded_egg()
-    >>> print system(buildout) #doctest: +ELLIPSIS
+    >>> run(buildout) #doctest: +ELLIPSIS
     GET 200 /...
     Develop: '/sample-buildout/depdemo'
     Updating eggs.
     Getting distribution for 'demoneeded'.
     Got demoneeded 1.2c1.
-    <BLANKLINE>
 
 So when both setuptools and buildout specify places to search for
 eggs, the dependency_links takes precedence over find-links.
@@ -165,12 +161,11 @@
     ... ''' % link_server)
 
     >>> remove_demoneeded_egg()
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/depdemo'
     Updating eggs.
     Getting distribution for 'demoneeded'.
     Got demoneeded 1.2c1.
-    <BLANKLINE>
 
 Notice that this time the egg isn't downloaded from the logging server.
 
@@ -190,10 +185,9 @@
     ... eggs = depdemo
     ... ''' % link_server)
     >>> remove_demoneeded_egg()
-    >>> print system(buildout) #doctest: +ELLIPSIS
+    >>> run(buildout) #doctest: +ELLIPSIS
     GET 200 /...
     Develop: '/sample-buildout/depdemo'
     Updating eggs.
     Getting distribution for 'demoneeded'.
     Got demoneeded 1.2c1.
-    <BLANKLINE>

Modified: zc.buildout/branches/python-3/src/zc/buildout/download.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/download.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/download.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -24,13 +24,13 @@
 import re
 import shutil
 import tempfile
-import urllib
-import urlparse
+import urllib.request, urllib.parse, urllib.error
+import urllib.parse
 import zc.buildout
 
 
-class URLOpener(urllib.FancyURLopener):
-    http_error_default = urllib.URLopener.http_error_default
+class URLOpener(urllib.request.FancyURLopener):
+    http_error_default = urllib.request.URLopener.http_error_default
 
 
 class ChecksumError(zc.buildout.UserError):
@@ -157,7 +157,7 @@
         if re.match(r"^[A-Za-z]:\\", url):
             url = 'file:' + url
 
-        parsed_url = urlparse.urlparse(url, 'file')
+        parsed_url = urllib.parse.urlparse(url, 'file')
         url_scheme, _, url_path = parsed_url[:3]
         if url_scheme == 'file':
             self.logger.debug('Using local resource %s' % url)
@@ -172,14 +172,18 @@
                 "Couldn't download %r in offline mode." % url)
 
         self.logger.info('Downloading %s' % url)
-        urllib._urlopener = url_opener
+        urllib.request._urlopener = url_opener
         handle, tmp_path = tempfile.mkstemp(prefix='buildout-')
         try:
-            tmp_path, headers = urllib.urlretrieve(url, tmp_path)
-            if not check_md5sum(tmp_path, md5sum):
-                raise ChecksumError(
-                    'MD5 checksum mismatch downloading %r' % url)
-        except IOError, e:
+            try:
+                tmp_path, headers = urllib.request.urlretrieve(url, tmp_path)
+                if not check_md5sum(tmp_path, md5sum):
+                    raise ChecksumError(
+                        'MD5 checksum mismatch downloading %r' % url)
+            finally:
+                os.close(handle)
+        except IOError:
+            e = sys.exc_info()[0]
             os.remove(tmp_path)
             raise zc.buildout.UserError("Error downloading extends for URL "
                               "%s: %r" % (url, e[1:3]))
@@ -204,7 +208,7 @@
         else:
             if re.match(r"^[A-Za-z]:\\", url):
                 url = 'file:' + url
-            parsed = urlparse.urlparse(url, 'file')
+            parsed = urllib.parse.urlparse(url, 'file')
             url_path = parsed[2]
 
             if parsed[0] == 'file':

Modified: zc.buildout/branches/python-3/src/zc/buildout/download.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/download.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/download.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -28,7 +28,7 @@
 
 >>> from zc.buildout.download import Download
 >>> download = Download()
->>> print download.cache_dir
+>>> print(download.cache_dir)
 None
 
 Downloading a file is achieved by calling the utility with the URL as an
@@ -37,7 +37,7 @@
 meant to be cleaned up during the same buildout run:
 
 >>> path, is_temp = download(server_url+'foo.txt')
->>> print path
+>>> print(path)
 /.../buildout-...
 >>> cat(path)
 This is a foo text.
@@ -59,8 +59,8 @@
 When trying to access a file that doesn't exist, we'll get an exception:
 
 >>> try: download(server_url+'not-there') # doctest: +ELLIPSIS
-... except: print 'download error'
-... else: print 'woops'
+... except: print('download error')
+... else: print('woops')
 download error
 
 Downloading a local file doesn't produce a temporary file but simply returns
@@ -102,7 +102,7 @@
 >>> target_dir = tmpdir('download-target')
 >>> path, is_temp = download(server_url+'foo.txt',
 ...                          path=join(target_dir, 'downloaded.txt'))
->>> print path
+>>> print(path)
 /download-target/downloaded.txt
 >>> cat(path)
 This is a foo text.
@@ -136,7 +136,7 @@
 
 >>> cache = tmpdir('download-cache')
 >>> download = Download(cache=cache)
->>> print download.cache_dir
+>>> print(download.cache_dir)
 /download-cache/
 
 Simple usage
@@ -148,7 +148,7 @@
 
 >>> ls(cache)
 >>> path, is_temp = download(server_url+'foo.txt')
->>> print path
+>>> print(path)
 /download-cache/foo.txt
 >>> cat(path)
 This is a foo text.
@@ -160,7 +160,7 @@
 
 >>> write(server_data, 'foo.txt', 'The wrong text.')
 >>> path, is_temp = download(server_url+'foo.txt')
->>> print path
+>>> print(path)
 /download-cache/foo.txt
 >>> cat(path)
 This is a foo text.
@@ -179,7 +179,7 @@
 >>> mkdir(server_data, 'other')
 >>> write(server_data, 'other', 'foo.txt', 'The wrong text.')
 >>> path, is_temp = download(server_url+'other/foo.txt')
->>> print path
+>>> print(path)
 /download-cache/foo.txt
 >>> cat(path)
 This is a foo text.
@@ -194,7 +194,7 @@
 
 >>> path, is_temp = download(server_url+'foo.txt',
 ...                          path=join(target_dir, 'downloaded.txt'))
->>> print path
+>>> print(path)
 /download-target/downloaded.txt
 >>> cat(path)
 This is a foo text.
@@ -208,7 +208,7 @@
 
 >>> path, is_temp = download(server_url+'foo.txt',
 ...                          path=join(target_dir, 'downloaded.txt'))
->>> print path
+>>> print(path)
 /download-target/downloaded.txt
 >>> cat(path)
 This is a foo text.
@@ -281,7 +281,7 @@
 download cache. Let's use a namespace "test" instead:
 
 >>> download = Download(cache=cache, namespace='test')
->>> print download.cache_dir
+>>> print(download.cache_dir)
 /download-cache/test
 
 The namespace sub-directory hasn't been created yet:
@@ -292,7 +292,7 @@
 of the file inside it:
 
 >>> path, is_temp = download(server_url+'foo.txt')
->>> print path
+>>> print(path)
 /download-cache/test/foo.txt
 >>> ls(cache)
 d test
@@ -311,7 +311,7 @@
 >>> write(cache, 'foo.txt', 'The wrong text.')
 
 >>> path, is_temp = download(server_url+'foo.txt')
->>> print path
+>>> print(path)
 /download-cache/test/foo.txt
 >>> cat(path)
 This is a foo text.
@@ -332,7 +332,7 @@
 
 >>> download = Download(cache=cache, hash_name=True)
 >>> path, is_temp = download(server_url+'foo.txt')
->>> print path
+>>> print(path)
 /download-cache/09f5793fcdc1716727f72d49519c688d
 >>> cat(path)
 This is a foo text.
@@ -362,7 +362,7 @@
 cache under a different name:
 
 >>> path2, is_temp = download(server_url+'other/foo.txt')
->>> print path2
+>>> print(path2)
 /download-cache/537b6d73267f8f4447586989af8c470e
 >>> path == path2
 False
@@ -390,7 +390,7 @@
 cache is configured in the first place:
 
 >>> download = Download(cache=cache, fallback=True)
->>> print download.cache_dir
+>>> print(download.cache_dir)
 /download-cache/
 
 A downloaded file will be cached:
@@ -408,8 +408,8 @@
 
 >>> remove(server_data, 'foo.txt')
 >>> try: Download()(server_url+'foo.txt') # doctest: +ELLIPSIS
-... except: print 'download error'
-... else: print 'woops'
+... except: print('download error')
+... else: print('woops')
 download error
 >>> path, is_temp = download(server_url+'foo.txt')
 >>> cat(path)
@@ -426,7 +426,7 @@
 
 >>> offline_download = Download(cache=cache, offline=True, fallback=True)
 >>> path, is_temp = offline_download(server_url+'foo.txt')
->>> print path
+>>> print(path)
 /download-cache/foo.txt
 >>> cat(path)
 This is a foo text.
@@ -466,7 +466,7 @@
 option:
 
 >>> download = Download({'download-cache': cache}, namespace='cmmi')
->>> print download.cache_dir
+>>> print(download.cache_dir)
 /download-cache/cmmi
 
 If the ``download-cache`` option specifies a relative path, it is understood
@@ -474,18 +474,18 @@
 that is given:
 
 >>> download = Download({'download-cache': 'relative-cache'})
->>> print download.cache_dir
+>>> print(download.cache_dir)
 /sample-buildout/relative-cache/
 
 >>> download = Download({'directory': join(sample_buildout, 'root'),
 ...                      'download-cache': 'relative-cache'})
->>> print download.cache_dir
+>>> print(download.cache_dir)
 /sample-buildout/root/relative-cache/
 
 Keyword parameters take precedence over the corresponding options:
 
 >>> download = Download({'download-cache': cache}, cache=None)
->>> print download.cache_dir
+>>> print(download.cache_dir)
 None
 
 Whether to assume offline mode can be inferred from either the ``offline`` or

Modified: zc.buildout/branches/python-3/src/zc/buildout/downloadcache.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/downloadcache.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/downloadcache.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -31,7 +31,7 @@
 We specified a link server that has some distributions available for
 download:
 
-    >>> print get(link_server),
+    >>> print_(get(link_server).decode())
     <html><body>
     <a href="bigdemo-0.1-py2.4.egg">bigdemo-0.1-py2.4.egg</a><br>
     <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
@@ -45,8 +45,8 @@
     <a href="index/">index/</a><br>
     <a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
     </body></html>
-    
 
+
 We'll enable logging on the link server so we can see what's going on:
 
     >>> get(link_server+'enable_server_logging')
@@ -58,7 +58,7 @@
 If we run the buildout, we'll see the eggs installed from the link
 server as usual:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     GET 200 /
     GET 200 /demo-0.2-py2.4.egg
     GET 200 /demoneeded-1.2c1.zip
@@ -87,8 +87,8 @@
     >>> for  f in os.listdir('eggs'):
     ...     if f.startswith('demo'):
     ...         remove('eggs', f)
-   
-    >>> print system(buildout),
+
+    >>> run(buildout)
     GET 200 /
     Updating eggs.
     Getting distribution for 'demo==0.2'.
@@ -131,7 +131,7 @@
     ... eggs = demo
     ... ''' % globals())
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Uninstalling eggs.
     Installing eggs.
     Getting distribution for 'demo'.

Modified: zc.buildout/branches/python-3/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/easy_install.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/easy_install.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -26,6 +26,7 @@
 import pkg_resources
 import py_compile
 import re
+import setuptools
 import setuptools.archive_util
 import setuptools.command.setopt
 import setuptools.package_index
@@ -52,6 +53,7 @@
 
 is_win32 = sys.platform == 'win32'
 is_jython = sys.platform.startswith('java')
+setuptools_key = pkg_resources.Requirement.parse('setuptools').key
 is_distribute = (
     pkg_resources.Requirement.parse('setuptools').key=='distribute')
 
@@ -72,7 +74,7 @@
     jython_os_name = (java.lang.System.getProperties()['os.name']).lower()
 
 setuptools_loc = pkg_resources.working_set.find(
-    pkg_resources.Requirement.parse('setuptools')
+    pkg_resources.Requirement.parse(setuptools_key)
     ).location
 
 # Include buildout and setuptools eggs in paths.  We prevent dupes just to
@@ -94,11 +96,11 @@
     stdout, stderr = subprocess.Popen(
         [executable, '-S', '-c',
          'try:\n'
-         '    import ConfigParser\n'
+         '    import pickle\n'
          'except ImportError:\n'
-         '    print 1\n'
+         '    print(1)\n'
          'else:\n'
-         '    print 0\n'],
+         '    print(0)\n'],
         stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
     return bool(int(stdout.strip()))
 
@@ -129,7 +131,7 @@
         cmd.extend(args)
         cmd.extend([
             "-c", "import sys, os;"
-            "print repr([os.path.normpath(p) for p in sys.path if p])"])
+            "print(repr([os.path.normpath(p) for p in sys.path if p]))"])
         # Windows needs some (as yet to be determined) part of the real env.
         env = os.environ.copy()
         # We need to make sure that PYTHONPATH, which will often be set
@@ -184,10 +186,10 @@
                              close_fds=not is_win32)
         i, o = (p.stdin, p.stdout)
         i.close()
-        version = o.read().strip()
+        version = o.read().strip().decode()
         o.close()
         pystring, version = version.split()
-        assert pystring == 'Python'
+        assert pystring == 'Python', pystring
         version = re.match('(\d[.]\d)([.].*\d)?$', version).group(1)
         _versions[executable] = version
         return version
@@ -716,6 +718,13 @@
 
     def _get_dist(self, requirement, ws, always_unzip):
 
+        if (requirement.project_name == 'setuptools' and
+            (ws.find(pkg_resources.Requirement.parse('distribute'))
+             or sys.version_info[0] >= 3
+             )
+            ):
+            requirement = pkg_resources.Requirement.parse('distribute')
+
         __doing__ = 'Getting distribution for %r.', str(requirement)
 
         # Maybe an existing dist is already the best dist that satisfies the
@@ -849,7 +858,7 @@
                         "does not require setuptools.",
                         dist)
                 requirement = self._constrain(
-                    pkg_resources.Requirement.parse('setuptools')
+                    pkg_resources.Requirement.parse(setuptools_key)
                     )
                 if ws.find(requirement) is None:
                     for dist in self._get_dist(requirement, ws, False):
@@ -857,8 +866,6 @@
 
 
     def _constrain(self, requirement):
-        if is_distribute and requirement.key == 'setuptools':
-            requirement = pkg_resources.Requirement.parse('distribute')
         version = self._versions.get(requirement.project_name)
         if version:
             if version not in requirement:
@@ -914,9 +921,21 @@
         while requirements:
             # Process dependencies breadth-first.
             req = self._constrain(requirements.pop(0))
+
             if req in processed:
                 # Ignore cyclic or redundant dependencies.
                 continue
+
+            if (req.project_name == 'setuptools' and
+                (ws.find(pkg_resources.Requirement.parse('distribute'))
+                 or sys.version_info[0] >= 3
+                 )
+                ):
+                processed[req] = True
+                req = pkg_resources.Requirement.parse('distribute')
+                if req in processed:
+                    continue
+
             dist = best.get(req.key)
             if dist is None:
                 # Find the best distribution and add it to the map.
@@ -924,7 +943,7 @@
                 if dist is None:
                     try:
                         dist = best[req.key] = env.best_match(req, ws)
-                    except pkg_resources.VersionConflict, err:
+                    except pkg_resources.VersionConflict as err:
                         raise VersionConflict(err, ws)
                     if dist is None or (
                         dist.location in self._site_packages and not
@@ -1157,12 +1176,12 @@
         undo.append(lambda: os.remove(tsetup))
         undo.append(lambda: os.close(fd))
 
-        os.write(fd, runsetup_template % dict(
+        os.write(fd, (runsetup_template % dict(
             setuptools=setuptools_loc,
             setupdir=directory,
             setup=setup,
             __file__ = setup,
-            ))
+            )).encode())
 
         tmp3 = tempfile.mkdtemp('build', dir=dest)
         undo.append(lambda : shutil.rmtree(tmp3))
@@ -1305,7 +1324,7 @@
     for p in path:
         if p not in unique_path:
             unique_path.append(p)
-    return map(realpath, unique_path)
+    return list(map(realpath, unique_path))
 
 def _generate_scripts(reqs, working_set, dest, path, scripts, relative_paths,
                       initialization, executable, arguments,
@@ -1463,7 +1482,7 @@
     if changed:
         open(script_name, 'w').write(contents)
         try:
-            os.chmod(script_name, 0755)
+            os.chmod(script_name, 0o755)
         except (AttributeError, os.error):
             pass
         logger.info("Generated %s %r.", logged_type, full_name)
@@ -1548,7 +1567,7 @@
         if _opt == '-i':
             _interactive = True
         elif _opt == '-c':
-            exec _val
+            exec(_val)
         elif _opt == '-m':
             sys.argv[1:] = _args
             _args = []
@@ -1559,7 +1578,7 @@
         sys.argv[:] = _args
         __file__ = _args[0]
         del _options, _args
-        execfile(__file__)
+        exec(compile(open(__file__).read(), __file__, "exec"))
 
 if _interactive:
     del _interactive
@@ -1578,7 +1597,7 @@
            "import imp; "
            "fp, path, desc = imp.find_module(%r); "
            "fp.close(); "
-           "print path" % (name,)]
+           "print(path)" % (name,)]
     env = os.environ.copy()
     # We need to make sure that PYTHONPATH, which will often be set to
     # include a custom buildout-generated site.py, is not set, or else
@@ -1595,7 +1614,7 @@
         return None
     # else: ...
     res = stdout.strip()
-    if res.endswith('.pyc') or res.endswith('.pyo'):
+    if res.endswith('.pyc'.encode()) or res.endswith('.pyo'.encode()):
         raise RuntimeError('Cannot find uncompiled version of %s' % (name,))
     if not os.path.exists(res):
         raise RuntimeError(
@@ -1816,7 +1835,8 @@
 
 os.chdir(%(setupdir)r)
 sys.argv[0] = %(setup)r
-execfile(%(setup)r)
+
+exec(compile(open(%(setup)r).read(), %(setup)r, "exec"))
 """
 
 

Modified: zc.buildout/branches/python-3/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/easy_install.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/easy_install.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -107,7 +107,7 @@
 
 We have a link server that has a number of eggs:
 
-    >>> print get(link_server),
+    >>> print_(get(link_server).decode())
     <html><body>
     <a href="bigdemo-0.1-py2.4.egg">bigdemo-0.1-py2.4.egg</a><br>
     <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
@@ -138,7 +138,7 @@
 The working set contains the distributions we retrieved.
 
     >>> for dist in ws:
-    ...     print dist
+    ...     print(dist)
     demo 0.2
     demoneeded 1.1
 
@@ -182,7 +182,7 @@
     >>> ws = zc.buildout.easy_install.install(
     ...     ['demo'], dest, links=[link_server], index=link_server+'index/')
     >>> for dist in ws:
-    ...     print dist
+    ...     print(dist)
     demo 0.4c1
     demoneeded 1.2c1
 
@@ -207,7 +207,7 @@
     ...     links=[link_server], index=link_server+'index/')
 
     >>> for dist in ws:
-    ...     print dist
+    ...     print(dist)
     demo 0.3
     other 1.0
     demoneeded 1.0
@@ -321,7 +321,7 @@
     ...
     IncompatibleVersionError: Bad version 0.2
 
-    >>> print handler
+    >>> print(handler)
     zc.buildout.easy_install DEBUG
       Installing 'demo >0.2'.
     zc.buildout.easy_install ERROR
@@ -336,7 +336,7 @@
     ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
     ...     )
 
-    >>> print handler
+    >>> print(handler)
     zc.buildout.easy_install DEBUG
       Installing 'demo'.
     zc.buildout.easy_install DEBUG
@@ -764,7 +764,7 @@
             if _opt == '-i':
                 _interactive = True
             elif _opt == '-c':
-                exec _val
+                exec(_val)
             elif _opt == '-m':
                 sys.argv[1:] = _args
                 _args = []
@@ -785,20 +785,20 @@
 
     >>> write('ascript', '''
     ... "demo doc"
-    ... print sys.argv
-    ... print (__name__, __file__, __doc__)
+    ... print(sys.argv)
+    ... print(__name__, __file__, __doc__)
     ... ''')
-    >>> print system(join(bin, 'py')+' ascript a b c'),
+    >>> run(join(bin, 'py')+' ascript a b c')
     ['ascript', 'a', 'b', 'c']
     ('__main__', 'ascript', 'demo doc')
 
 For Python 2.5 and higher, you can also use the -m option to run a
 module:
 
-    >>> print system(join(bin, 'py')+' -m pdb'),
+    >>> run(join(bin, 'py')+' -m pdb')
     usage: pdb.py scriptfile [arg] ...
 
-    >>> print system(join(bin, 'py')+' -m pdb what'),
+    >>> run(join(bin, 'py')+' -m pdb what')
     Error: what does not exist
 
 An additional argument can be passed to define which scripts to install
@@ -818,7 +818,7 @@
     >>> ls(bin)
     -  run
 
-    >>> print system(os.path.join(bin, 'run')),
+    >>> run(os.path.join(bin, 'run'))
     3 1
 
 The ``scripts`` function: Including extra paths in scripts
@@ -948,7 +948,7 @@
 
 Of course, running the script works:
 
-    >>> print system(join(bo, 'bin', 'run')),
+    >>> run(join(bo, 'bin', 'run'))
     3 1
 
 We specified an interpreter and its paths are adjusted too:
@@ -979,7 +979,7 @@
             if _opt == '-i':
                 _interactive = True
             elif _opt == '-c':
-                exec _val
+                exec(_va)
             elif _opt == '-m':
                 sys.argv[1:] = _args
                 _args = []
@@ -1088,7 +1088,7 @@
 behavior of the function it replaces.  The following shows the part that
 buildout inserts, in the simplest case.
 
-    >>> sys.stdout.write('#\n'); cat(site_path)
+    >>> print_('#\n'); cat(site_path)
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     #...
     def addsitepackages(known_paths):
@@ -1110,11 +1110,11 @@
 
 Here are some examples of the interpreter in use.
 
-    >>> print call_py(interpreter_path, "print 16+26")
+    >>> print_(call_py(interpreter_path, "print(16+26)").decode())
     42
-    <BLANKLINE>
-    >>> res = call_py(interpreter_path, "import sys; print sys.path")
-    >>> print res # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+
+    >>> res = call_py(interpreter_path, "import sys; print(sys.path)")
+    >>> print(res) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     ['',
      '/interpreter/parts/interpreter',
      ...,
@@ -1144,7 +1144,7 @@
     >>> cat(sitecustomize_path)
     import os
     os.environ['FOO'] = 'bar baz bing shazam'
-    >>> print call_py(interpreter_path, "import os; print os.environ['FOO']")
+    >>> print(call_py(interpreter_path, "import os; print(os.environ['FOO'])"))
     bar baz bing shazam
     <BLANKLINE>
 
@@ -1177,7 +1177,7 @@
 paths join a base to a path, as with the use of this argument in the
 ``scripts`` function.
 
-    >>> sys.stdout.write('#\n'); cat(site_path) # doctest: +ELLIPSIS
+    >>> print_('#\n'); cat(site_path) # doctest: +ELLIPSIS
     #...
     def addsitepackages(known_paths):
         """Add site packages, as determined by zc.buildout.
@@ -1194,8 +1194,8 @@
 
 The paths resolve in practice as you would expect.
 
-    >>> print call_py(interpreter_path,
-    ...               "import sys, pprint; pprint.pprint(sys.path)")
+    >>> print(call_py(interpreter_path,
+    ...               "import sys, pprint; pprint.pprint(sys.path)"))
     ... # doctest: +ELLIPSIS
     ['',
      '/interpreter/parts/interpreter',
@@ -1212,7 +1212,7 @@
     >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
     ...     interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
     ...     interpreter='py', extra_paths=[join(interpreter_dir, 'other')])
-    >>> sys.stdout.write('#\n'); cat(site_path) # doctest: +ELLIPSIS
+    >>> print_('#\n'); cat(site_path) # doctest: +ELLIPSIS
     #...
     def addsitepackages(known_paths):
         """Add site packages, as determined by zc.buildout.
@@ -1224,8 +1224,8 @@
             '/interpreter/other'
             ]...
 
-    >>> print call_py(interpreter_path,
-    ...               "import sys, pprint; pprint.pprint(sys.path)")
+    >>> print(call_py(interpreter_path,
+    ...               "import sys, pprint; pprint.pprint(sys.path)"))
     ... # doctest: +ELLIPSIS
     ['',
      '/interpreter/parts/interpreter',
@@ -1270,7 +1270,7 @@
     >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
     ...     interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
     ...     interpreter='py', include_site_packages=True)
-    >>> sys.stdout.write('#\n'); cat(site_path)
+    >>> print_('#\n'); cat(site_path)
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     #...
     def addsitepackages(known_paths):
@@ -1305,8 +1305,8 @@
 this package give the feature a more thorough workout, but this should
 give you an idea of the feature.
 
-    >>> res = call_py(interpreter_path, "import sys; print sys.path")
-    >>> print res # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    >>> res = call_py(interpreter_path, "import sys; print(sys.path)")
+    >>> print(res) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     ['',
      '/interpreter/parts/interpreter',
      ...,
@@ -1342,7 +1342,7 @@
     >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
     ...     interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
     ...     interpreter='py', include_site_packages=True)
-    >>> sys.stdout.write('#\n'); cat(site_path)
+    >>> print_('#\n'); cat(site_path)
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     #...
     def addsitepackages(known_paths):
@@ -1376,7 +1376,7 @@
     <BLANKLINE>
     def original_addsitepackages(known_paths):...
 
-    >>> print call_py(interpreter_path, "import sys; print sys.path")
+    >>> print(call_py(interpreter_path, "import sys; print(sys.path)"))
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     ['',
      '/interpreter/parts/interpreter',
@@ -1403,7 +1403,7 @@
     ...     interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
     ...     interpreter='py', include_site_packages=True,
     ...     relative_paths=interpreter_dir)
-    >>> sys.stdout.write('#\n'); cat(site_path)
+    >>> print_('#\n'); cat(site_path)
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     #...
     def addsitepackages(known_paths):
@@ -1441,7 +1441,7 @@
     <BLANKLINE>
     def original_addsitepackages(known_paths):...
 
-    >>> print call_py(interpreter_path, "import sys; print sys.path")
+    >>> print(call_py(interpreter_path, "import sys; print(sys.path)"))
     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
     ['',
      '/interpreter/parts/interpreter',
@@ -1523,9 +1523,8 @@
     >>> demo_call = join(interpreter_bin_dir, 'demo')
     >>> if sys.platform == 'win32':
     ...     demo_call = '"%s"' % demo_call
-    >>> print system(demo_call)
+    >>> run(demo_call)
     3 1
-    <BLANKLINE>
 
 There are a few differences from the ``scripts`` function.  First, the
 ``reqs`` argument (an iterable of string requirements or entry point
@@ -1680,7 +1679,7 @@
 Let's update our link server with a new version of extdemo:
 
     >>> update_extdemo()
-    >>> print get(link_server),
+    >>> print_(get(link_server).decode())
     <html><body>
     <a href="bigdemo-0.1-py2.4.egg">bigdemo-0.1-py2.4.egg</a><br>
     <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>

Modified: zc.buildout/branches/python-3/src/zc/buildout/extends-cache.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/extends-cache.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/extends-cache.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -41,20 +41,20 @@
 When trying to run this buildout offline, we'll find that we cannot read all
 of the required configuration:
 
->>> print system(buildout + ' -o')
+>>> run(buildout + ' -o')
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base.cfg' in offline mode.
 
 Trying the same online, we can:
 
->>> print system(buildout)
+>>> run(buildout)
 Unused options for buildout: 'foo'.
 
 As long as we haven't said anything about caching downloaded configuration,
 nothing gets cached. Offline mode will still cause the buildout to fail:
 
->>> print system(buildout + ' -o')
+>>> run(buildout + ' -o')
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base.cfg' in offline mode.
@@ -73,7 +73,7 @@
 ... extends-cache = cache
 ... """ % server_url)
 
->>> print system(buildout)
+>>> run(buildout)
 Unused options for buildout: 'foo'.
 
 >>> cache = join(sample_buildout, 'cache')
@@ -88,7 +88,7 @@
 
 We can now run buildout offline as it will read base.cfg from the cache:
 
->>> print system(buildout + ' -o')
+>>> run(buildout + ' -o')
 Unused options for buildout: 'foo'.
 
 The cache is being used purely as a fall-back in case we are offline or don't
@@ -104,18 +104,18 @@
 ... bar = baz
 ... """)
 
->>> print system(buildout + ' -o')
+>>> run(buildout + ' -o')
 Unused options for buildout: 'foo'.
 
 In online mode, buildout will download and use the modified version:
 
->>> print system(buildout)
+>>> run(buildout)
 Unused options for buildout: 'bar'.
 
 Trying offline mode again, the new version will be used as it has been put in
 the cache now:
 
->>> print system(buildout + ' -o')
+>>> run(buildout + ' -o')
 Unused options for buildout: 'bar'.
 
 Clean up:
@@ -203,7 +203,7 @@
 Buildout will now assemble its configuration from all of these 6 files,
 defaults first. The online resources end up in the respective extends caches:
 
->>> print system(buildout)
+>>> run(buildout)
 Unused options for buildout: 'foo'.
 
 >>> ls('user-cache')
@@ -249,7 +249,7 @@
 >>> remove('user-cache', os.listdir('user-cache')[0])
 >>> remove('cache', os.listdir('cache')[0])
 
->>> print system(buildout)
+>>> run(buildout)
 Unused options for buildout: 'foo'.
 
 >>> ls('user-cache')
@@ -272,7 +272,7 @@
 If we run buildout in offline mode now, it will fail because it cannot get at
 the remote configuration file needed by the user's defaults:
 
->>> print system(buildout + ' -o')
+>>> run(buildout + ' -o')
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base_default.cfg' in offline mode.
@@ -285,7 +285,7 @@
 ... extends = fancy_default.cfg
 ... offline = true
 ... """)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base_default.cfg' in offline mode.
@@ -299,7 +299,7 @@
 ... extends = %sbase_default.cfg
 ... offline = true
 ... """ % server_url)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base.cfg' in offline mode.
@@ -313,7 +313,7 @@
 ... extends = fancy.cfg
 ... offline = true
 ... """)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base.cfg' in offline mode.
@@ -327,7 +327,7 @@
 ... extends = %sbase.cfg
 ... offline = true
 ... """ % server_url)
->>> print system(buildout)
+>>> run(buildout)
 Unused options for buildout: 'foo'.
 
 The ``install-from-cache`` option is treated accordingly:
@@ -337,7 +337,7 @@
 ... extends = fancy_default.cfg
 ... install-from-cache = true
 ... """)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base_default.cfg' in offline mode.
@@ -351,7 +351,7 @@
 ... extends = %sbase_default.cfg
 ... install-from-cache = true
 ... """ % server_url)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base.cfg' in offline mode.
@@ -365,7 +365,7 @@
 ... extends = fancy.cfg
 ... install-from-cache = true
 ... """)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Initializing.
 Error: Couldn't download 'http://localhost/base.cfg' in offline mode.
@@ -379,7 +379,7 @@
 ... extends = %sbase.cfg
 ... install-from-cache = true
 ... """ % server_url)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Installing.
   Checking for upgrades.
@@ -406,7 +406,7 @@
 ... extends-cache = cache
 ... extends = %sbase.cfg
 ... """ % server_url)
->>> print system(buildout)
+>>> run(buildout)
 >>> ls('cache')
 -  5aedc98d7e769290a29d654a591a3a45
 >>> cat('cache', os.listdir(cache)[0])
@@ -420,7 +420,7 @@
 ... parts =
 ... foo = bar
 ... """)
->>> print system(buildout + " -n")
+>>> run(buildout + " -n")
 Unused options for buildout: 'foo'.
 >>> cat('cache', os.listdir(cache)[0])
 [buildout]
@@ -434,7 +434,7 @@
 ... [buildout]
 ... parts =
 ... """)
->>> print system(buildout + " -N")
+>>> run(buildout + " -N")
 Unused options for buildout: 'foo'.
 >>> cat('cache', os.listdir(cache)[0])
 [buildout]
@@ -463,7 +463,7 @@
 ... newest = true
 ... extends = %sbaseA.cfg %sbaseB.cfg
 ... """ % (server_url, server_url))
->>> print system(buildout + " -n")
+>>> run(buildout + " -n")
 Unused options for buildout: 'bar' 'foo'.
 
 (XXX We patch download utility's API to produce readable output for the test;
@@ -472,7 +472,7 @@
 >>> import zc.buildout
 >>> old_download = zc.buildout.download.Download.download
 >>> def wrapper_download(self, url, md5sum=None, path=None):
-...   print "The URL %s was downloaded." % url
+...   print("The URL %s was downloaded." % url)
 ...   return old_download(url, md5sum, path)
 >>> zc.buildout.download.Download.download = wrapper_download
 
@@ -498,7 +498,7 @@
 ... parts =
 ... extended-by = foo.cfg
 ... """)
->>> print system(buildout)
+>>> run(buildout)
 While:
   Initializing.
 Error: No-longer supported "extended-by" option found in http://localhost/base.cfg.

Modified: zc.buildout/branches/python-3/src/zc/buildout/repeatable.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/repeatable.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/repeatable.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -24,7 +24,7 @@
     ... class Recipe:
     ...     def __init__(*a): pass
     ...     def install(self):
-    ...         print 'recipe v1'
+    ...         print('recipe v1')
     ...         return ()
     ...     update = install
     ... ''')
@@ -39,7 +39,7 @@
 
     >>> write('recipe', 'README', '')
 
-    >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
     Running setup script 'recipe/setup.py'.
     ...
 
@@ -50,7 +50,7 @@
     ... class Recipe:
     ...     def __init__(*a): pass
     ...     def install(self):
-    ...         print 'recipe v2'
+    ...         print('recipe v2')
     ...         return ()
     ...     update = install
     ... ''')
@@ -64,7 +64,7 @@
     ... ''')
 
 
-    >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
     Running setup script 'recipe/setup.py'.
     ...
 
@@ -82,7 +82,7 @@
 
 If we run the buildout, it will use version 2:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Getting distribution for 'spam'.
     Got spam 2.
     Installing foo.
@@ -112,7 +112,7 @@
 
 Now, if we run the buildout, we'll use version 1 of the spam recipe:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Getting distribution for 'spam==1'.
     Got spam 1.
     Uninstalling foo.
@@ -123,7 +123,7 @@
 about versions used. If we run the buildout in verbose mode without
 specifying a versions section:
 
-    >>> print system(buildout+' buildout:versions= -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' buildout:versions= -v') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     We have a develop egg: zc.buildout 1.0.0.
     We have the best distribution that satisfies 'setuptools'.
@@ -145,7 +145,7 @@
 
 If we run the buildout with the versions section:
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     We have a develop egg: zc.buildout 1.0.0.
     We have the best distribution that satisfies 'setuptools'.

Modified: zc.buildout/branches/python-3/src/zc/buildout/rmtree.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/rmtree.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/rmtree.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -54,7 +54,7 @@
     0
     """
     def retry_writeable (func, path, exc):
-        os.chmod (path, 0600)
+        os.chmod (path, 0o600)
         func (path)
 
     shutil.rmtree (path, onerror = retry_writeable)

Modified: zc.buildout/branches/python-3/src/zc/buildout/runsetup.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/runsetup.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/runsetup.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -17,7 +17,7 @@
 To illustrate this, we'll create a package in a sample buildout:
 
     >>> mkdir('hello')
-    >>> write('hello', 'hello.py', 'print "Hello World!"')
+    >>> write('hello', 'hello.py', 'print("Hello World!")')
     >>> write('hello', 'README', 'This is hello')
     >>> write('hello', 'setup.py',
     ... """
@@ -29,10 +29,10 @@
     ...       author_email="bob at foo.com",
     ...       )
     ... """)
-  
+
 We can use the buildout command to generate the hello egg:
 
-    >>> print system(buildout +' setup hello -q bdist_egg'),
+    >>> run(buildout +' setup hello -q bdist_egg')
     Running setup script 'hello/setup.py'.
     zip_safe flag not set; analyzing archive contents...
 

Modified: zc.buildout/branches/python-3/src/zc/buildout/setup.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/setup.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/setup.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -28,14 +28,14 @@
 doesn't import setuptools.  Let's try running it to create an egg.
 We'll use the buildout script from our sample buildout:
 
-    >>> print system(buildout+' setup'),
+    >>> run(buildout+' setup')
     ... # doctest: +NORMALIZE_WHITESPACE
     Error: The setup command requires the path to a setup script or
     directory containing a setup script, and its arguments.
 
 Oops, we forgot to give the name of the setup script:
 
-    >>> print system(buildout+' setup setup.py bdist_egg'),
+    >>> run(buildout+' setup setup.py bdist_egg')
     ... # doctest: +ELLIPSIS
     Running setup script 'setup.py'.
     ...
@@ -46,6 +46,6 @@
 Note that we can specify a directory name.  This is often shorter and
 preferred by the lazy :)
 
-    >>> print system(buildout+' setup . bdist_egg'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup . bdist_egg') # doctest: +ELLIPSIS
     Running setup script './setup.py'.
     ...

Modified: zc.buildout/branches/python-3/src/zc/buildout/testing.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/testing.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/testing.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -12,11 +12,9 @@
 #
 ##############################################################################
 """Various test-support utility functions
-
-$Id$
 """
 
-import BaseHTTPServer
+import http.server
 import errno
 import logging
 import os
@@ -31,10 +29,11 @@
 import textwrap
 import threading
 import time
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 
 import zc.buildout.buildout
 import zc.buildout.easy_install
+from zc.buildout.easy_install import setuptools_key
 from zc.buildout.rmtree import rmtree
 
 fsync = getattr(os, 'fsync', lambda fileno: None)
@@ -50,7 +49,7 @@
         and os.path.exists(path+'-script.py')
         ):
         path = path+'-script.py'
-    print open(path).read(),
+    sys.stdout.write(open(path).read())
 
 def ls(dir, *subs):
     if subs:
@@ -59,12 +58,12 @@
     names.sort()
     for name in names:
         if os.path.isdir(os.path.join(dir, name)):
-            print 'd ',
+            print('d ', end=' ')
         elif os.path.islink(os.path.join(dir, name)):
-            print 'l ',
+            print('l ', end=' ')
         else:
-            print '- ',
-        print name
+            print('- ', end=' ')
+        print(name)
 
 def mkdir(*path):
     os.mkdir(os.path.join(*path))
@@ -103,13 +102,19 @@
                          )
     i, o, e = (p.stdin, p.stdout, p.stderr)
     if input:
-        i.write(input)
+        i.write(input.encode())
     i.close()
     result = o.read() + e.read()
     o.close()
     e.close()
     return result
 
+def print_(*args):
+    sys.stdout.write(' '.join(map(str, args)))
+
+def run(command, input=''):
+    sys.stdout.write(system(command, input).decode())
+
 def call_py(interpreter, cmd, flags=None):
     if sys.platform == 'win32':
         args = ['"%s"' % arg for arg in (interpreter, flags, cmd) if arg]
@@ -121,7 +126,7 @@
             ' '.join(arg for arg in (interpreter, flags, '-c', cmd) if arg))
 
 def get(url):
-    return urllib2.urlopen(url).read()
+    return urllib.request.urlopen(url).read()
 
 def _runsetup(setup, executable, *args):
     if os.path.isdir(setup):
@@ -170,7 +175,7 @@
         if os.path.exists(e):
             return e
     else:
-        cmd = 'python%s -c "import sys; print sys.executable"' % version
+        cmd = 'python%s -c "import sys; print(sys.executable)"' % version
         p = subprocess.Popen(cmd,
                              shell=True,
                              stdin=subprocess.PIPE,
@@ -183,7 +188,7 @@
         o.close()
         if os.path.exists(e):
             return e
-        cmd = 'python -c "import sys; print \'%s.%s\' % sys.version_info[:2]"'
+        cmd = 'python -c "import sys; print(\'%s.%s\' % sys.version_info[:2])"'
         p = subprocess.Popen(cmd,
                              shell=True,
                              stdin=subprocess.PIPE,
@@ -195,7 +200,7 @@
         e = o.read().strip()
         o.close()
         if e == version:
-            cmd = 'python -c "import sys; print sys.executable"'
+            cmd = 'python -c "import sys; print(sys.executable)"'
             p = subprocess.Popen(cmd,
                                 shell=True,
                                 stdin=subprocess.PIPE,
@@ -248,7 +253,7 @@
 
 def set_installer_values(values):
     """Set the given values on the installer."""
-    for name, value in values.items():
+    for name, value in list(values.items()):
         getattr(zc.buildout.easy_install, name)(value)
 
 def make_buildout(executable=None):
@@ -366,7 +371,7 @@
             'zc.recipe.egg', os.path.join(buildout, 'develop-eggs'))
         install_develop(
             'z3c.recipe.scripts', os.path.join(buildout, 'develop-eggs'))
-        write('buildout.cfg', textwrap.dedent('''\
+        write('buildout.cfg', textwrap.dedent('''
             [buildout]
             parts = py
             include-site-packages = false
@@ -377,11 +382,14 @@
             interpreter = py
             initialization =
             %(initialization)s
-            extra-paths = %(site-packages)s
-            eggs = setuptools
-            ''') % {
-                'initialization': initialization,
-                'site-packages': site_packages_dir})
+            extra-paths = %(site_packages)s
+            eggs = %(setuptools_key)s
+            ''') % dict(
+                  initialization = initialization,
+                  site_packages = site_packages_dir,
+                  setuptools_key = setuptools_key,
+                  ),
+              )
         system(os.path.join(buildout, 'bin', 'buildout'))
         os.chdir(old_wd)
         return (
@@ -397,6 +405,8 @@
         tmpdir = tmpdir,
         write = write,
         system = system,
+        run = run,
+        print_ = print_,
         call_py = call_py,
         get = get,
         cd = (lambda *path: os.chdir(os.path.join(*path))),
@@ -413,10 +423,10 @@
     for f in test.globs['__tear_downs']:
         f()
 
-class Server(BaseHTTPServer.HTTPServer):
+class Server(http.server.HTTPServer):
 
     def __init__(self, tree, *args):
-        BaseHTTPServer.HTTPServer.__init__(self, *args)
+        http.server.HTTPServer.__init__(self, *args)
         self.tree = os.path.abspath(tree)
 
     __run = True
@@ -427,14 +437,14 @@
     def handle_error(self, *_):
         self.__run = False
 
-class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
+class Handler(http.server.BaseHTTPRequestHandler):
 
     Server.__log = False
 
     def __init__(self, request, address, server):
         self.__server = server
         self.tree = server.tree
-        BaseHTTPServer.BaseHTTPRequestHandler.__init__(
+        http.server.BaseHTTPRequestHandler.__init__(
             self, request, address, server)
 
     def do_GET(self):
@@ -477,7 +487,7 @@
                     name += '/'
                 out.append('<a href="%s">%s</a><br>\n' % (name, name))
             out.append('</body></html>\n')
-            out = ''.join(out)
+            out = ''.join(out).encode()
             self.send_header('Content-Length', str(len(out)))
             self.send_header('Content-Type', 'text/html')
         else:
@@ -497,7 +507,7 @@
 
     def log_request(self, code):
         if self.__server.__log:
-            print '%s %s %s' % (self.command, code, self.path)
+            print('%s %s %s' % (self.command, code, self.path))
 
 def _run(tree, port):
     server_address = ('localhost', port)
@@ -515,7 +525,7 @@
                 return port
         finally:
             s.close()
-    raise RuntimeError, "Can't find port"
+    raise RuntimeError("Can't find port")
 
 def _start_server(tree, name=''):
     port = get_port()
@@ -530,7 +540,7 @@
 
 def stop_server(url, thread=None):
     try:
-        urllib2.urlopen(url+'__stop__')
+        urllib.request.urlopen(url+'__stop__')
     except Exception:
         pass
     if thread is not None:
@@ -546,7 +556,7 @@
             s.close()
             if up:
                 break
-        except socket.error, e:
+        except socket.error as e:
             if e[0] not in (errno.ECONNREFUSED, errno.ECONNRESET):
                 raise
             s.close()
@@ -559,7 +569,7 @@
             raise SystemError("Couln't stop server")
 
 def install(project, destination):
-    if not isinstance(destination, basestring):
+    if not isinstance(destination, str):
         destination = os.path.join(destination.globs['sample_buildout'],
                                    'eggs')
 
@@ -579,7 +589,7 @@
              ).write(dist.location)
 
 def install_develop(project, destination):
-    if not isinstance(destination, basestring):
+    if not isinstance(destination, str):
         destination = os.path.join(destination.globs['sample_buildout'],
                                    'develop-eggs')
 

Modified: zc.buildout/branches/python-3/src/zc/buildout/testrecipes.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/testrecipes.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/testrecipes.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -7,10 +7,10 @@
         self.options = options
 
     def install(self):
-        items = self.options.items()
+        items = list(self.options.items())
         items.sort()
         for option, value in items:
-            print "  %s=%r" % (option, value)
+            print("  %s=%r" % (option, value))
         return ()
 
     update = install

Modified: zc.buildout/branches/python-3/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/tests.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/tests.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -11,6 +11,8 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
+from zc.buildout.easy_install import setuptools_key
+
 import doctest
 from zope.testing import renormalizing
 import os
@@ -48,7 +50,7 @@
     ... parts =
     ... ''')
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/foo'
 
     >>> ls('develop-eggs')
@@ -76,7 +78,7 @@
     ... parts =
     ... ''')
 
-    >>> print system(join('bin', 'buildout')+' -vv'), # doctest: +ELLIPSIS
+    >>> run(join('bin', 'buildout')+' -vv') # doctest: +ELLIPSIS
     Installing...
     Develop: '/sample-buildout/foo'
     ...
@@ -88,7 +90,7 @@
     -  z3c.recipe.scripts.egg-link
     -  zc.recipe.egg.egg-link
 
-    >>> print system(join('bin', 'buildout')+' -vvv'), # doctest: +ELLIPSIS
+    >>> run(join('bin', 'buildout')+' -vvv') # doctest: +ELLIPSIS
     Installing...
     Develop: '/sample-buildout/foo'
     in: '/sample-buildout/foo'
@@ -126,10 +128,7 @@
     ... parts =
     ... x = ${buildout:y}
     ... y = ${buildout:z}
-    ... z = ${buildout:x}
-    ... ''')
-
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    ... z = ${runprint system(os.path.join(sample_buildout, 'bin', 'buildout'))
     ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
     While:
       Initializing.
@@ -151,7 +150,7 @@
     ... x = ${bui$ldout:y}
     ... ''')
 
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout'))
     While:
       Initializing.
       Getting section buildout.
@@ -168,7 +167,7 @@
     ... x = ${buildout:y{z}
     ... ''')
 
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout'))
     While:
       Initializing.
       Getting section buildout.
@@ -187,7 +186,7 @@
     ... x = ${parts}
     ... ''')
 
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout'))
     While:
       Initializing.
       Getting section buildout.
@@ -204,7 +203,7 @@
     ... x = ${buildout:y:z}
     ... ''')
 
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout'))
     While:
       Initializing.
       Getting section buildout.
@@ -221,7 +220,7 @@
     ... parts = x
     ... ''')
 
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout'))
     While:
       Installing.
       Getting section x.
@@ -239,7 +238,7 @@
     ... foo = 1
     ... ''')
 
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout'))
     While:
       Installing.
     Error: Missing option: x:recipe
@@ -288,7 +287,7 @@
     ...        samplez
     ... ''' % globals())
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/sampley'
     Develop: '/sample-buildout/samplez'
     Installing eggs.
@@ -321,7 +320,7 @@
 
 If we use the verbose switch, we can see where requirements are coming from:
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     We have a develop egg: zc.buildout 1.0.0
     We have the best distribution that satisfies 'setuptools'.
@@ -372,7 +371,7 @@
     ... eggs = samplea
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/sampley'
     Develop: '/sample-buildout/samplea'
     Develop: '/sample-buildout/sampleb'
@@ -420,7 +419,7 @@
 indicate the eggs from site-packages that have been selected.  You'll see
 we have two: demo 0.3 and demoneeded 1.1.
 
-    >>> print system(buildout+" -v"),
+    >>> run(buildout+" -v")
     Installing 'zc.buildout', 'setuptools'.
     We have a develop egg: zc.buildout V
     We have the best distribution that satisfies 'setuptools'.
@@ -506,14 +505,14 @@
     >>> os.chdir(sample_buildout)
     >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing debug.
 
 If we run the buildout again, we shoudn't get a message about
 uninstalling anything because the configuration hasn't changed.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Updating debug.
 """
@@ -577,7 +576,7 @@
     >>> write('demo', 'demo.py',
     ... '''
     ... def main():
-    ...     print 'Python 2.5'
+    ...     print('Python 2.5')
     ... ''')
 
     >>> write('buildout.cfg',
@@ -587,7 +586,7 @@
     ... parts =
     ... ''')
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/demo'
 
     >>> import zc.buildout.easy_install
@@ -597,7 +596,7 @@
     ...      ['demo'], ws, sys.executable, 'bin'))
     True
 
-    >>> print system(join('bin', 'demo')),
+    >>> run(join('bin', 'demo'))
     Python 2.5
 
 Now, finally, let's test _get_version:
@@ -616,7 +615,7 @@
     ... x = ${foo:bar}
     ... ''')
 
-    >>> print system(buildout + ' foo:bar=1 -vv'), # doctest: +ELLIPSIS
+    >>> run(buildout + ' foo:bar=1 -vv') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     ...
     [foo]
@@ -627,7 +626,7 @@
 
 def test_help():
     """
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')+' -h'),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout')+' -h')
     ... # doctest: +ELLIPSIS
     Usage: buildout [options] [assignments] [command [command arguments]]
     <BLANKLINE>
@@ -636,8 +635,7 @@
       -h, --help
     ...
 
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
-    ...              +' --help'),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout') +' --help')
     ... # doctest: +ELLIPSIS
     Usage: buildout [options] [assignments] [command [command arguments]]
     <BLANKLINE>
@@ -663,8 +661,7 @@
     ... ''')
 
     >>> os.chdir(d)
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
-    ...              + ' bootstrap'),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout') + ' bootstrap')
     Creating directory '/sample-bootstrap/bin'.
     Creating directory '/sample-bootstrap/parts'.
     Creating directory '/sample-bootstrap/eggs'.
@@ -690,15 +687,14 @@
     ... ''')
 
     >>> os.chdir(d)
-    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
-    ...              + ' bootstrap'),
+    >>> run(os.path.join(sample_buildout, 'bin', 'buildout') + ' bootstrap')
     Creating directory '/sample-bootstrap/bin'.
     Creating directory '/sample-bootstrap/parts'.
     Creating directory '/sample-bootstrap/eggs'.
     Creating directory '/sample-bootstrap/develop-eggs'.
     Generated script '/sample-bootstrap/bin/buildout'.
 
-    >>> print system(os.path.join('bin', 'buildout')),
+    >>> run(os.path.join('bin', 'buildout'))
     Unused options for buildout: 'scripts' 'eggs'.
 
     """
@@ -722,7 +718,7 @@
     ... parts =
     ... """)
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/foo'
 
     >>> ls('develop-eggs')
@@ -745,7 +741,7 @@
     ... parts =
     ... """)
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/foo'
     Develop: '/sample-buildout/bar'
 
@@ -763,7 +759,7 @@
     ... develop = bar
     ... parts =
     ... """)
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/bar'
 
 It is gone
@@ -780,7 +776,7 @@
     ... [buildout]
     ... parts =
     ... """)
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
 
 All gone
 
@@ -826,7 +822,7 @@
     ... parts =
     ... """)
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/foo'
 
 Now, if we generate a working set using the egg link, we will get a warning
@@ -845,7 +841,7 @@
     ...     ])]
     ['foox', 'setuptools']
 
-    >>> print handler
+    >>> print(handler)
     zc.buildout.easy_install WARNING
       Develop distribution: foox 0.0.0
     uses namespace packages but the distribution does not require setuptools.
@@ -863,7 +859,7 @@
     -  z3c.recipe.scripts.egg-link
     -  zc.recipe.egg.egg-link
 
-    >>> print 'START ->'; ls('eggs') # doctest: +ELLIPSIS
+    >>> print('START ->'); ls('eggs') # doctest: +ELLIPSIS
     START...
     -  foox-0.0.0-py2.4.egg
     ...
@@ -878,7 +874,7 @@
     ...     ])]
     ['foox', 'setuptools']
 
-    >>> print handler,
+    >>> print_(handler.decode())
 
 We get the same behavior if the it is a depedency that uses a
 namespace package.
@@ -899,7 +895,7 @@
     ... parts =
     ... """)
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/foo'
     Develop: '/sample-buildout/bar'
 
@@ -911,7 +907,7 @@
     ...     ])]
     ['bar', 'foox', 'setuptools']
 
-    >>> print handler,
+    >>> print_(handler.decode())
     zc.buildout.easy_install WARNING
       Develop distribution: foox 0.0.0
     uses namespace packages but the distribution does not require setuptools.
@@ -987,9 +983,9 @@
     ... class Install:
     ...     def __init__(*args): pass
     ...     def install(self):
-    ...         print 'installing'
+    ...         print('installing')
     ...         return ()
-    ... def uninstall(name, options): print 'uninstalling'
+    ... def uninstall(name, options): print('uninstalling')
     ... ''')
 
     >>> write('buildout.cfg', '''
@@ -1000,7 +996,7 @@
     ... recipe = recipes:demo
     ... ''')
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/recipes'
     Installing demo.
     installing
@@ -1015,7 +1011,7 @@
     ... x = 1
     ... ''')
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/recipes'
     Uninstalling demo.
     Running uninstall recipe.
@@ -1030,7 +1026,7 @@
     ... parts =
     ... ''')
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/recipes'
     Uninstalling demo.
     Running uninstall recipe.
@@ -1045,7 +1041,7 @@
     >>> write('demo', 'demo.py',
     ... """
     ... def ext(buildout):
-    ...     print 'ext', list(buildout)
+    ...     print('ext', list(buildout))
     ... """)
 
     >>> write('demo', 'setup.py',
@@ -1070,7 +1066,7 @@
     ... offline = true
     ... """)
 
-    >>> print system(join(sample_buildout, 'bin', 'buildout')),
+    >>> run(join(sample_buildout, 'bin', 'buildout'))
     ext ['buildout']
 
 
@@ -1108,20 +1104,20 @@
     ... ''')
 
 
-    >>> print system(join(sample_buildout, 'bin', 'buildout')),
+    >>> run(join(sample_buildout, 'bin', 'buildout'))
     Develop: '/sample-buildout/recipe'
     Installing foo.
 
     >>> mkdir('recipe', '.svn')
     >>> mkdir('recipe', 'CVS')
-    >>> print system(join(sample_buildout, 'bin', 'buildout')),
+    >>> run(join(sample_buildout, 'bin', 'buildout'))
     Develop: '/sample-buildout/recipe'
     Updating foo.
 
     >>> write('recipe', '.svn', 'x', '1')
     >>> write('recipe', 'CVS', 'x', '1')
 
-    >>> print system(join(sample_buildout, 'bin', 'buildout')),
+    >>> run(join(sample_buildout, 'bin', 'buildout'))
     Develop: '/sample-buildout/recipe'
     Updating foo.
 
@@ -1160,7 +1156,7 @@
     ... ''')
 
 
-    >>> print system(join(sample_buildout, 'bin', 'buildout')),
+    >>> run(join(sample_buildout, 'bin', 'buildout'))
     Develop: '/sample-buildout/recipe'
     Installing foo.
 
@@ -1177,7 +1173,7 @@
 
     >>> remove('recipe', 'some-file')
 
-    >>> print system(join(sample_buildout, 'bin', 'buildout')),
+    >>> run(join(sample_buildout, 'bin', 'buildout'))
     Develop: '/sample-buildout/recipe'
     Updating foo.
 
@@ -1185,7 +1181,7 @@
 
 def o_option_sets_offline():
     """
-    >>> print system(join(sample_buildout, 'bin', 'buildout')+' -vvo'),
+    >>> run(join(sample_buildout, 'bin', 'buildout')+' -vvo')
     ... # doctest: +ELLIPSIS
     <BLANKLINE>
     ...
@@ -1206,7 +1202,7 @@
     ... class Recipe:
     ...     def __init__(*a): pass
     ...     def install(self):
-    ...         print 'recipe v1'
+    ...         print('recipe v1')
     ...         return ()
     ...     update = install
     ... ''')
@@ -1221,7 +1217,7 @@
 
     >>> write('recipe', 'README', '')
 
-    >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup recipe bdist_egg') # doctest: +ELLIPSIS
     Running setup script 'recipe/setup.py'.
     ...
 
@@ -1239,7 +1235,7 @@
     ... recipe = recipe
     ... ''' % join('recipe', 'dist'))
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Getting distribution for 'recipe'.
     Got recipe 1.
     Installing foo.
@@ -1252,7 +1248,7 @@
     ... class Recipe:
     ...     def __init__(*a): pass
     ...     def install(self):
-    ...         print 'recipe v2'
+    ...         print('recipe v2')
     ...         return ()
     ...     update = install
     ... ''')
@@ -1266,25 +1262,25 @@
     ... ''')
 
 
-    >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup recipe bdist_egg') # doctest: +ELLIPSIS
     Running setup script 'recipe/setup.py'.
     ...
 
 We won't get the update if we specify -N:
 
-    >>> print system(buildout+' -N'),
+    >>> run(buildout+' -N')
     Updating foo.
     recipe v1
 
 or if we use -o:
 
-    >>> print system(buildout+' -o'),
+    >>> run(buildout+' -o')
     Updating foo.
     recipe v1
 
 But we will if we use neither of these:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Getting distribution for 'recipe'.
     Got recipe 2.
     Uninstalling foo.
@@ -1303,7 +1299,7 @@
     ... recipe = recipe ==1
     ... ''' % join('recipe', 'dist'))
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Uninstalling foo.
     Installing foo.
     recipe v1
@@ -1352,11 +1348,11 @@
     ... recipe = recipe
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipe'
     Installing foo.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipe'
     Updating foo.
 
@@ -1388,7 +1384,7 @@
     ...     ['demo==0.2'], dest,
     ...     links=[link_server], index=link_server+'index/')
 
-    >>> print handler # doctest: +ELLIPSIS
+    >>> print(handler) # doctest: +ELLIPSIS
     zc.buildout.easy_install DEBUG
       Installing 'demo==0.2'.
     zc.buildout.easy_install DEBUG
@@ -1434,7 +1430,7 @@
     ... recipe = recipes:mkdir
     ... ''')
 
-    >>> print system(buildout), # doctest: +ELLIPSIS
+    >>> run(buildout) # doctest: +ELLIPSIS
     Develop: '/sample-buildout/recipes'
     While:
       Installing.
@@ -1486,7 +1482,7 @@
     ... z = 1
     ... """)
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/.'
     Unused options for buildout: 'a'.
     Installing foo.
@@ -1554,19 +1550,19 @@
     ... recipe = recipes:clean
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing p1.
     Installing p2.
     Installing p3.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Updating p1.
     Updating p2.
     Installing p3.
 
-    >>> print system(buildout+' buildout:parts='),
+    >>> run(buildout+' buildout:parts=')
     Develop: '/sample-buildout/recipes'
     Uninstalling p2.
     Uninstalling p1.
@@ -1592,20 +1588,20 @@
     ... recipe = recipes:clean
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing p1.
     Installing p2.
     Installing p3.
     Installing p4.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Updating p1.
     Updating p2.
     Updating p3.
 
-    >>> print system(buildout+' buildout:parts='),
+    >>> run(buildout+' buildout:parts=')
     Develop: '/sample-buildout/recipes'
     Uninstalling p2.
     Uninstalling p1.
@@ -1633,7 +1629,7 @@
     ... recipe = recipes:clean
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Installing p1.
     Installing p2.
@@ -1660,7 +1656,7 @@
     ... x = 1
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling p4.
     Updating p1.
@@ -1684,7 +1680,7 @@
     ... recipe = recipes:clean
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Uninstalling p1.
     Installing p1.
@@ -1717,7 +1713,7 @@
     ...     zip_safe=False)
     ... ''')
 
-    >>> print system(buildout+' setup badegg sdist'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup badegg sdist') # doctest: +ELLIPSIS
     Running setup script 'badegg/setup.py'.
     ...
 
@@ -1739,7 +1735,7 @@
     ... scripts = buildout=bo
     ... ''' % globals())
 
-    >>> print system(buildout);print 'X' # doctest: +ELLIPSIS
+    >>> print(system(buildout));print('X') # doctest: +ELLIPSIS
     Installing eggs.
     Getting distribution for 'badegg'.
     Got badegg 1.
@@ -1801,7 +1797,7 @@
     ... eggs = demo
     ... ''' % globals())
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Installing x.
     Getting distribution for 'demo'.
     Got demo 0.4c1.
@@ -1809,7 +1805,7 @@
     Got demoneeded 1.2c1.
     Generated script '/sample-buildout/bin/demo'.
 
-    >>> print system(join('bin', 'demo')),
+    >>> run(join('bin', 'demo'))
     4 2
 
     >>> write('buildout.cfg',
@@ -1823,14 +1819,14 @@
     ... eggs = demo ==0.1
     ... ''' % globals())
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Uninstalling x.
     Installing x.
     Getting distribution for 'demo==0.1'.
     Got demo 0.1.
     Generated script '/sample-buildout/bin/demo'.
 
-    >>> print system(join('bin', 'demo')),
+    >>> run(join('bin', 'demo'))
     1 2
     """
 
@@ -1852,9 +1848,10 @@
 version 0.3 and demoneeded version 1.1.
 
     >>> py_path = make_py_with_system_install(make_py, sample_eggs)
-    >>> print call_py(
+    >>> print_(call_py(
     ...     py_path,
-    ...     "import tellmy.version; print tellmy.version.__version__"),
+    ...     "import tellmy.version; print(tellmy.version.__version__)"
+    ...     ).decode())
     1.1
 
 Now here's a setup that would expose the bug, using the
@@ -1869,7 +1866,7 @@
     >>> for dist in workingset:
     ...     res = str(dist)
     ...     if res.startswith('tellmy.version'):
-    ...         print res
+    ...         print(res)
     ...         break
     tellmy.version 1.0
 
@@ -1889,9 +1886,10 @@
 tellmy.version 1.1, and tellmy.fortune 1.0.  tellmy.version 1.1 is installed.
 
     >>> py_path = make_py_with_system_install(make_py, sample_eggs)
-    >>> print call_py(
+    >>> print_(call_py(
     ...     py_path,
-    ...     "import tellmy.version; print tellmy.version.__version__")
+    ...     "import tellmy.version; print(tellmy.version.__version__)"
+    ...     ).decode())
     1.1
     <BLANKLINE>
 
@@ -1918,12 +1916,12 @@
     ...        demo
     ... script-initialization =
     ...     import tellmy.version
-    ...     print tellmy.version.__version__
+    ...     print(tellmy.version.__version__)
     ...     import tellmy.fortune
-    ...     print tellmy.fortune.__version__
+    ...     print(tellmy.fortune.__version__)
     ... ''' % globals())
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Installing eggs.
     Getting distribution for 'tellmy.version==1.0'.
     Got tellmy.version 1.0.
@@ -1935,7 +1933,6 @@
     Got demoneeded 1.2c1.
     Generated script '/sample-buildout/bin/demo'.
     Generated interpreter '/sample-buildout/bin/py'.
-    <BLANKLINE>
 
 Finally, we are ready to see if it worked.  Prior to the bug fix that
 this tests, the results of both calls below was the following::
@@ -1950,20 +1947,19 @@
 we could not import tellmy.fortune at all.  The following are the correct
 results for the interpreter and for the script.
 
-    >>> print call_py(
+    >>> print(call_py(
     ...     join('bin', 'py'),
     ...     "import tellmy.version; " +
-    ...     "print tellmy.version.__version__; " +
+    ...     "print(tellmy.version.__version__); " +
     ...     "import tellmy.fortune; " +
-    ...     "print tellmy.fortune.__version__") # doctest: +ELLIPSIS
+    ...     "print(tellmy.fortune.__version__)")) # doctest: +ELLIPSIS
     1.0
     1.0...
 
-    >>> print system(join('bin', 'demo'))
+    >>> run(join('bin', 'demo'))
     1.0
     1.0
     4 2
-    <BLANKLINE>
     """
 
 def handle_sys_path_version_hack():
@@ -2003,11 +1999,11 @@
     ...             " name='tellmy.version',\n"
     ...             " package_dir = {'': 'src'},\n"
     ...             " packages = ['tellmy', 'tellmy.version'],\n"
-    ...             " install_requires = ['setuptools'],\n"
+    ...             " install_requires = [%(setuptools_key)r],\n"
     ...             " namespace_packages=['tellmy'],\n"
     ...             " zip_safe=True, version=__version__,\n"
     ...             " author='bob', url='bob', author_email='bob')\n"
-    ...             )
+    ...             % globals())
     ...         zc.buildout.testing.sdist(tmp, sample_eggs)
     ...         if version == '1.0':
     ...             # We install the 1.0 version in site packages the way a
@@ -2015,9 +2011,10 @@
     ...             zc.buildout.testing.sys_install(tmp, site_packages_path)
     ...     finally:
     ...         shutil.rmtree(tmp)
-    >>> print call_py(
+    >>> print_(call_py(
     ...     py_path,
-    ...     "import tellmy.version; print tellmy.version.__version__")
+    ...     "import tellmy.version; print(tellmy.version.__version__)"
+    ...     ).decode())
     1.0
     <BLANKLINE>
     >>> write('buildout.cfg',
@@ -2055,11 +2052,10 @@
 the comment leading up to zc.buildout.easy_install._easy_install_cmd).
 Now the install works correctly, as seen here.
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Installing eggs.
     Getting distribution for 'tellmy.version==1.1'.
     Got tellmy.version 1.1.
-    <BLANKLINE>
 
     """
 
@@ -2344,7 +2340,7 @@
 site-packages are at the end.  They were not before this bugfix.
 
     >>> test = 'import pprint, sys; pprint.pprint(sys.path[-4:])'
-    >>> print call_py(join(interpreter_bin_dir, 'py'), test)
+    >>> print(call_py(join(interpreter_bin_dir, 'py'), test))
     ['/interpreter/eggs/other-1.0-pyN.N.egg',
      '/interpreter/eggs/demoneeded-1.1-pyN.N.egg',
      '/executable_buildout/eggs/setuptools-0.0-pyN.N.egg',
@@ -2374,7 +2370,7 @@
     >>> test = (
     ...     "import subprocess, sys; subprocess.call("
     ...     "[sys.executable, '-c', "
-    ...     "'import eggrecipedemo; print eggrecipedemo.x'])")
+    ...     "'import eggrecipedemo; print(eggrecipedemo.x)'])")
     >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
     ...     interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
     ...     reqs=['demo'], interpreter='py',
@@ -2382,13 +2378,12 @@
 
 This works for the script.
 
-    >>> print system(join(interpreter_bin_dir, 'demo'))
+    >>> run(join(interpreter_bin_dir, 'demo'))
     3
-    <BLANKLINE>
 
 This also works for the generated interpreter.
 
-    >>> print call_py(join(interpreter_bin_dir, 'py'), test)
+    >>> print(call_py(join(interpreter_bin_dir, 'py'), test))
     3
     <BLANKLINE>
 
@@ -2411,7 +2406,7 @@
 You can also see, actually more easily than in the other example, that we
 have the desired eggs available.
 
-    >>> print system(join(interpreter_bin_dir, 'demo')), # doctest: +ELLIPSIS
+    >>> run(join(interpreter_bin_dir, 'demo')) # doctest: +ELLIPSIS
     ['',
      '/interpreter/parts/interpreter',
      '/sample-buildout/foo',
@@ -2421,7 +2416,8 @@
 
 This also works for the generated interpreter, with identical results.
 
-    >>> print call_py(join(interpreter_bin_dir, 'py'), test),
+    >>> print_(call_py(join(interpreter_bin_dir, 'py'), test
+    ... ).decode())
     ... # doctest: +ELLIPSIS
     ['',
      '/interpreter/parts/interpreter',
@@ -2514,12 +2510,11 @@
 
 Now, it is handled smoothly.
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/recipes'
     Getting distribution for 'demoneeded==1.2c1'.
     Got demoneeded 1.2c1.
     Installing dummy.
-    <BLANKLINE>
 
 Here's the same story with a namespace package, which has some additional
 complications behind the scenes.  First, a recipe, in the "tellmy" namespace.
@@ -2547,12 +2542,12 @@
     ... setup(
     ...     name="tellmy.recipes",
     ...     packages=['tellmy', 'tellmy.recipes'],
-    ...     install_requires=['setuptools'],
+    ...     install_requires=[%(setuptools_key)r],
     ...     namespace_packages=['tellmy'],
     ...     entry_points = {'zc.buildout':
     ...                     ['dummy = tellmy.recipes.dummy:Dummy']},
     ...     )
-    ... ''')
+    ... ''' % globals())
 
 Now, a buildout that uses it.
 
@@ -2575,12 +2570,11 @@
 
 Now we actually run the buildout.
 
-    >>> print system(buildout)
+    >>> run(buildout)
     Develop: '/sample-buildout/ns'
     Develop: '/sample-buildout/recipes'
     Uninstalling dummy.
     Installing dummy.
-    <BLANKLINE>
 
     """
 
@@ -2592,8 +2586,8 @@
         ...     p = subprocess.Popen(s, stdin=subprocess.PIPE,
         ...                 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
         ...     p.stdin.close()
-        ...     print p.stdout.read()
-        ...     print 'Exit:', bool(p.wait())
+        ...     print(p.stdout.read())
+        ...     print('Exit:', bool(p.wait()))
 
         >>> call(buildout)
         <BLANKLINE>
@@ -2664,11 +2658,11 @@
     ... import os
     ... class Bad:
     ...     def __init__(self, *_):
-    ...         print os.getcwd()
+    ...         print(os.getcwd())
     ...     def install(self):
-    ...         print os.getcwd()
+    ...         print(os.getcwd())
     ...         os.chdir('bad_start')
-    ...         print os.getcwd()
+    ...         print(os.getcwd())
     ...         return ()
     ... ''')
 
@@ -2691,8 +2685,8 @@
     ... ''')
 
     >>> os.chdir('bad_start')
-    >>> print system(join(sample_buildout, 'bin', 'buildout')
-    ...              +' -c '+join(sample_buildout, 'buildout.cfg')),
+    >>> run(join(sample_buildout, 'bin', 'buildout')
+    ...              +' -c '+join(sample_buildout, 'buildout.cfg'))
     Develop: '/sample-buildout/.'
     /sample-buildout
     /sample-buildout
@@ -2721,7 +2715,7 @@
 
 
     >>> for dist in ws:
-    ...     print dist
+    ...     print(dist)
     demo 0.2
     demoneeded 1.1
 
@@ -2734,7 +2728,7 @@
 def bug_75607_buildout_should_not_run_if_it_creates_an_empty_buildout_cfg():
     """
     >>> remove('buildout.cfg')
-    >>> print system(buildout),
+    >>> run(buildout)
     While:
       Initializing.
     Error: Couldn't open /sample-buildout/buildout.cfg
@@ -2775,7 +2769,7 @@
     ... eggs = pack0
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/pack0'
     Develop: '/sample-buildout/pack1'
     Develop: '/sample-buildout/pack2'
@@ -2791,7 +2785,7 @@
 
     However, if we run in verbose mode, we can see why packages were included:
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     We have a develop egg: zc.buildout 1.0.0
     We have the best distribution that satisfies 'setuptools'.
@@ -2856,7 +2850,7 @@
     ...             },
     ...       )
     ... ''')
-    >>> print system(buildout+' setup '+src+' bdist_egg'),
+    >>> run(buildout+' setup '+src+' bdist_egg')
     ... # doctest: +ELLIPSIS
     Running setup ...
     creating 'dist/wackyextension-1-...
@@ -2880,7 +2874,7 @@
 When we run the buildout. it will load the extension from the dist
 directory and then use the wacky extension to load the demo package
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Getting distribution for 'wackyextension'.
     Got wackyextension 1.
     Installing demo.
@@ -2902,7 +2896,7 @@
     ... setup(name='foo')
     ... ''')
 
-    >>> print system(buildout+' setup test bdist_egg'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup test bdist_egg') # doctest: +ELLIPSIS
     Running setup script 'test/setup.py'.
     ...
 
@@ -2963,9 +2957,9 @@
         )
 
     if dist.extras:
-        print 'downloaded', dist.version
+        print('downloaded', dist.version)
     else:
-        print 'had', dist.version
+        print('had', dist.version)
     sys.path_importer_cache.clear()
 
 def prefer_final():
@@ -3082,7 +3076,7 @@
     ... eggs = demo
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     ...
     Picked: demo = 0.4c1
@@ -3104,7 +3098,7 @@
     ... eggs = demo
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     ...
     Picked: demo = 0.4c1
@@ -3126,7 +3120,7 @@
     ... eggs = demo
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing 'zc.buildout', 'setuptools'.
     ...
     Picked: demo = 0.3
@@ -3147,7 +3141,7 @@
     ... eggs = demo
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     While:
       Initializing.
     Error: Invalid value for prefer-final option: no
@@ -3181,7 +3175,7 @@
     ... recipe = demorecipe
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing ...
     Picked: demoextension = 1.0
     ...
@@ -3205,7 +3199,7 @@
     ... recipe = demorecipe
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing ...
     Picked: demoextension = 1.0
     ...
@@ -3227,7 +3221,7 @@
     ... recipe = demorecipe
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     Installing ...
     Picked: demoextension = 1.1b1
     ...
@@ -3248,7 +3242,7 @@
     ... recipe = demorecipe
     ... ''' % globals())
 
-    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    >>> run(buildout+' -v') # doctest: +ELLIPSIS
     While:
       Initializing.
     Error: Invalid value for accept-buildout-test-releases option: no
@@ -3278,7 +3272,7 @@
     ... parts =
     ... ''')
 
-    >>> print system(join('bin', 'buildout')),
+    >>> run(join('bin', 'buildout'))
     Develop: '/sample-buildout/foo'
 
     >>> ls('develop-eggs')
@@ -3329,7 +3323,7 @@
     ...         pkg_resources.Requirement.parse('setuptools')).version,
     ...        distribute_version))
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Installing foo.
     Getting distribution for 'foo==1'.
     Got foo 1.
@@ -3357,11 +3351,11 @@
     >>> write('t.py',
     ... '''
     ... import eggrecipedemo, eggrecipedemoneeded
-    ... print eggrecipedemo.main.func_code.co_filename
-    ... print eggrecipedemoneeded.f.func_code.co_filename
+    ... print(eggrecipedemo.main.func_code.co_filename)
+    ... print(eggrecipedemoneeded.f.func_code.co_filename)
     ... ''')
 
-    >>> print system(join('bin', 'py')+ ' t.py'),
+    >>> run(join('bin', 'py')+ ' t.py')
     /sample-buildout/eggs/demo-0.4c1-py2.4.egg/eggrecipedemo.py
     /sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg/eggrecipedemoneeded.py
 
@@ -3384,7 +3378,7 @@
     ... eggs-directory = ${buildout:directory}/develop-eggs
     ... parts =
     ... ''' % globals())
-    >>> print system(buildout),
+    >>> run(buildout)
 
     """
 
@@ -3415,7 +3409,7 @@
 
     We can see that both eggs were found:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/sampley'
     Develop: '/sample-buildout/samplez'
     Installing eggs.
@@ -3447,7 +3441,7 @@
     We should get one of the eggs, and a warning for the pattern that
     did not match anything.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Develop: '/sample-buildout/samplea'
     Couldn't develop '/sample-buildout/grumble*' (not found)
     Installing eggs.
@@ -3502,7 +3496,7 @@
     ... <= p1
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Installing p1.
       foo='1\n2 b'
       recipe='zc.buildout:debug'
@@ -3542,7 +3536,7 @@
     ... x = ${buildout:bar-option} ${buildout:foo-option}
     ... ''')
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Installing p.
       recipe='zc.buildout:debug'
       x='bar\nbaz foo\nham'
@@ -3569,7 +3563,7 @@
     ... <= p1
     ... ''')
 
-    >>> print system(buildout+' buildout:parts+=p2 p1:foo+=bar'),
+    >>> run(buildout+' buildout:parts+=p2 p1:foo+=bar')
     Installing p1.
       foo='1 a\nb\nbar'
       recipe='zc.buildout:debug'
@@ -3587,6 +3581,7 @@
 
 def create_sample_namespace_eggs(dest, site_packages_path=None):
     from zc.buildout.testing import write, mkdir
+    setuptools_key_ = setuptools_key
     for pkg, version in (('version', '1.0'), ('version', '1.1'),
                          ('fortune', '1.0')):
         tmp = tempfile.mkdtemp()
@@ -3607,7 +3602,7 @@
                 " name='tellmy.%(pkg)s',\n"
                 " package_dir = {'': 'src'},\n"
                 " packages = ['tellmy', 'tellmy.%(pkg)s'],\n"
-                " install_requires = ['setuptools'],\n"
+                " install_requires = [%(setuptools_key_)r],\n"
                 " namespace_packages=['tellmy'],\n"
                 " zip_safe=True, version=%(version)r,\n"
                 " author='bob', url='bob', author_email='bob')\n"
@@ -3704,7 +3699,7 @@
         tmp, 'eggrecipedemo.py',
         'import eggrecipedemoneeded\n'
         'x=%s\n'
-        'def main(): print x, eggrecipedemoneeded.y\n'
+        'def main(): print(x), eggrecipedemoneeded.y\n'
         % minor_version)
     write(
         tmp, 'setup.py',
@@ -3791,7 +3786,7 @@
 from distutils.core import setup, Extension
 
 if os.environ.get('test-variable'):
-    print "Have environment test-variable:", os.environ['test-variable']
+    print("Have environment test-variable:", os.environ['test-variable'])
 
 setup(name = "extdemo", version = "%s", url="http://www.zope.org",
       author="Demo", author_email="demo at demo.com",
@@ -3841,15 +3836,19 @@
         zip = zipfile.ZipFile(dest, 'a')
         zip.writestr(
             'EGG-INFO/PKG-INFO',
-            zip.read('EGG-INFO/PKG-INFO').replace("Version: %s" % oldver,
-                                                  "Version: %s" % version)
+            zip.read('EGG-INFO/PKG-INFO').replace(
+                ("Version: %s" % oldver).encode(),
+                ("Version: %s" % version).encode(),
+                )
             )
         zip.close()
     else:
         shutil.copytree(dist.location, dest)
         info_path = os.path.join(dest, 'EGG-INFO', 'PKG-INFO')
-        info = open(info_path).read().replace("Version: %s" % oldver,
-                                              "Version: %s" % version)
+        info = open(info_path).read().replace(
+            ("Version: %s" % oldver),
+            ("Version: %s" % version),
+            )
         open(info_path, 'w').write(info)
 
 def getWorkingSetWithBuildoutEgg(test):
@@ -3871,7 +3870,7 @@
             '-q', 'bdist_egg', '-d', eggs,
             dict(os.environ,
                  PYTHONPATH=pkg_resources.working_set.find(
-                               pkg_resources.Requirement.parse('setuptools')
+                               pkg_resources.Requirement.parse(setuptools_key)
                                ).location,
                  ),
             ) == 0
@@ -3897,12 +3896,8 @@
     makeNewRelease('zc.buildout', ws, new_releases)
     makeNewRelease('zc.buildout', ws, new_releases, '100.0b1')
     os.mkdir(os.path.join(new_releases, 'zc.buildout'))
-    if zc.buildout.easy_install.is_distribute:
-        makeNewRelease('distribute', ws, new_releases)
-        os.mkdir(os.path.join(new_releases, 'distribute'))
-    else:
-        makeNewRelease('setuptools', ws, new_releases)
-        os.mkdir(os.path.join(new_releases, 'setuptools'))
+    makeNewRelease(setuptools_key, ws, new_releases)
+    os.mkdir(os.path.join(new_releases, setuptools_key))
 
 def bootstrapSetup(test):
     easy_install_SetUp(test)

Modified: zc.buildout/branches/python-3/src/zc/buildout/testselectingpython.py
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/testselectingpython.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/testselectingpython.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -11,8 +11,10 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
+from zope.testing import renormalizing
+from zc.buildout.easy_install import setuptools_key
+
 import os, re, subprocess, sys, textwrap, unittest, doctest
-from zope.testing import renormalizing
 import zc.buildout.tests
 import zc.buildout.testing
 
@@ -60,12 +62,12 @@
         executable_parts = os.path.join(executable_dir, 'parts')
         test.globs['mkdir'](executable_parts)
         ws = zc.buildout.easy_install.install(
-            ['setuptools'], executable_dir,
+            [setuptools_key], executable_dir,
             index='http://www.python.org/pypi/',
             always_unzip=True, executable=other_executable)
         zc.buildout.easy_install.sitepackage_safe_scripts(
             executable_dir, ws, other_executable, executable_parts,
-            reqs=['setuptools'], interpreter='py')
+            reqs=[setuptools_key], interpreter='py')
         original_executable = other_executable
         other_executable = os.path.join(executable_dir, 'py')
         assert not subprocess.call(

Modified: zc.buildout/branches/python-3/src/zc/buildout/update.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/update.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/update.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -44,7 +44,7 @@
     ...     def install(self):
     ...         for project in 'zc.buildout', 'setuptools':
     ...             req = pkg_resources.Requirement.parse(project)
-    ...             print project, pkg_resources.working_set.find(req).version
+    ...             print(project, pkg_resources.working_set.find(req).version)
     ...         return ()
     ...     update = install
     ... """)
@@ -64,7 +64,7 @@
 Now if we run the buildout, the buildout will upgrade itself to the
 new versions found in new releases:
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Getting distribution for 'zc.buildout'.
     Got zc.buildout 99.99.
     Getting distribution for 'setuptools'.
@@ -140,7 +140,7 @@
 
 Now we can see that we actually "upgrade" to an earlier version.
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Upgraded:
       zc.buildout version 1.0.0,
       setuptools version 0.6;
@@ -167,7 +167,7 @@
     ... recipe = showversions
     ... """ % dict(new_releases=new_releases))
 
-    >>> print system(buildout+' -o'),
+    >>> run(buildout+' -o')
     Develop: '/sample-buildout/showversions'
     Updating show-versions.
     zc.buildout 1.0.0
@@ -175,7 +175,7 @@
 
 Or in non-newest mode:
 
-    >>> print system(buildout+' -N'),
+    >>> run(buildout+' -N')
     Develop: '/sample-buildout/showversions'
     Updating show-versions.
     zc.buildout 1.0.0
@@ -195,7 +195,7 @@
     ... """ % dict(new_releases=new_releases))
 
     >>> cd(sample_buildout2)
-    >>> print system(buildout),
+    >>> run(buildout)
     Creating directory '/sample_buildout2/bin'.
     Creating directory '/sample_buildout2/parts'.
     Creating directory '/sample_buildout2/eggs'.
@@ -230,8 +230,7 @@
     ... recipe = showversions
     ... """ % dict(new_releases=new_releases))
 
-    >>> print system(buildout +
-    ...              ' buildout:accept-buildout-test-releases=true'),
+    >>> run(buildout + ' buildout:accept-buildout-test-releases=true')
     ... # doctest: +NORMALIZE_WHITESPACE
     Getting distribution for 'zc.buildout'.
     Got zc.buildout 100.0b1.
@@ -254,12 +253,12 @@
     >>> import sys
     >>> if sys.platform.startswith('win'):
     ...     buildout_script += '-script.py'
-    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    >>> print(open(buildout_script).read()) # doctest: +ELLIPSIS
     #...
     sys.argv.insert(1, 'buildout:accept-buildout-test-releases=true')
-    print ('NOTE: Accepting early releases of build system packages.  Rerun '
-           'bootstrap without --accept-buildout-test-releases (-t) to return to '
-           'default behavior.')
+    print('NOTE: Accepting early releases of build system packages.  Rerun '
+          'bootstrap without --accept-buildout-test-releases (-t) to return to '
+          'default behavior.')
     ...
 
 If the update process for buildout or setuptools fails the error should be

Modified: zc.buildout/branches/python-3/src/zc/buildout/virtualenv.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/virtualenv.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/virtualenv.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -76,7 +76,7 @@
     ...     py_file.write(line)
     ...     if line.startswith('environ = os.environ.copy()'):
     ...         py_file.write(extra)
-    ...         print 'Rewritten.'
+    ...         print('Rewritten.')
     ...
     Rewritten.
     >>> py_file.close()
@@ -114,14 +114,15 @@
     ...     sys.meta_path.append(ImportHook)
     ... ''' % (py_path,))
     >>> sitecustomize_file.close()
-    >>> print call_py(
+    >>> print(call_py(
     ...     _safe_arg(py_path),
-    ...     "import ConfigParser")
+    ...     "import ConfigParser"))
     <BLANKLINE>
-    >>> print 'X'; print call_py(
+
+    >>> print('X'); print(call_py(
     ...     _safe_arg(py_path),
     ...     "import ConfigParser",
-    ...     '-S') # doctest: +ELLIPSIS
+    ...     '-S')) # doctest: +ELLIPSIS
     X...Traceback (most recent call last):
       ...
     ImportError: No module named ConfigParser
@@ -157,9 +158,9 @@
     ... parts =
     ... ''')
     >>> write('bootstrap.py', open(bootstrap_py).read())
-    >>> print 'X'; print system(
+    >>> print('X'); run(
     ...     _safe_arg(py_path)+' '+
-    ...     'bootstrap.py'); print 'X' # doctest: +ELLIPSIS
+    ...     'bootstrap.py'); print('X') # doctest: +ELLIPSIS
     X...
     Generated script '/broken_S/bin/buildout'.
     ...
@@ -208,7 +209,7 @@
     ... eggs = demo
     ... ''' % globals())
 
-    >>> print system(buildout), # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+    >>> run(buildout) # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
     Installing eggs.
     Getting distribution for 'demo'.
     Got demo 0.4c1.
@@ -232,19 +233,19 @@
 you don't want those warnings for those particular recipes that use the
 new features, you can use the "-s" option to squelch the warnings.
 
-    >>> print system(buildout + ' -s'),
+    >>> run(buildout + ' -s')
     Updating eggs.
 
 A lower verbosity (one or more -q options) also quiets the warning.
 
-    >>> print system(buildout + ' -q'),
+    >>> run(buildout + ' -q')
 
 Notice that, as we saw before with bin/buildout, the generated scripts
 are old-style, because the new-style feature gracefully degrades to the
 previous implementation when it encounters an executable with a broken
 dash-S.
 
-    >>> print 'X'; cat('bin', 'py') # doctest: +ELLIPSIS
+    >>> print('X'); cat('bin', 'py') # doctest: +ELLIPSIS
     X...
     <BLANKLINE>
     import sys

Modified: zc.buildout/branches/python-3/src/zc/buildout/windows.txt
===================================================================
--- zc.buildout/branches/python-3/src/zc/buildout/windows.txt	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/src/zc/buildout/windows.txt	2011-03-16 13:51:30 UTC (rev 120975)
@@ -21,7 +21,7 @@
     ...              name)
     ...
     ...     def install(self):
-    ...         print "can't remove read only files"
+    ...         print("can't remove read only files")
     ...         if not os.path.exists (self.location):
     ...             os.makedirs (self.location)
     ...
@@ -43,7 +43,7 @@
 
     >>> write('recipe', 'README', '')
 
-    >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
+    >>> run(buildout+' setup recipe bdist_egg') # doctest: +ELLIPSIS
     Running setup script 'recipe/setup.py'.
     ...
 
@@ -59,7 +59,7 @@
     ... recipe = spam
     ... ''' % join('recipe', 'dist'))
 
-    >>> print system(buildout),
+    >>> run(buildout)
     Getting distribution for 'spam'.
     Got spam 1.
     Installing foo.

Modified: zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py
===================================================================
--- zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -23,7 +23,7 @@
 
     def __init__(self, buildout, name, options):
         if 'extends' in options:
-            for key, value in buildout[options['extends']].items():
+            for key, value in list(buildout[options['extends']].items()):
                 options.setdefault(key, value)
         super(Base, self).__init__(buildout, name, options)
         self.default_eggs = '' # Disables feature from zc.recipe.egg.

Modified: zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py
===================================================================
--- zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -223,7 +223,7 @@
 Let's look at the site.py that was generated:
 
     >>> import sys
-    >>> sys.stdout.write('#'); cat(sample_buildout, 'parts', 'py', 'site.py')
+    >>> print_('#'); cat(sample_buildout, 'parts', 'py', 'site.py')
     ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
     #...
     def addsitepackages(known_paths):

Modified: zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/custom.py
===================================================================
--- zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/custom.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/custom.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -62,7 +62,7 @@
             self.environment = buildout[environment_section]
         else:
             self.environment = {}
-        environment_data = self.environment.items()
+        environment_data = list(self.environment.items())
         environment_data.sort()
         options['_environment-data'] = repr(environment_data)
 
@@ -101,7 +101,7 @@
 
     def _set_environment(self):
         self._saved_environment = {}
-        for key, value in self.environment.items():
+        for key, value in list(self.environment.items()):
             if key in os.environ:
                 self._saved_environment[key] = os.environ[key]
             # Interpolate value with variables from environment. Maybe there

Modified: zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/egg.py
===================================================================
--- zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/egg.py	2011-03-16 13:31:40 UTC (rev 120974)
+++ zc.buildout/branches/python-3/zc.recipe.egg_/src/zc/recipe/egg/egg.py	2011-03-16 13:51:30 UTC (rev 120975)
@@ -16,7 +16,7 @@
 $Id$
 """
 
-import UserDict, logging, os, re, zipfile
+import collections, logging, os, re, zipfile
 import zc.buildout
 import zc.buildout.easy_install
 
@@ -198,7 +198,7 @@
 Egg = Scripts
 
 
-class _BackwardsSupportOption(UserDict.UserDict):
+class _BackwardsSupportOption(collections.UserDict):
 
     def __init__(self, data):
         self.data = data # We want to show mutations to the underlying dict.



More information about the checkins mailing list