[Python-checkins] distutils2 (merge default -> default): Branch merge. Will clean up later.

eric.araujo python-checkins at python.org
Wed Aug 31 16:25:14 CEST 2011


http://hg.python.org/distutils2/rev/20f69a01ae38
changeset:   1133:20f69a01ae38
parent:      1131:0151c8da5e4b
parent:      1132:132b1cb435ec
user:        Éric Araujo <merwok at netwok.org>
date:        Wed Aug 31 16:25:02 2011 +0200
summary:
  Branch merge.  Will clean up later.

files:
  distutils2/_backport/functools.py                 |   56 +
  distutils2/_backport/path.py                      |   15 +
  distutils2/_backport/shutil.py                    |    4 +-
  distutils2/command/bdist_msi.py                   |   26 +-
  distutils2/command/bdist_wininst.py               |   73 +-
  distutils2/command/build_ext.py                   |    2 +-
  distutils2/command/build_scripts.py               |   27 +-
  distutils2/command/cmd.py                         |    2 +-
  distutils2/command/config.py                      |   40 +-
  distutils2/command/install_dist.py                |    2 +-
  distutils2/command/install_distinfo.py            |   60 +-
  distutils2/command/install_lib.py                 |    2 +-
  distutils2/command/install_scripts.py             |    2 +-
  distutils2/command/sdist.py                       |    2 +-
  distutils2/command/upload.py                      |   18 +-
  distutils2/command/upload_docs.py                 |   21 +-
  distutils2/compiler/ccompiler.py                  |   12 +-
  distutils2/compiler/cygwinccompiler.py            |   11 +-
  distutils2/config.py                              |   10 +-
  distutils2/create.py                              |  104 +-
  distutils2/database.py                            |   54 +-
  distutils2/depgraph.py                            |    5 +-
  distutils2/install.py                             |    7 +-
  distutils2/manifest.py                            |   12 +-
  distutils2/markers.py                             |    7 +-
  distutils2/metadata.py                            |   10 +-
  distutils2/pypi/dist.py                           |   12 +-
  distutils2/pypi/simple.py                         |   25 +-
  distutils2/run.py                                 |    6 +-
  distutils2/tests/__init__.py                      |    1 -
  distutils2/tests/pypi_server.py                   |   16 +-
  distutils2/tests/support.py                       |   11 +-
  distutils2/tests/test_command_build_ext.py        |   23 +-
  distutils2/tests/test_command_build_py.py         |    2 +-
  distutils2/tests/test_command_build_scripts.py    |   10 +-
  distutils2/tests/test_command_config.py           |    5 +-
  distutils2/tests/test_command_install_dist.py     |   27 +-
  distutils2/tests/test_command_install_distinfo.py |   44 +-
  distutils2/tests/test_command_install_scripts.py  |    5 +-
  distutils2/tests/test_command_register.py         |   11 +-
  distutils2/tests/test_command_sdist.py            |   38 +-
  distutils2/tests/test_command_upload.py           |   10 +-
  distutils2/tests/test_command_upload_docs.py      |   24 +-
  distutils2/tests/test_config.py                   |    6 +-
  distutils2/tests/test_create.py                   |   17 +-
  distutils2/tests/test_database.py                 |  109 ++-
  distutils2/tests/test_dist.py                     |   35 +-
  distutils2/tests/test_manifest.py                 |   10 +-
  distutils2/tests/test_markers.py                  |    5 +-
  distutils2/tests/test_metadata.py                 |   37 +-
  distutils2/tests/test_mixin2to3.py                |   31 +-
  distutils2/tests/test_msvc9compiler.py            |   12 +-
  distutils2/tests/test_pypi_server.py              |   23 +-
  distutils2/tests/test_pypi_simple.py              |   25 +-
  distutils2/tests/test_pypi_xmlrpc.py              |    4 +-
  distutils2/tests/test_run.py                      |    9 +-
  distutils2/tests/test_util.py                     |   66 +-
  distutils2/util.py                                |  283 +++++----
  sysconfig.py                                      |   14 +-
  59 files changed, 898 insertions(+), 642 deletions(-)


diff --git a/distutils2/_backport/functools.py b/distutils2/_backport/functools.py
new file mode 100644
--- /dev/null
+++ b/distutils2/_backport/functools.py
@@ -0,0 +1,56 @@
+"""functools.py - Tools for working with functions and callable objects
+Copied from:
+https://github.com/dln/pycassa/commit/90736f8146c1cac8287f66e8c8b64cb80e011513#diff-1
+
+"""
+
+try:
+    from _functools import partial
+except:
+    class partial(object):
+        "A simple replacement of functools.partial"
+        def __init__(self, func, *args, **kw):
+            self.func = func
+            self.args = args
+            self.keywords = kw
+        def __call__(self, *otherargs, **otherkw):
+            kw = self.keywords.copy()
+            kw.update(otherkw)
+            return self.func(*(self.args + otherargs), **kw)
+
+# update_wrapper() and wraps() are tools to help write
+# wrapper functions that can handle naive introspection
+
+WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
+WRAPPER_UPDATES = ('__dict__',)
+def update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS,
+                   updated=WRAPPER_UPDATES):
+    """Update a wrapper function to look like the wrapped function
+
+       wrapper is the function to be updated
+       wrapped is the original function
+       assigned is a tuple naming the attributes assigned directly
+       from the wrapped function to the wrapper function (defaults to
+       functools.WRAPPER_ASSIGNMENTS)
+       updated is a tuple naming the attributes of the wrapper that
+       are updated with the corresponding attribute from the wrapped
+       function (defaults to functools.WRAPPER_UPDATES)
+    """
+    for attr in assigned:
+        setattr(wrapper, attr, getattr(wrapped, attr))
+    for attr in updated:
+        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
+    # Return the wrapper so this can be used as a decorator via partial()
+    return wrapper
+
+def wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES):
+    """Decorator factory to apply update_wrapper() to a wrapper function
+
+       Returns a decorator that invokes update_wrapper() with the decorated
+       function as the wrapper argument and the arguments to wraps() as the
+       remaining arguments. Default arguments are as for update_wrapper().
+       This is a convenience function to simplify applying partial() to
+       update_wrapper().
+    """
+    return partial(update_wrapper, wrapped=wrapped,
+                   assigned=assigned, updated=updated)
diff --git a/distutils2/_backport/path.py b/distutils2/_backport/path.py
new file mode 100644
--- /dev/null
+++ b/distutils2/_backport/path.py
@@ -0,0 +1,15 @@
+from posixpath import curdir, sep, pardir, join, abspath, commonprefix
+
+def relpath(path, start=curdir):
+    """Return a relative version of a path"""
+    if not path:
+        raise ValueError("no path specified")
+    start_list = abspath(start).split(sep)
+    path_list = abspath(path).split(sep)
+    # Work out how much of the filepath is shared by start and path.
+    i = len(commonprefix([start_list, path_list]))
+    rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
+    if not rel_list:
+        return curdir
+    return join(*rel_list)
+
diff --git a/distutils2/_backport/shutil.py b/distutils2/_backport/shutil.py
--- a/distutils2/_backport/shutil.py
+++ b/distutils2/_backport/shutil.py
@@ -748,7 +748,7 @@
         try:
             format_info = _UNPACK_FORMATS[format]
         except KeyError:
-            raise ValueError("Unknown unpack format '{0}'".format(format))
+            raise ValueError("Unknown unpack format '%s'" % format)
 
         func = format_info[0]
         func(filename, extract_dir, **dict(format_info[1]))
@@ -756,7 +756,7 @@
         # we need to look at the registered unpackers supported extensions
         format = _find_unpack_format(filename)
         if format is None:
-            raise ReadError("Unknown archive format '{0}'".format(filename))
+            raise ReadError("Unknown archive format '%s'" % filename)
 
         func = _UNPACK_FORMATS[format][1]
         kwargs = dict(_UNPACK_FORMATS[format][2])
diff --git a/distutils2/command/bdist_msi.py b/distutils2/command/bdist_msi.py
--- a/distutils2/command/bdist_msi.py
+++ b/distutils2/command/bdist_msi.py
@@ -390,18 +390,20 @@
         #     entries for each version as the above code does
         if self.pre_install_script:
             scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
-            with open(scriptfn, "w") as f:
-                # The batch file will be executed with [PYTHON], so that %1
-                # is the path to the Python interpreter; %0 will be the path
-                # of the batch file.
-                # rem ="""
-                # %1 %0
-                # exit
-                # """
-                # <actual script>
-                f.write('rem ="""\n%1 %0\nexit\n"""\n')
-                with open(self.pre_install_script) as fp:
-                    f.write(fp.read())
+            f = open(scriptfn, "w")
+            # The batch file will be executed with [PYTHON], so that %1
+            # is the path to the Python interpreter; %0 will be the path
+            # of the batch file.
+            # rem ="""
+            # %1 %0
+            # exit
+            # """
+            # <actual script>
+            f.write('rem ="""\n%1 %0\nexit\n"""\n')
+            fp = open(self.pre_install_script)
+            f.write(fp.read())
+            fp.close()
+            f.close()
             add_data(self.db, "Binary",
                      [("PreInstall", msilib.Binary(scriptfn)),
                      ])
diff --git a/distutils2/command/bdist_wininst.py b/distutils2/command/bdist_wininst.py
--- a/distutils2/command/bdist_wininst.py
+++ b/distutils2/command/bdist_wininst.py
@@ -245,45 +245,50 @@
         logger.info("creating %s", installer_name)
 
         if bitmap:
-            with open(bitmap, "rb") as fp:
-                bitmapdata = fp.read()
+            fp = open(bitmap, "rb")
+            bitmapdata = fp.read()
+            fp.close()
             bitmaplen = len(bitmapdata)
         else:
             bitmaplen = 0
 
-        with open(installer_name, "wb") as file:
-            file.write(self.get_exe_bytes())
-            if bitmap:
-                file.write(bitmapdata)
+        file = open(installer_name, "wb")
+        file.write(self.get_exe_bytes())
+        if bitmap:
+            file.write(bitmapdata)
 
-            # Convert cfgdata from unicode to ascii, mbcs encoded
-            if isinstance(cfgdata, unicode):
-                cfgdata = cfgdata.encode("mbcs")
+        # Convert cfgdata from unicode to ascii, mbcs encoded
+        if isinstance(cfgdata, unicode):
+            cfgdata = cfgdata.encode("mbcs")
 
-            # Append the pre-install script
+        # Append the pre-install script
+        cfgdata = cfgdata + "\0"
+        if self.pre_install_script:
+            fp = open(self.pre_install_script)
+            script_data = fp.read()
+            fp.close()
+            cfgdata = cfgdata + script_data + "\n\0"
+        else:
+            # empty pre-install script
             cfgdata = cfgdata + "\0"
-            if self.pre_install_script:
-                with open(self.pre_install_script) as fp:
-                    script_data = fp.read()
-                cfgdata = cfgdata + script_data + "\n\0"
-            else:
-                # empty pre-install script
-                cfgdata = cfgdata + "\0"
-            file.write(cfgdata)
+        file.write(cfgdata)
 
-            # The 'magic number' 0x1234567B is used to make sure that the
-            # binary layout of 'cfgdata' is what the wininst.exe binary
-            # expects.  If the layout changes, increment that number, make
-            # the corresponding changes to the wininst.exe sources, and
-            # recompile them.
-            header = struct.pack("<iii",
-                                 0x1234567B,       # tag
-                                 len(cfgdata),     # length
-                                 bitmaplen,        # number of bytes in bitmap
-                                 )
-            file.write(header)
-            with open(arcname, "rb") as fp:
-                file.write(fp.read())
+        # The 'magic number' 0x1234567B is used to make sure that the
+        # binary layout of 'cfgdata' is what the wininst.exe binary
+        # expects.  If the layout changes, increment that number, make
+        # the corresponding changes to the wininst.exe sources, and
+        # recompile them.
+        header = struct.pack("<iii",
+                             0x1234567B,       # tag
+                             len(cfgdata),     # length
+                             bitmaplen,        # number of bytes in bitmap
+                             )
+        file.write(header)
+        file.close()
+
+        fp = open(arcname, "rb")
+        file.write(fp.read())
+        fp.close()
 
     def get_installer_filename(self, fullname):
         # Factored out to allow overriding in subclasses
@@ -338,5 +343,7 @@
             sfix = ''
 
         filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix))
-        with open(filename, "rb") as fp:
-            return fp.read()
+        fp = open(filename, "rb")
+        content = fp.read()
+        fp.close()
+        return content
diff --git a/distutils2/command/build_ext.py b/distutils2/command/build_ext.py
--- a/distutils2/command/build_ext.py
+++ b/distutils2/command/build_ext.py
@@ -656,7 +656,7 @@
 
         else:
             if sysconfig.get_config_var('Py_ENABLE_SHARED'):
-                pythonlib = 'python{}.{}'.format(
+                pythonlib = 'python%s.%s' % (
                     sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)
                 return ext.libraries + [pythonlib]
             else:
diff --git a/distutils2/command/build_scripts.py b/distutils2/command/build_scripts.py
--- a/distutils2/command/build_scripts.py
+++ b/distutils2/command/build_scripts.py
@@ -11,7 +11,7 @@
 
 
 # check if Python is called on the first line with this expression
-first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$')
+first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
 
 class build_scripts(Command, Mixin2to3):
 
@@ -93,7 +93,7 @@
                 match = first_line_re.match(first_line)
                 if match:
                     adjust = True
-                    post_interp = match.group(1) or b''
+                    post_interp = match.group(1) or ''
 
             if adjust:
                 logger.info("copying and adjusting %s -> %s", script,
@@ -107,7 +107,7 @@
                            "python%s%s" % (sysconfig.get_config_var("VERSION"),
                                            sysconfig.get_config_var("EXE")))
                     executable = fsencode(executable)
-                    shebang = b"#!" + executable + post_interp + b"\n"
+                    shebang = "#!" + executable + post_interp + "\n"
                     # Python parser starts to read a script using UTF-8 until
                     # it gets a #coding:xxx cookie. The shebang has to be the
                     # first line of a file, the #coding:xxx cookie cannot be
@@ -117,8 +117,8 @@
                         shebang.decode('utf-8')
                     except UnicodeDecodeError:
                         raise ValueError(
-                            "The shebang ({!r}) is not decodable "
-                            "from utf-8".format(shebang))
+                            "The shebang (%r) is not decodable "
+                            "from utf-8" % shebang)
                     # If the script is encoded to a custom encoding (use a
                     # #coding:xxx cookie), the shebang has to be decodable from
                     # the script encoding too.
@@ -126,12 +126,13 @@
                         shebang.decode(encoding)
                     except UnicodeDecodeError:
                         raise ValueError(
-                            "The shebang ({!r}) is not decodable "
-                            "from the script encoding ({})"
-                            .format(shebang, encoding))
-                    with open(outfile, "wb") as outf:
-                        outf.write(shebang)
-                        outf.writelines(f.readlines())
+                            "The shebang (%r) is not decodable "
+                            "from the script encoding (%s)" % (
+                                shebang, encoding))
+                    outf = open(outfile, "wb")
+                    outf.write(shebang)
+                    outf.writelines(f.readlines())
+                    outf.close()
                 if f:
                     f.close()
             else:
@@ -144,8 +145,8 @@
                 if self.dry_run:
                     logger.info("changing mode of %s", file)
                 else:
-                    oldmode = os.stat(file).st_mode & 0o7777
-                    newmode = (oldmode | 0o555) & 0o7777
+                    oldmode = os.stat(file).st_mode & 07777
+                    newmode = (oldmode | 00555) & 07777
                     if newmode != oldmode:
                         logger.info("changing mode of %s from %o to %o",
                                  file, oldmode, newmode)
diff --git a/distutils2/command/cmd.py b/distutils2/command/cmd.py
--- a/distutils2/command/cmd.py
+++ b/distutils2/command/cmd.py
@@ -351,7 +351,7 @@
     def execute(self, func, args, msg=None, level=1):
         util.execute(func, args, msg, dry_run=self.dry_run)
 
-    def mkpath(self, name, mode=0o777, dry_run=None, verbose=0):
+    def mkpath(self, name, mode=00777, dry_run=None, verbose=0):
         if dry_run is None:
             dry_run = self.dry_run
         name = os.path.normpath(name)
diff --git a/distutils2/command/config.py b/distutils2/command/config.py
--- a/distutils2/command/config.py
+++ b/distutils2/command/config.py
@@ -110,14 +110,15 @@
 
     def _gen_temp_sourcefile(self, body, headers, lang):
         filename = "_configtest" + LANG_EXT[lang]
-        with open(filename, "w") as file:
-            if headers:
-                for header in headers:
-                    file.write("#include <%s>\n" % header)
-                file.write("\n")
-            file.write(body)
-            if body[-1] != "\n":
-                file.write("\n")
+        file = open(filename, "w")
+        if headers:
+            for header in headers:
+                file.write("#include <%s>\n" % header)
+            file.write("\n")
+        file.write(body)
+        if body[-1] != "\n":
+            file.write("\n")
+        file.close()
         return filename
 
     def _preprocess(self, body, headers, include_dirs, lang):
@@ -206,15 +207,15 @@
         if isinstance(pattern, basestring):
             pattern = re.compile(pattern)
 
-        with open(out) as file:
-            match = False
-            while True:
-                line = file.readline()
-                if line == '':
-                    break
-                if pattern.search(line):
-                    match = True
-                    break
+        file = open(out)
+        match = False
+        while True:
+            line = file.readline()
+            if line == '':
+                break
+            if pattern.search(line):
+                match = True
+                break
 
         self._clean()
         return match
@@ -345,5 +346,6 @@
         logger.info(filename)
     else:
         logger.info(head)
-    with open(filename) as file:
-        logger.info(file.read())
+    file = open(filename)
+    logger.info(file.read())
+    file.close()
diff --git a/distutils2/command/install_dist.py b/distutils2/command/install_dist.py
--- a/distutils2/command/install_dist.py
+++ b/distutils2/command/install_dist.py
@@ -501,7 +501,7 @@
         home = convert_path(os.path.expanduser("~"))
         for name, path in self.config_vars.items():
             if path.startswith(home) and not os.path.isdir(path):
-                os.makedirs(path, 0o700)
+                os.makedirs(path, 00700)
 
     # -- Command execution methods -------------------------------------
 
diff --git a/distutils2/command/install_distinfo.py b/distutils2/command/install_distinfo.py
--- a/distutils2/command/install_distinfo.py
+++ b/distutils2/command/install_distinfo.py
@@ -6,7 +6,10 @@
 import csv
 import os
 import re
-import hashlib
+try:
+    import hashlib
+except ImportError: #<2.5
+    from distutils2._backport import hashlib
 
 from distutils2.command.cmd import Command
 from distutils2 import logger
@@ -92,8 +95,9 @@
 
             installer_path = os.path.join(self.distinfo_dir, 'INSTALLER')
             logger.info('creating %s', installer_path)
-            with open(installer_path, 'w') as f:
-                f.write(self.installer)
+            f = open(installer_path, 'w')
+            f.write(self.installer)
+            f.close()
             self.outputs.append(installer_path)
 
             if self.requested:
@@ -109,40 +113,42 @@
                     resources_path = os.path.join(self.distinfo_dir,
                                                   'RESOURCES')
                     logger.info('creating %s', resources_path)
-                    with open(resources_path, 'wb') as f:
-                        writer = csv.writer(f, delimiter=',',
-                                            lineterminator='\n',
-                                            quotechar='"')
-                        for tuple in install_data.get_resources_out():
-                            writer.writerow(tuple)
+                    f = open(resources_path, 'wb')
+                    writer = csv.writer(f, delimiter=',',
+                                        lineterminator='\n',
+                                        quotechar='"')
+                    for tuple in install_data.get_resources_out():
+                        writer.writerow(tuple)
 
-                        self.outputs.append(resources_path)
+                    f.close()
+                    self.outputs.append(resources_path)
 
             if not self.no_record:
                 record_path = os.path.join(self.distinfo_dir, 'RECORD')
                 logger.info('creating %s', record_path)
-                with codecs.open(record_path, 'w', encoding='utf-8') as f:
-                    writer = csv.writer(f, delimiter=',',
+                f = codecs.open(record_path, 'w', encoding='utf-8')
+                writer = csv.writer(f, delimiter=',',
                                         lineterminator='\n',
                                         quotechar='"')
 
-                    install = self.get_finalized_command('install_dist')
+                install = self.get_finalized_command('install_dist')
 
-                    for fpath in install.get_outputs():
-                        if fpath.endswith('.pyc') or fpath.endswith('.pyo'):
-                            # do not put size and md5 hash, as in PEP-376
-                            writer.writerow((fpath, '', ''))
-                        else:
-                            size = os.path.getsize(fpath)
-                            with open(fpath, 'rb') as fp:
-                                hash = hashlib.md5()
-                                hash.update(fp.read())
-                            md5sum = hash.hexdigest()
-                            writer.writerow((fpath, md5sum, size))
+                for fpath in install.get_outputs():
+                    if fpath.endswith('.pyc') or fpath.endswith('.pyo'):
+                        # do not put size and md5 hash, as in PEP-376
+                        writer.writerow((fpath, '', ''))
+                    else:
+                        size = os.path.getsize(fpath)
+                        fp = open(fpath, 'rb')
+                        hash = hashlib.md5()
+                        hash.update(fp.read())
+                        fp.close()
+                        md5sum = hash.hexdigest()
+                        writer.writerow((fpath, md5sum, size))
 
-                    # add the RECORD file itself
-                    writer.writerow((record_path, '', ''))
-                    self.outputs.append(record_path)
+                # add the RECORD file itself
+                writer.writerow((record_path, '', ''))
+                self.outputs.append(record_path)
 
     def get_outputs(self):
         return self.outputs
diff --git a/distutils2/command/install_lib.py b/distutils2/command/install_lib.py
--- a/distutils2/command/install_lib.py
+++ b/distutils2/command/install_lib.py
@@ -114,7 +114,7 @@
         return outfiles
 
     def byte_compile(self, files):
-        if getattr(sys, 'dont_write_bytecode'):
+        if hasattr(sys, 'dont_write_bytecode'):
             # XXX do we want this?  because a Python runs without bytecode
             # doesn't mean that the *dists should not contain bytecode
             #--or does it?
diff --git a/distutils2/command/install_scripts.py b/distutils2/command/install_scripts.py
--- a/distutils2/command/install_scripts.py
+++ b/distutils2/command/install_scripts.py
@@ -48,7 +48,7 @@
                 if self.dry_run:
                     logger.info("changing mode of %s", file)
                 else:
-                    mode = (os.stat(file).st_mode | 0o555) & 0o7777
+                    mode = (os.stat(file).st_mode | 00555) & 07777
                     logger.info("changing mode of %s to %o", file, mode)
                     os.chmod(file, mode)
 
diff --git a/distutils2/command/sdist.py b/distutils2/command/sdist.py
--- a/distutils2/command/sdist.py
+++ b/distutils2/command/sdist.py
@@ -337,7 +337,7 @@
         """
         return self.archive_files
 
-    def create_tree(self, base_dir, files, mode=0o777, verbose=1,
+    def create_tree(self, base_dir, files, mode=00777, verbose=1,
                     dry_run=False):
         need_dir = set()
         for file in files:
diff --git a/distutils2/command/upload.py b/distutils2/command/upload.py
--- a/distutils2/command/upload.py
+++ b/distutils2/command/upload.py
@@ -5,9 +5,11 @@
 import logging
 import platform
 import urlparse
-from io import BytesIO
 from base64 import standard_b64encode
-from hashlib import md5
+try:
+    from hashlib import md5
+except ImportError:
+    from distutils2._backport.hashlib import md5
 from urllib2 import HTTPError
 from urllib2 import urlopen, Request
 
@@ -102,8 +104,9 @@
 
         # Fill in the data - send all the metadata in case we need to
         # register a new release
-        with open(filename, 'rb') as f:
-            content = f.read()
+        f = open(filename, 'rb')
+        content = f.read()
+        f.close()
 
         data = self.distribution.metadata.todict()
 
@@ -119,8 +122,9 @@
             data['comment'] = 'built for %s' % platform.platform(terse=True)
 
         if self.sign:
-            with open(filename + '.asc') as fp:
-                sig = fp.read()
+            fp = open(filename + '.asc')
+            sig = fp.read()
+            fp.close()
             data['gpg_signature'] = [
                 (os.path.basename(filename) + ".asc", sig)]
 
@@ -128,7 +132,7 @@
         # The exact encoding of the authentication string is debated.
         # Anyway PyPI only accepts ascii for both username or password.
         user_pass = (self.username + ":" + self.password).encode('ascii')
-        auth = b"Basic " + standard_b64encode(user_pass)
+        auth = "Basic " + standard_b64encode(user_pass)
 
         # Build up the MIME payload for the POST data
         files = []
diff --git a/distutils2/command/upload_docs.py b/distutils2/command/upload_docs.py
--- a/distutils2/command/upload_docs.py
+++ b/distutils2/command/upload_docs.py
@@ -7,7 +7,7 @@
 import logging
 import httplib
 import urlparse
-from io import BytesIO
+from StringIO import StringIO
 
 from distutils2 import logger
 from distutils2.util import (read_pypirc, DEFAULT_REPOSITORY, DEFAULT_REALM,
@@ -18,14 +18,15 @@
 
 def zip_dir(directory):
     """Compresses recursively contents of directory into a BytesIO object"""
-    destination = BytesIO()
-    with zipfile.ZipFile(destination, "w") as zip_file:
-        for root, dirs, files in os.walk(directory):
-            for name in files:
-                full = os.path.join(root, name)
-                relative = root[len(directory):].lstrip(os.path.sep)
-                dest = os.path.join(relative, name)
-                zip_file.write(full, dest)
+    destination = StringIO()
+    zip_file = zipfile.ZipFile(destination, "w")
+    for root, dirs, files in os.walk(directory):
+        for name in files:
+            full = os.path.join(root, name)
+            relative = root[len(directory):].lstrip(os.path.sep)
+            dest = os.path.join(relative, name)
+            zip_file.write(full, dest)
+    zip_file.close()
     return destination
 
 
@@ -87,7 +88,7 @@
         content_type, body = encode_multipart(fields, files)
 
         credentials = self.username + ':' + self.password
-        auth = b"Basic " + base64.encodebytes(credentials.encode()).strip()
+        auth = "Basic " + base64.encodebytes(credentials.encode()).strip()
 
         logger.info("Submitting documentation to %s", self.repository)
 
diff --git a/distutils2/compiler/ccompiler.py b/distutils2/compiler/ccompiler.py
--- a/distutils2/compiler/ccompiler.py
+++ b/distutils2/compiler/ccompiler.py
@@ -5,7 +5,6 @@
 """
 
 import os
-import sys
 from shutil import move
 from distutils2 import logger
 from distutils2.util import split_quoted, execute, newer_group, spawn
@@ -728,14 +727,15 @@
         if library_dirs is None:
             library_dirs = []
         fd, fname = tempfile.mkstemp(".c", funcname, text=True)
-        with os.fdopen(fd, "w") as f:
-            for incl in includes:
-                f.write("""#include "%s"\n""" % incl)
-            f.write("""\
+        f = os.fdopen(fd, "w")
+        for incl in includes:
+            f.write("""#include "%s"\n""" % incl)
+        f.write("""\
 main (int argc, char **argv) {
     %s();
 }
 """ % funcname)
+        f.close()
         try:
             objects = self.compile([fname], include_dirs=include_dirs)
         except CompileError:
@@ -852,7 +852,7 @@
             return
         return move(src, dst)
 
-    def mkpath(self, name, mode=0o777):
+    def mkpath(self, name, mode=00777):
         name = os.path.normpath(name)
         if os.path.isdir(name) or name == '':
             return
diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py
--- a/distutils2/compiler/cygwinccompiler.py
+++ b/distutils2/compiler/cygwinccompiler.py
@@ -344,11 +344,12 @@
     # let's see if __GNUC__ is mentioned in python.h
     fn = sysconfig.get_config_h_filename()
     try:
-        with open(fn) as config_h:
-            if "__GNUC__" in config_h.read():
-                return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn
-            else:
-                return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn
+        config_h = open(fn)
+        if "__GNUC__" in config_h.read():
+            return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn
+        else:
+            return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn
+        config_h.close()
     except IOError:
         exc = sys.exc_info()[1]
         return (CONFIG_H_UNCERTAIN,
diff --git a/distutils2/config.py b/distutils2/config.py
--- a/distutils2/config.py
+++ b/distutils2/config.py
@@ -177,8 +177,9 @@
                     value = []
                     for filename in filenames:
                         # will raise if file not found
-                        with open(filename) as description_file:
-                            value.append(description_file.read().strip())
+                        description_file = open(filename)
+                        value.append(description_file.read().strip())
+                        description_file.close()
                         # add filename as a required file
                         if filename not in metadata.requires_files:
                             metadata.requires_files.append(filename)
@@ -287,8 +288,9 @@
 
         for filename in filenames:
             logger.debug("  reading %s", filename)
-            with codecs.open(filename, 'r', encoding='utf-8') as f:
-                parser.readfp(f)
+            f = codecs.open(filename, 'r', encoding='utf-8')
+            parser.readfp(f)
+            f.close()
 
             if os.path.split(filename)[-1] == 'setup.cfg':
                 self._read_setup_cfg(parser, filename)
diff --git a/distutils2/create.py b/distutils2/create.py
--- a/distutils2/create.py
+++ b/distutils2/create.py
@@ -26,8 +26,12 @@
 import glob
 import shutil
 import sysconfig
-import tokenize
-from hashlib import md5
+if 'any' not in dir(__builtins__):
+    from distutils2._backport import any
+try:
+    from hashlib import md5
+except ImportError:
+    from distutils2._backport.hashlib import md5
 from textwrap import dedent
 from distutils2.util import cmp_to_key, detect_encoding
 from ConfigParser import RawConfigParser
@@ -112,11 +116,12 @@
     This function load the setup file in all cases (even if it have already
     been loaded before, because we are monkey patching its setup function with
     a particular one"""
-    with open("setup.py", "rb") as f:
-        encoding, lines = detect_encoding(f.readline)
-    with open("setup.py") as f:
-        imp.load_module("setup", f, "setup.py", (".py", "r", imp.PY_SOURCE))
-
+    f = open("setup.py", "rb")
+    encoding, lines = detect_encoding(f.readline)
+    f.close()
+    f = open("setup.py")
+    imp.load_module("setup", f, "setup.py", (".py", "r", imp.PY_SOURCE))
+    f.close()
 
 def ask_yn(question, default=None, helptext=None):
     question += ' (y/n)'
@@ -274,49 +279,51 @@
                 return
             shutil.move(_FILENAME, '%s.old' % _FILENAME)
 
-        with codecs.open(_FILENAME, 'w', encoding='utf-8') as fp:
-            fp.write('[metadata]\n')
-            # TODO use metadata module instead of hard-coding field-specific
-            # behavior here
+        fp = codecs.open(_FILENAME, 'w', encoding='utf-8')
+        fp.write(u'[metadata]\n')
+        # TODO use metadata module instead of hard-coding field-specific
+        # behavior here
 
-            # simple string entries
-            for name in ('name', 'version', 'summary', 'download_url'):
-                fp.write('%s = %s\n' % (name, self.data.get(name, 'UNKNOWN')))
+        # simple string entries
+        for name in ('name', 'version', 'summary', 'download_url'):
+            fp.write(u'%s = %s\n' % (name, self.data.get(name, 'UNKNOWN')))
 
-            # optional string entries
-            if 'keywords' in self.data and self.data['keywords']:
-                fp.write('keywords = %s\n' % ' '.join(self.data['keywords']))
-            for name in ('home_page', 'author', 'author_email',
-                         'maintainer', 'maintainer_email', 'description-file'):
-                if name in self.data and self.data[name]:
-                    fp.write('%s = %s\n' % (name, self.data[name]))
-            if 'description' in self.data:
-                fp.write(
-                    'description = %s\n'
-                    % '\n       |'.join(self.data['description'].split('\n')))
+        # optional string entries
+        if 'keywords' in self.data and self.data['keywords']:
+            fp.write(u'keywords = %s\n' % ' '.join(self.data['keywords']))
+        for name in ('home_page', 'author', 'author_email',
+                     'maintainer', 'maintainer_email', 'description-file'):
+            if name in self.data and self.data[name]:
+                fp.write(u'%s = %s\n' % (name.decode('utf-8'),
+                    self.data[name].decode('utf-8')))
+        if 'description' in self.data:
+            fp.write(
+                u'description = %s\n'
+                % u'\n       |'.join(self.data['description'].split('\n')))
 
-            # multiple use string entries
-            for name in ('platform', 'supported-platform', 'classifier',
-                         'requires-dist', 'provides-dist', 'obsoletes-dist',
-                         'requires-external'):
-                if not(name in self.data and self.data[name]):
-                    continue
-                fp.write('%s = ' % name)
-                fp.write(''.join('    %s\n' % val
-                                 for val in self.data[name]).lstrip())
-            fp.write('\n[files]\n')
-            for name in ('packages', 'modules', 'scripts',
-                         'package_data', 'extra_files'):
-                if not(name in self.data and self.data[name]):
-                    continue
-                fp.write('%s = %s\n'
-                         % (name, '\n    '.join(self.data[name]).strip()))
-            fp.write('\nresources =\n')
-            for src, dest in self.data['resources']:
-                fp.write('    %s = %s\n' % (src, dest))
-            fp.write('\n')
+        # multiple use string entries
+        for name in ('platform', 'supported-platform', 'classifier',
+                     'requires-dist', 'provides-dist', 'obsoletes-dist',
+                     'requires-external'):
+            if not(name in self.data and self.data[name]):
+                continue
+            fp.write(u'%s = ' % name)
+            fp.write(u''.join('    %s\n' % val
+                             for val in self.data[name]).lstrip())
+        fp.write(u'\n[files]\n')
+        for name in ('packages', 'modules', 'scripts',
+                     'package_data', 'extra_files'):
+            if not(name in self.data and self.data[name]):
+                continue
+            fp.write(u'%s = %s\n'
+                     % (name, u'\n    '.join(self.data[name]).strip()))
+        fp.write(u'\nresources =\n')
+        for src, dest in self.data['resources']:
+            fp.write(u'    %s = %s\n' % (src, dest))
+        fp.write(u'\n')
+        fp.close()
 
-        os.chmod(_FILENAME, 0o644)
+        os.chmod(_FILENAME, 00644)
         print('Wrote "%s".' % _FILENAME)
 
     def convert_py_to_cfg(self):
@@ -410,8 +417,9 @@
                                  self.data['description']).lower().encode())
                 ref = ref.digest()
                 for readme in glob.glob('README*'):
-                    with codecs.open(readme, encoding='utf-8') as fp:
-                        contents = fp.read()
+                    fp = codecs.open(readme, encoding='utf-8')
+                    contents = fp.read()
+                    fp.close()
                     contents = re.sub('\s', '', contents.lower()).encode()
                     val = md5(contents).digest()
                     if val == ref:
diff --git a/distutils2/database.py b/distutils2/database.py
--- a/distutils2/database.py
+++ b/distutils2/database.py
@@ -6,7 +6,10 @@
 import csv
 import sys
 import zipimport
-from hashlib import md5
+try:
+    from hashlib import md5
+except ImportError:
+    from _backport.hashlib import md5
 from distutils2 import logger
 from distutils2.errors import PackagingError
 from distutils2.version import suggest_normalized_version, VersionPredicate
@@ -158,25 +161,27 @@
 
     def _get_records(self, local=False):
         results = []
-        with self.get_distinfo_file('RECORD') as record:
-            record_reader = csv.reader(record, delimiter=',',
-                                       lineterminator='\n')
-            for row in record_reader:
-                missing = [None for i in range(len(row), 3)]
-                path, checksum, size = row + missing
-                if local:
-                    path = path.replace('/', os.sep)
-                    path = os.path.join(sys.prefix, path)
-                results.append((path, checksum, size))
+        record = self.get_distinfo_file('RECORD')
+        record_reader = csv.reader(record, delimiter=',',
+                                   lineterminator='\n')
+        for row in record_reader:
+            missing = [None for i in range(len(row), 3)]
+            path, checksum, size = row + missing
+            if local:
+                path = path.replace('/', os.sep)
+                path = os.path.join(sys.prefix, path)
+            results.append((path, checksum, size))
+        record.close()
         return results
 
     def get_resource_path(self, relative_path):
-        with self.get_distinfo_file('RESOURCES') as resources_file:
-            resources_reader = csv.reader(resources_file, delimiter=',',
-                                           lineterminator='\n')
-            for relative, destination in resources_reader:
-                if relative == relative_path:
-                    return destination
+        resources_file = self.get_distinfo_file('RESOURCES')
+        resources_reader = csv.reader(resources_file, delimiter=',',
+                                       lineterminator='\n')
+        for relative, destination in resources_reader:
+            if relative == relative_path:
+                return destination
+        resources_file.close()
         raise KeyError(
             'no resource file with relative path %r is installed' %
             relative_path)
@@ -325,8 +330,9 @@
                 self.metadata = Metadata(path=meta_path)
                 try:
                     req_path = os.path.join(path, 'EGG-INFO', 'requires.txt')
-                    with open(req_path, 'r') as fp:
-                        requires = fp.read()
+                    fp = open(req_path, 'r')
+                    requires = fp.read()
+                    fp.close()
                 except IOError:
                     requires = None
             else:
@@ -346,8 +352,9 @@
             if os.path.isdir(path):
                 path = os.path.join(path, 'PKG-INFO')
                 try:
-                    with open(os.path.join(path, 'requires.txt'), 'r') as fp:
-                        requires = fp.read()
+                    fp = open(os.path.join(path, 'requires.txt'), 'r')
+                    requires = fp.read()
+                    fp.close()
                 except IOError:
                     requires = None
             self.metadata = Metadata(path=path)
@@ -409,8 +416,9 @@
     def list_installed_files(self, local=False):
 
         def _md5(path):
-            with open(path, 'rb') as f:
-                content = f.read()
+            f = open(path, 'rb')
+            content = f.read()
+            f.close()
             return md5(content).hexdigest()
 
         def _size(path):
diff --git a/distutils2/depgraph.py b/distutils2/depgraph.py
--- a/distutils2/depgraph.py
+++ b/distutils2/depgraph.py
@@ -258,8 +258,9 @@
         else:
             filename = 'depgraph.dot'
 
-        with open(filename, 'w') as f:
-            graph_to_dot(graph, f, True)
+        f = open(filename, 'w')
+        graph_to_dot(graph, f, True)
+        f.close()
         tempout.seek(0)
         tempout = tempout.read()
         print(tempout)
diff --git a/distutils2/install.py b/distutils2/install.py
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -495,9 +495,10 @@
 
     # trying to write a file there
     try:
-        with tempfile.NamedTemporaryFile(suffix=project,
-                                         dir=purelib_path) as testfile:
-            testfile.write(b'test')
+        testfile = tempfile.NamedTemporaryFile(suffix=project,
+                dir=purelib_path)
+        testfile.write('test')
+        testfile.close()
     except OSError:
         # FIXME this should check the errno, or be removed altogether (race
         # condition: the directory permissions could be changed between here
diff --git a/distutils2/manifest.py b/distutils2/manifest.py
--- a/distutils2/manifest.py
+++ b/distutils2/manifest.py
@@ -99,8 +99,9 @@
         named by 'self.manifest'.
         """
         if os.path.isfile(path):
-            with open(path) as fp:
-                first_line = fp.readline()
+            fp = open(path)
+            first_line = fp.readline()
+            fp.close()
 
             if first_line != '# file GENERATED by distutils2, do NOT edit\n':
                 logger.info("not writing to manually maintained "
@@ -120,9 +121,10 @@
         distribution.
         """
         logger.info("reading manifest file %r", path)
-        with open(path) as manifest:
-            for line in manifest.readlines():
-                self.append(line)
+        manifest = open(path)
+        for line in manifest.readlines():
+            self.append(line)
+        manifest.close()
 
     def exclude_pattern(self, pattern, anchor=True, prefix=None,
                         is_regex=False):
diff --git a/distutils2/markers.py b/distutils2/markers.py
--- a/distutils2/markers.py
+++ b/distutils2/markers.py
@@ -24,7 +24,10 @@
 def _operate(operation, x, y):
     return _OPERATORS[operation](x, y)
 
-
+try:
+    python_implementation = platform.python_implementation()
+except AttributeError: #<2.6 - assume CPython?
+    python_implementation = 'CPython'
 # restricted set of variables
 _VARS = {'sys.platform': sys.platform,
          'python_version': sys.version[:3],
@@ -32,7 +35,7 @@
          'os.name': os.name,
          'platform.version': platform.version(),
          'platform.machine': platform.machine(),
-         'platform.python_implementation': platform.python_implementation()}
+         'platform.python_implementation': python_implementation}
 
 
 class _Operation(object):
diff --git a/distutils2/metadata.py b/distutils2/metadata.py
--- a/distutils2/metadata.py
+++ b/distutils2/metadata.py
@@ -300,8 +300,9 @@
 
     def read(self, filepath):
         """Read the metadata values from a file path."""
-        with codecs.open(filepath, 'r', encoding='utf-8') as fp:
-            self.read_file(fp)
+        fp = codecs.open(filepath, 'r', encoding='utf-8')
+        self.read_file(fp)
+        fp.close()
 
     def read_file(self, fileob):
         """Read the metadata values from a file object."""
@@ -323,8 +324,9 @@
 
     def write(self, filepath):
         """Write the metadata fields to filepath."""
-        with codecs.open(filepath, 'w', encoding='utf-8') as fp:
-            self.write_file(fp)
+        fp = codecs.open(filepath, 'w', encoding='utf-8')
+        self.write_file(fp)
+        fp.close()
 
     def write_file(self, fileobject):
         """Write the PKG-INFO format data to a file object."""
diff --git a/distutils2/pypi/dist.py b/distutils2/pypi/dist.py
--- a/distutils2/pypi/dist.py
+++ b/distutils2/pypi/dist.py
@@ -8,7 +8,10 @@
 """
 
 import re
-import hashlib
+try:
+    import hashlib
+except ImportError: #<2.5
+    from distutils2._backport import hashlib
 import tempfile
 import urllib
 import urlparse
@@ -324,9 +327,10 @@
         hashname = self.url['hashname']
         expected_hashval = self.url['hashval']
         if None not in (expected_hashval, hashname):
-            with open(filename, 'rb') as f:
-                hashval = hashlib.new(hashname)
-                hashval.update(f.read())
+            f = open(filename, 'rb')
+            hashval = hashlib.new(hashname)
+            hashval.update(f.read())
+            f.close()
 
             if hashval.hexdigest() != expected_hashval:
                 raise HashDoesNotMatch("got %s instead of %s"
diff --git a/distutils2/pypi/simple.py b/distutils2/pypi/simple.py
--- a/distutils2/pypi/simple.py
+++ b/distutils2/pypi/simple.py
@@ -15,7 +15,10 @@
 import os
 
 from fnmatch import translate
-from functools import wraps
+try:
+    from functools import wraps
+except ImportError:
+    from distutils2._backport.functools import wraps
 from distutils2 import logger
 from distutils2.metadata import Metadata
 from distutils2.version import get_version_predicate
@@ -27,7 +30,6 @@
                                     UnableToDownload, CantParseArchiveName,
                                     ReleaseNotFound, ProjectNotFound)
 from distutils2.pypi.mirrors import get_mirrors
-from distutils2.metadata import Metadata
 
 __all__ = ['Crawler', 'DEFAULT_SIMPLE_INDEX_URL']
 
@@ -158,16 +160,17 @@
 
         Return a list of names.
         """
-        with self._open_url(self.index_url) as index:
-            if '*' in name:
-                name.replace('*', '.*')
-            else:
-                name = "%s%s%s" % ('*.?', name, '*.?')
-            name = name.replace('*', '[^<]*')  # avoid matching end tag
-            projectname = re.compile('<a[^>]*>(%s)</a>' % name, re.I)
-            matching_projects = []
+        index = self._open_url(self.index_url)
+        if '*' in name:
+            name.replace('*', '.*')
+        else:
+            name = "%s%s%s" % ('*.?', name, '*.?')
+        name = name.replace('*', '[^<]*')  # avoid matching end tag
+        projectname = re.compile('<a[^>]*>(%s)</a>' % name, re.I)
+        matching_projects = []
 
-            index_content = index.read()
+        index_content = index.read()
+        index.close()
 
         # FIXME should use bytes I/O and regexes instead of decoding
         index_content = index_content.decode()
diff --git a/distutils2/run.py b/distutils2/run.py
--- a/distutils2/run.py
+++ b/distutils2/run.py
@@ -684,10 +684,12 @@
     except (IOError, os.error, PackagingError, CCompilerError):
         logger.exception(sys.exc_info()[1])
         return 1
-    finally:
+    except:
         logger.setLevel(old_level)
         logger.handlers[:] = old_handlers
-
+        raise
+    logger.setLevel(old_level)
+    logger.handlers[:] = old_handlers
 
 if __name__ == '__main__':
     sys.exit(main())
diff --git a/distutils2/tests/__init__.py b/distutils2/tests/__init__.py
--- a/distutils2/tests/__init__.py
+++ b/distutils2/tests/__init__.py
@@ -16,7 +16,6 @@
 import os
 import sys
 import unittest2 as unittest
-from .support import TESTFN
 
 # XXX move helpers to support, add tests for them, remove things that
 # duplicate test.support (or keep them for the backport; needs thinking)
diff --git a/distutils2/tests/pypi_server.py b/distutils2/tests/pypi_server.py
--- a/distutils2/tests/pypi_server.py
+++ b/distutils2/tests/pypi_server.py
@@ -34,7 +34,11 @@
 import select
 import threading
 import socketserver
-from functools import wraps
+try:
+    from functools import wraps
+except ImportError:
+    from distutils2._backport.functools import wraps
+
 from http.server import HTTPServer, SimpleHTTPRequestHandler
 from xmlrpc.server import SimpleXMLRPCServer
 
@@ -219,12 +223,14 @@
                         relative_path += "index.html"
 
                     if relative_path.endswith('.tar.gz'):
-                        with open(fs_path + relative_path, 'br') as file:
-                            data = file.read()
+                        fp = open(fs_path + relative_path, 'br')
+                        data = fp.read()
+                        fp.close()
                         headers = [('Content-type', 'application/x-gtar')]
                     else:
-                        with open(fs_path + relative_path) as file:
-                            data = file.read().encode()
+                        fp = open(fs_path + relative_path)
+                        data = fp.read().encode()
+                        fp.close()
                         headers = [('Content-type', 'text/html')]
 
                     headers.append(('Content-Length', len(data)))
diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py
--- a/distutils2/tests/support.py
+++ b/distutils2/tests/support.py
@@ -171,8 +171,9 @@
         """
         if isinstance(path, (list, tuple)):
             path = os.path.join(*path)
-        with codecs.open(path, 'w', encoding=encoding) as f:
-            f.write(content)
+        f = codecs.open(path, 'w', encoding=encoding)
+        f.write(content)
+        f.close()
 
     def create_dist(self, **kw):
         """Create a stub distribution object and files.
@@ -297,7 +298,7 @@
 
 # Disambiguate TESTFN for parallel testing, while letting it remain a valid
 # module name.
-TESTFN = "{0}_{1}_tmp".format(TESTFN, os.getpid())
+TESTFN = "%s_%s_tmp" % (TESTFN, os.getpid())
 
 
 # TESTFN_UNICODE is a non-ascii filename
@@ -333,12 +334,12 @@
 elif sys.platform != 'darwin':
     try:
         # ascii and utf-8 cannot encode the byte 0xff
-        b'\xff'.decode(TESTFN_ENCODING)
+        '\xff'.decode(TESTFN_ENCODING)
     except UnicodeDecodeError:
         # 0xff will be encoded using the surrogate character u+DCFF
         try:
             TESTFN_UNENCODABLE = TESTFN \
-                + b'-\xff'.decode(TESTFN_ENCODING, 'surrogateescape')
+                + '-\xff'.decode(TESTFN_ENCODING, 'surrogateescape')
         except LookupError:
             pass
     else:
diff --git a/distutils2/tests/test_command_build_ext.py b/distutils2/tests/test_command_build_ext.py
--- a/distutils2/tests/test_command_build_ext.py
+++ b/distutils2/tests/test_command_build_ext.py
@@ -10,9 +10,9 @@
                               PackagingPlatformError)
 from distutils2.command.build_ext import build_ext
 from distutils2.compiler.extension import Extension
-from .support import assert_python_ok
+from distutils2.tests.support import assert_python_ok
 
-from distutils2.tests import support, unittest, verbose, unload
+from distutils2.tests import support, unittest, verbose
 
 
 def _get_source_filename():
@@ -92,8 +92,10 @@
         try:
             cmd.ensure_finalized()
             cmd.run()
-        finally:
+        except:
             sys.stdout = old_stdout
+            raise
+        sys.stdout = old_stdout
 
         code = """if 1:
             import sys
@@ -124,14 +126,18 @@
 
         old_var = _CONFIG_VARS.get('Py_ENABLE_SHARED')
         _CONFIG_VARS['Py_ENABLE_SHARED'] = 1
-        try:
-            cmd.ensure_finalized()
-        finally:
+        def cleanup():
             sys.platform = old
             if old_var is None:
                 del _CONFIG_VARS['Py_ENABLE_SHARED']
             else:
                 _CONFIG_VARS['Py_ENABLE_SHARED'] = old_var
+        try:
+            cmd.ensure_finalized()
+        except:
+            cleanup()
+            raise
+        cleanup()
 
         # make sure we get some library dirs under solaris
         self.assertGreater(len(cmd.library_dirs), 0)
@@ -407,8 +413,8 @@
 
         deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c')
 
-        with open(deptarget_c, 'w') as fp:
-            fp.write(textwrap.dedent('''\
+        fp = open(deptarget_c, 'w')
+        fp.write(textwrap.dedent('''\
                 #include <AvailabilityMacros.h>
 
                 int dummy;
@@ -419,6 +425,7 @@
                 #endif
 
             ''' % operator))
+        fp.close()
 
         # get the deployment target that the interpreter was built with
         target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
diff --git a/distutils2/tests/test_command_build_py.py b/distutils2/tests/test_command_build_py.py
--- a/distutils2/tests/test_command_build_py.py
+++ b/distutils2/tests/test_command_build_py.py
@@ -61,7 +61,7 @@
         self.assertIn("__init__.py", files)
         self.assertIn("README.txt", files)
         # XXX even with -O, distutils writes pyc, not pyo; bug?
-        if sys.dont_write_bytecode:
+        if hasattr(sys , 'dont_write_bytecode'):
             self.assertNotIn("__init__.pyc", files)
         else:
             self.assertIn("__init__.pyc", files)
diff --git a/distutils2/tests/test_command_build_scripts.py b/distutils2/tests/test_command_build_scripts.py
--- a/distutils2/tests/test_command_build_scripts.py
+++ b/distutils2/tests/test_command_build_scripts.py
@@ -70,8 +70,9 @@
         return expected
 
     def write_script(self, dir, name, text):
-        with open(os.path.join(dir, name), "w") as f:
-            f.write(text)
+        f = open(os.path.join(dir, name), "w")
+        f.write(text)
+        f.close()
 
     def test_version_int(self):
         source = self.mkdtemp()
@@ -93,9 +94,12 @@
         sysconfig._CONFIG_VARS['VERSION'] = 4
         try:
             cmd.run()
-        finally:
+        except:
             if old is not None:
                 sysconfig._CONFIG_VARS['VERSION'] = old
+            raise
+        if old is not None:
+            sysconfig._CONFIG_VARS['VERSION'] = old
 
         built = os.listdir(target)
         for name in expected:
diff --git a/distutils2/tests/test_command_config.py b/distutils2/tests/test_command_config.py
--- a/distutils2/tests/test_command_config.py
+++ b/distutils2/tests/test_command_config.py
@@ -13,8 +13,9 @@
 
     def test_dump_file(self):
         this_file = __file__.rstrip('co')
-        with open(this_file) as f:
-            numlines = len(f.readlines())
+        f = open(this_file)
+        numlines = len(f.readlines())
+        f.close()
 
         dump_file(this_file, 'I am the header')
 
diff --git a/distutils2/tests/test_command_install_dist.py b/distutils2/tests/test_command_install_dist.py
--- a/distutils2/tests/test_command_install_dist.py
+++ b/distutils2/tests/test_command_install_dist.py
@@ -8,10 +8,7 @@
 
 _CONFIG_VARS = get_config_vars()
 
-from distutils2.tests import captured_stdout
-
 from distutils2.command.install_dist import install_dist
-from distutils2.command import install_dist as install_module
 from distutils2.dist import Distribution
 from distutils2.errors import PackagingOptionError
 
@@ -46,9 +43,12 @@
             cmd = install_dist(dist)
             cmd.home = destination
             cmd.ensure_finalized()
-        finally:
+        except:
             _SCHEMES.set('posix_prefix', 'platinclude', old_posix_prefix)
             _SCHEMES.set('posix_home', 'platinclude', old_posix_home)
+            raise
+        _SCHEMES.set('posix_prefix', 'platinclude', old_posix_prefix)
+        _SCHEMES.set('posix_home', 'platinclude', old_posix_home)
 
         self.assertEqual(cmd.install_base, destination)
         self.assertEqual(cmd.install_platbase, destination)
@@ -88,13 +88,17 @@
         self.old_expand = os.path.expanduser
         os.path.expanduser = _expanduser
 
+        def cleanup():
+            _CONFIG_VARS['userbase'] = self.old_user_base
+            _SCHEMES.set(scheme, 'purelib', self.old_user_site)
+            os.path.expanduser = self.old_expand
         try:
             # this is the actual test
             self._test_user_site()
-        finally:
-            _CONFIG_VARS['userbase'] = self.old_user_base
-            _SCHEMES.set(scheme, 'purelib', self.old_user_site)
-            os.path.expanduser = self.old_expand
+        except:
+            cleanup()
+            raise
+        cleanup()
 
     def _test_user_site(self):
         schemes = get_scheme_names()
@@ -191,8 +195,11 @@
         # let's check the record file was created with four
         # lines, one for each .dist-info entry: METADATA,
         # INSTALLER, REQUSTED, RECORD
-        with open(cmd.record) as f:
-            self.assertEqual(len(f.readlines()), 4)
+        f = open(cmd.record)
+        lines = f.readlines()
+        f.close()
+        self.assertEqual(len(lines), 4)
+
 
         # XXX test that fancy_getopt is okay with options named
         # record and no-record but unrelated
diff --git a/distutils2/tests/test_command_install_distinfo.py b/distutils2/tests/test_command_install_distinfo.py
--- a/distutils2/tests/test_command_install_distinfo.py
+++ b/distutils2/tests/test_command_install_distinfo.py
@@ -2,8 +2,10 @@
 
 import os
 import csv
-import hashlib
-import sys
+try:
+    import hashlib
+except:
+    from distutils2._backport import hashlib
 
 from distutils2.command.install_distinfo import install_distinfo
 from distutils2.command.cmd import Command
@@ -55,10 +57,16 @@
         dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
         self.checkLists(os.listdir(dist_info),
                         ['METADATA', 'RECORD', 'REQUESTED', 'INSTALLER'])
-        with open(os.path.join(dist_info, 'INSTALLER')) as fp:
-            self.assertEqual(fp.read(), 'distutils')
-        with open(os.path.join(dist_info, 'REQUESTED')) as fp:
-            self.assertEqual(fp.read(), '')
+        fp = open(os.path.join(dist_info, 'INSTALLER'))
+        content = fp.read()
+        fp.close()
+        self.assertEqual(content, 'distutils')
+
+        fp = open(os.path.join(dist_info, 'REQUESTED'))
+        content = fp.read()
+        fp.close()
+        self.assertEqual(content, '')
+
         meta_path = os.path.join(dist_info, 'METADATA')
         self.assertTrue(Metadata(path=meta_path).check())
 
@@ -80,8 +88,10 @@
         cmd.run()
 
         dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
-        with open(os.path.join(dist_info, 'INSTALLER')) as fp:
-            self.assertEqual(fp.read(), 'bacon-python')
+        fp = open(os.path.join(dist_info, 'INSTALLER'))
+        content = fp.read()
+        fp.close()
+        self.assertEqual(content, 'bacon-python')
 
     def test_requested(self):
         pkg_dir, dist = self.create_dist(name='foo',
@@ -162,23 +172,25 @@
 
         expected = []
         for f in install.get_outputs():
-            if (f.endswith(('.pyc', '.pyo')) or f == os.path.join(
+            if (f.endswith('.pyc',) or f.endswith('.pyo') or f == os.path.join(
                 install_dir, 'foo-1.0.dist-info', 'RECORD')):
                 expected.append([f, '', ''])
             else:
                 size = os.path.getsize(f)
                 md5 = hashlib.md5()
-                with open(f, 'rb') as fp:
-                    md5.update(fp.read())
+                fp = open(f, 'rb')
+                md5.update(fp.read())
+                fp.close()
                 hash = md5.hexdigest()
                 expected.append([f, hash, str(size)])
 
         parsed = []
-        with open(os.path.join(dist_info, 'RECORD'), 'r') as f:
-            reader = csv.reader(f, delimiter=',',
-                                   lineterminator=os.linesep,
-                                   quotechar='"')
-            parsed = list(reader)
+        f = open(os.path.join(dist_info, 'RECORD'), 'r')
+        reader = csv.reader(f, delimiter=',',
+                               lineterminator=os.linesep,
+                               quotechar='"')
+        parsed = list(reader)
+        f.close()
 
         self.maxDiff = None
         self.checkLists(parsed, expected)
diff --git a/distutils2/tests/test_command_install_scripts.py b/distutils2/tests/test_command_install_scripts.py
--- a/distutils2/tests/test_command_install_scripts.py
+++ b/distutils2/tests/test_command_install_scripts.py
@@ -38,8 +38,9 @@
 
         def write_script(name, text):
             expected.append(name)
-            with open(os.path.join(source, name), "w") as f:
-                f.write(text)
+            f = open(os.path.join(source, name), "w")
+            f.write(text)
+            f.close()
 
         write_script("script1.py", ("#! /usr/bin/env python2.3\n"
                                     "# bogus script w/ Python sh-bang\n"
diff --git a/distutils2/tests/test_command_register.py b/distutils2/tests/test_command_register.py
--- a/distutils2/tests/test_command_register.py
+++ b/distutils2/tests/test_command_register.py
@@ -128,8 +128,9 @@
         self.assertTrue(os.path.exists(self.rc))
 
         # with the content similar to WANTED_PYPIRC
-        with open(self.rc) as fp:
-            content = fp.read()
+        fp = open(self.rc)
+        content = fp.read()
+        fp.close()
         self.assertEqual(content, WANTED_PYPIRC)
 
         # now let's make sure the .pypirc file generated
@@ -149,7 +150,7 @@
         req1 = dict(self.conn.reqs[0].headers)
         req2 = dict(self.conn.reqs[1].headers)
         self.assertEqual(req2['Content-length'], req1['Content-length'])
-        self.assertIn(b'xxx', self.conn.reqs[1].data)
+        self.assertIn('xxx', self.conn.reqs[1].data)
 
     def test_password_not_in_file(self):
 
@@ -178,7 +179,7 @@
         req = self.conn.reqs[0]
         headers = dict(req.headers)
         self.assertEqual(headers['Content-length'], '628')
-        self.assertIn(b'tarek', req.data)
+        self.assertIn('tarek', req.data)
 
     def test_password_reset(self):
         # this test runs choice 3
@@ -193,7 +194,7 @@
         req = self.conn.reqs[0]
         headers = dict(req.headers)
         self.assertEqual(headers['Content-length'], '298')
-        self.assertIn(b'tarek', req.data)
+        self.assertIn('tarek', req.data)
 
     @unittest.skipUnless(DOCUTILS_SUPPORT, 'needs docutils')
     def test_strict(self):
diff --git a/distutils2/tests/test_command_sdist.py b/distutils2/tests/test_command_sdist.py
--- a/distutils2/tests/test_command_sdist.py
+++ b/distutils2/tests/test_command_sdist.py
@@ -213,8 +213,9 @@
         self.assertEqual(len(content), 10)
 
         # Checking the MANIFEST
-        with open(join(self.tmp_dir, 'MANIFEST')) as fp:
-            manifest = fp.read()
+        fp = open(join(self.tmp_dir, 'MANIFEST'))
+        manifest = fp.read()
+        fp.close()
         self.assertEqual(manifest, MANIFEST % {'sep': os.sep})
 
     @requires_zlib
@@ -330,9 +331,10 @@
 
         # Should produce four lines. Those lines are one comment, one default
         # (README) and two package files.
-        with open(cmd.manifest) as f:
-            manifest = [line.strip() for line in f.read().split('\n')
-                        if line.strip() != '']
+        f = open(cmd.manifest)
+        manifest = [line.strip() for line in f.read().split('\n')
+                    if line.strip() != '']
+        f.close()
         self.assertEqual(len(manifest), 3)
 
         # Adding a file
@@ -345,9 +347,10 @@
 
         cmd.run()
 
-        with open(cmd.manifest) as f:
-            manifest2 = [line.strip() for line in f.read().split('\n')
-                         if line.strip() != '']
+        f = open(cmd.manifest)
+        manifest2 = [line.strip() for line in f.read().split('\n')
+                     if line.strip() != '']
+        f.close()
 
         # Do we have the new file in MANIFEST?
         self.assertEqual(len(manifest2), 4)
@@ -360,9 +363,10 @@
         cmd.ensure_finalized()
         cmd.run()
 
-        with open(cmd.manifest) as f:
-            manifest = [line.strip() for line in f.read().split('\n')
-                        if line.strip() != '']
+        f = open(cmd.manifest)
+        manifest = [line.strip() for line in f.read().split('\n')
+                    if line.strip() != '']
+        f.close()
 
         self.assertEqual(manifest[0],
                          '# file GENERATED by distutils2, do NOT edit')
@@ -375,9 +379,10 @@
         self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
         cmd.run()
 
-        with open(cmd.manifest) as f:
-            manifest = [line.strip() for line in f.read().split('\n')
-                        if line.strip() != '']
+        f = open(cmd.manifest)
+        manifest = [line.strip() for line in f.read().split('\n')
+                    if line.strip() != '']
+        f.close()
 
         self.assertEqual(manifest, ['README.manual'])
 
@@ -388,8 +393,9 @@
         cmd.ensure_finalized()
         self.write_file((self.tmp_dir, 'yeah'), 'xxx')
         cmd.run()
-        with open(cmd.manifest) as f:
-            content = f.read()
+        f = open(cmd.manifest)
+        content = f.read()
+        f.close()
 
         self.assertIn('yeah', content)
 
diff --git a/distutils2/tests/test_command_upload.py b/distutils2/tests/test_command_upload.py
--- a/distutils2/tests/test_command_upload.py
+++ b/distutils2/tests/test_command_upload.py
@@ -1,6 +1,5 @@
 """Tests for distutils2.command.upload."""
 import os
-import sys
 
 from distutils2.command.upload import upload
 from distutils2.dist import Distribution
@@ -44,7 +43,6 @@
 """
 
 
- at unittest.skipIf(threading is None, 'needs threading')
 class UploadTestCase(support.TempdirManager, support.EnvironRestorer,
                      support.LoggingCatcher, PyPIServerTestCase):
 
@@ -114,7 +112,7 @@
         handler, request_data = self.pypi.requests[-1]
         headers = handler.headers
         #self.assertIn('d\xc3d\xc3', str(request_data))
-        self.assertIn(b'xxx', request_data)
+        self.assertIn('xxx', request_data)
 
         self.assertEqual(int(headers['content-length']), len(request_data))
         self.assertLess(int(headers['content-length']), 2500)
@@ -152,10 +150,12 @@
             "----------------GHSKFJDLGDS7543FJKLFHRE75642756743254"
             .encode())[1:4]
 
-        self.assertIn(b'name=":action"', action)
-        self.assertIn(b'doc_upload', action)
+        self.assertIn('name=":action"', action)
+        self.assertIn('doc_upload', action)
 
 
+UploadTestCase = unittest.skipIf(threading is None, 'needs threading')(
+        UploadTestCase)
 def test_suite():
     return unittest.makeSuite(UploadTestCase)
 
diff --git a/distutils2/tests/test_command_upload_docs.py b/distutils2/tests/test_command_upload_docs.py
--- a/distutils2/tests/test_command_upload_docs.py
+++ b/distutils2/tests/test_command_upload_docs.py
@@ -1,6 +1,5 @@
 """Tests for distutils2.command.upload_docs."""
 import os
-import sys
 import shutil
 import zipfile
 try:
@@ -33,8 +32,8 @@
 """
 
 
- at unittest.skipIf(threading is None, "Needs threading")
-class UploadDocsTestCase(support.TempdirManager,
+class UploadDocsTestCase(unittest.TestCase,
+                         support.TempdirManager,
                          support.EnvironRestorer,
                          support.LoggingCatcher,
                          PyPIServerTestCase):
@@ -103,7 +102,7 @@
 
         self.assertEqual(len(self.pypi.requests), 1)
         handler, request_data = self.pypi.requests[-1]
-        self.assertIn(b"content", request_data)
+        self.assertIn("content", request_data)
         self.assertIn("Basic", handler.headers['authorization'])
         self.assertTrue(handler.headers['content-type']
             .startswith('multipart/form-data;'))
@@ -113,16 +112,16 @@
 
 
         # check that we picked the right chunks
-        self.assertIn(b'name=":action"', action)
-        self.assertIn(b'name="name"', name)
-        self.assertIn(b'name="version"', version)
-        self.assertIn(b'name="content"', content)
+        self.assertIn('name=":action"', action)
+        self.assertIn('name="name"', name)
+        self.assertIn('name="version"', version)
+        self.assertIn('name="content"', content)
 
         # check their contents
-        self.assertIn(b'doc_upload', action)
-        self.assertIn(b'distr-name', name)
-        self.assertIn(b'docs/index.html', content)
-        self.assertIn(b'Ce mortel ennui', content)
+        self.assertIn('doc_upload', action)
+        self.assertIn('distr-name', name)
+        self.assertIn('docs/index.html', content)
+        self.assertIn('Ce mortel ennui', content)
 
     @unittest.skipIf(_ssl is None, 'Needs SSL support')
     def test_https_connection(self):
@@ -184,6 +183,7 @@
         self.assertTrue(record, "should report the response")
         self.assertIn(self.pypi.default_response_data, record)
 
+UploadDocsTestCase = unittest.skipIf(threading is None, "Needs threading")(UploadDocsTestCase)
 def test_suite():
     return unittest.makeSuite(UploadDocsTestCase)
 
diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py
--- a/distutils2/tests/test_config.py
+++ b/distutils2/tests/test_config.py
@@ -440,8 +440,10 @@
         cmd.finalize_options()
         cmd.get_file_list()
         cmd.make_distribution()
-        with open('MANIFEST') as fp:
-            self.assertIn('README\nREADME2\n', fp.read())
+        fp = open('MANIFEST')
+        content = fp.read()
+        fp.close()
+        self.assertIn('README\nREADME2\n', content)
 
     def test_sub_commands(self):
         self.write_setup()
diff --git a/distutils2/tests/test_create.py b/distutils2/tests/test_create.py
--- a/distutils2/tests/test_create.py
+++ b/distutils2/tests/test_create.py
@@ -1,5 +1,6 @@
 """Tests for distutils2.create."""
 from StringIO import StringIO
+import codecs
 import os
 import sys
 import sysconfig
@@ -135,8 +136,10 @@
         sys.stdin.seek(0)
         main()
 
-        with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp:
-            contents = fp.read()
+        fp = codecs.open(os.path.join(self.wdir, 'setup.cfg'),
+                encoding='utf-8')
+        contents = fp.read()
+        fp.close()
 
         self.assertEqual(contents, dedent(u"""\
             [metadata]
@@ -181,8 +184,9 @@
                         dedent(u"""
         # coding: utf-8
         from distutils.core import setup
-        with open('README.txt') as fp:
-            long_description = fp.read()
+        fp = open('README.txt')
+        long_description = fp.read()
+        fp.close()
 
         setup(name='pyxfoil',
               version='0.2',
@@ -210,8 +214,9 @@
         sys.stdin.seek(0)
         # FIXME Out of memory error.
         main()
-        with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp:
-            contents = fp.read()
+        fp = codecs.open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8')
+        contents = fp.read()
+        fp.close()
 
         self.assertEqual(contents, dedent(u"""\
             [metadata]
diff --git a/distutils2/tests/test_database.py b/distutils2/tests/test_database.py
--- a/distutils2/tests/test_database.py
+++ b/distutils2/tests/test_database.py
@@ -3,8 +3,14 @@
 import sys
 import shutil
 import tempfile
-from os.path import relpath  # separate import for backport concerns
-from hashlib import md5
+try:
+    from os.path import relpath  # separate import for backport concerns
+except:
+    from distutils2._backport.path import relpath
+try:
+    from hashlib import md5
+except ImportError:
+    from distutils2._backport.hashlib import md5
 from textwrap import dedent
 
 from distutils2.tests.test_util import GlobTestCaseBase
@@ -26,8 +32,9 @@
 
 
 def get_hexdigest(filename):
-    with open(filename, 'rb') as file:
-        checksum = md5(file.read())
+    fp = open(filename, 'rb')
+    checksum = md5(fp.read())
+    fp.close()
     return checksum.hexdigest()
 
 
@@ -58,11 +65,11 @@
         # could pass a custom copy_function to change the mode of files, but
         # shutil gives no control over the mode of directories :(
         for root, dirs, files in os.walk(self.fake_dists_path):
-            os.chmod(root, 0o755)
+            os.chmod(root, 00755)
             for f in files:
-                os.chmod(os.path.join(root, f), 0o644)
+                os.chmod(os.path.join(root, f), 00644)
             for d in dirs:
-                os.chmod(os.path.join(root, d), 0o755)
+                os.chmod(os.path.join(root, d), 00755)
 
 
 class CommonDistributionTests(FakeDistsMixin):
@@ -131,31 +138,33 @@
         for distinfo_dir in self.dirs:
 
             record_file = os.path.join(distinfo_dir, 'RECORD')
-            with open(record_file, 'w') as file:
-                record_writer = csv.writer(
-                    file, delimiter=',', quoting=csv.QUOTE_NONE,
-                    lineterminator='\n')
+            fp = open(record_file, 'w')
+            record_writer = csv.writer(
+                fp, delimiter=',', quoting=csv.QUOTE_NONE,
+                lineterminator='\n')
 
-                dist_location = distinfo_dir.replace('.dist-info', '')
+            dist_location = distinfo_dir.replace('.dist-info', '')
 
-                for path, dirs, files in os.walk(dist_location):
-                    for f in files:
-                        record_writer.writerow(record_pieces(
-                                               os.path.join(path, f)))
-                for file in ('INSTALLER', 'METADATA', 'REQUESTED'):
+            for path, dirs, files in os.walk(dist_location):
+                for f in files:
                     record_writer.writerow(record_pieces(
-                                           os.path.join(distinfo_dir, file)))
-                record_writer.writerow([relpath(record_file, sys.prefix)])
+                                           os.path.join(path, f)))
+            for file in ('INSTALLER', 'METADATA', 'REQUESTED'):
+                record_writer.writerow(record_pieces(
+                                       os.path.join(distinfo_dir, file)))
+            record_writer.writerow([relpath(record_file, sys.prefix)])
+            fp.close()
 
-            with open(record_file) as file:
-                record_reader = csv.reader(file, lineterminator='\n')
-                record_data = {}
-                for row in record_reader:
-                    if row == []:
-                        continue
-                    path, md5_, size = (row[:] +
-                                        [None for i in range(len(row), 3)])
-                    record_data[path] = md5_, size
+            fp = open(record_file)
+            record_reader = csv.reader(fp, lineterminator='\n')
+            record_data = {}
+            for row in record_reader:
+                if row == []:
+                    continue
+                path, md5_, size = (row[:] +
+                                    [None for i in range(len(row), 3)])
+                record_data[path] = md5_, size
+            fp.close()
             self.records[distinfo_dir] = record_data
 
     def test_instantiation(self):
@@ -197,11 +206,12 @@
         ]
 
         for distfile in distinfo_files:
-            with dist.get_distinfo_file(distfile) as value:
-                self.assertIsInstance(value, file)
-                # Is it the correct file?
-                self.assertEqual(value.name,
-                                 os.path.join(distinfo_dir, distfile))
+            value = dist.get_distinfo_file(distfile)
+            self.assertIsInstance(value, file)
+            # Is it the correct file?
+            self.assertEqual(value.name,
+                             os.path.join(distinfo_dir, distfile))
+            value.close()
 
         # Test an absolute path that is part of another distributions dist-info
         other_distinfo_file = os.path.join(
@@ -621,26 +631,28 @@
         metadata_path = os.path.join(dist_info, 'METADATA')
         resources_path = os.path.join(dist_info, 'RESOURCES')
 
-        with open(metadata_path, 'w') as fp:
-            fp.write(dedent("""\
-                Metadata-Version: 1.2
-                Name: test
-                Version: 0.1
-                Summary: test
-                Author: me
-                """))
-
+        fp = open(metadata_path, 'w')
+        fp.write(dedent("""\
+            Metadata-Version: 1.2
+            Name: test
+            Version: 0.1
+            Summary: test
+            Author: me
+            """))
+        fp.close()
         test_path = 'test.cfg'
 
         fd, test_resource_path = tempfile.mkstemp()
         os.close(fd)
         self.addCleanup(os.remove, test_resource_path)
 
-        with open(test_resource_path, 'w') as fp:
-            fp.write('Config')
+        fp = open(test_resource_path, 'w')
+        fp.write('Config')
+        fp.close()
 
-        with open(resources_path, 'w') as fp:
-            fp.write('%s,%s' % (test_path, test_resource_path))
+        fp = open(resources_path, 'w')
+        fp.write('%s,%s' % (test_path, test_resource_path))
+        fp.close()
 
         # Add fake site-packages to sys.path to retrieve fake dist
         self.addCleanup(sys.path.remove, temp_site_packages)
@@ -655,8 +667,9 @@
                          test_resource_path)
         self.assertRaises(KeyError, get_file_path, dist_name, 'i-dont-exist')
 
-        with get_file(dist_name, test_path) as fp:
-            self.assertEqual(fp.read(), 'Config')
+        fp = get_file(dist_name, test_path)
+        self.assertEqual(fp.read(), 'Config')
+        fp.close()
         self.assertRaises(KeyError, get_file, dist_name, 'i-dont-exist')
 
 
diff --git a/distutils2/tests/test_dist.py b/distutils2/tests/test_dist.py
--- a/distutils2/tests/test_dist.py
+++ b/distutils2/tests/test_dist.py
@@ -13,10 +13,10 @@
 from distutils2.command.cmd import Command
 from distutils2.metadata import Metadata
 from distutils2.errors import PackagingModuleError, PackagingOptionError
-from distutils2.tests import TESTFN, captured_stdout
+from distutils2.tests import captured_stdout
 from distutils2.tests import support, unittest
 from distutils2.tests.support import create_distribution
-from .support import unload
+from distutils2.tests.support import unload, TESTFN
 
 
 class test_dist(Command):
@@ -52,9 +52,10 @@
 
     def test_debug_mode(self):
         self.addCleanup(os.unlink, TESTFN)
-        with open(TESTFN, "w") as f:
-            f.write("[global]\n")
-            f.write("command_packages = foo.bar, splat")
+        f = open(TESTFN, "w")
+        f.write("[global]\n")
+        f.write("command_packages = foo.bar, splat")
+        f.close()
 
         files = [TESTFN]
         sys.argv.append("build")
@@ -82,8 +83,9 @@
         # let's make sure the file can be written
         # with Unicode fields. they are encoded with
         # PKG_INFO_ENCODING
-        with codecs.open(my_file, 'w', encoding='utf-8') as fp:
-            dist.metadata.write_file(fp)
+        fp = codecs.open(my_file, 'w', encoding='utf-8')
+        dist.metadata.write_file(fp)
+        fp.close()
 
         # regular ascii is of course always usable
         dist = cls(attrs={'author': 'Mister Cafe',
@@ -92,8 +94,9 @@
                           'summary': 'Cafe torrefie',
                           'description': 'Hehehe'})
 
-        with open(my_file, 'w') as fp:
-            dist.metadata.write_file(fp)
+        fp = open(my_file, 'w')
+        dist.metadata.write_file(fp)
+        fp.close()
 
     def test_bad_attr(self):
         Distribution(attrs={'author': 'xxx',
@@ -161,8 +164,9 @@
         else:
             user_filename = os.path.join(temp_home, "pydistutils.cfg")
 
-        with open(user_filename, 'w') as f:
-            f.write('[distutils2]\n')
+        f = open(user_filename, 'w')
+        f.write('[distutils2]\n')
+        f.close()
 
         def _expander(path):
             return temp_home
@@ -176,8 +180,10 @@
             d = distutils2.dist.Distribution(attrs={'script_args':
                                                    ['--no-user-cfg']})
             files = d.find_config_files()
-        finally:
+        except:
             os.path.expanduser = old_expander
+            raise
+        os.path.expanduser = old_expander
 
         # make sure --no-user-cfg disables the user cfg file
         self.assertEqual((len(all_files) - 1), len(files))
@@ -373,8 +379,9 @@
 
         temp_dir = self.mkdtemp()
         user_filename = os.path.join(temp_dir, user_filename)
-        with open(user_filename, 'w') as f:
-            f.write('.')
+        f = open(user_filename, 'w')
+        f.write('.')
+        f.close()
 
         dist = Distribution()
 
diff --git a/distutils2/tests/test_manifest.py b/distutils2/tests/test_manifest.py
--- a/distutils2/tests/test_manifest.py
+++ b/distutils2/tests/test_manifest.py
@@ -37,8 +37,9 @@
     def test_manifest_reader(self):
         tmpdir = self.mkdtemp()
         MANIFEST = os.path.join(tmpdir, 'MANIFEST.in')
-        with open(MANIFEST, 'w') as f:
-            f.write(_MANIFEST)
+        f = open(MANIFEST, 'w')
+        f.write(_MANIFEST)
+        f.close()
 
         manifest = Manifest()
         manifest.read_template(MANIFEST)
@@ -51,8 +52,9 @@
             self.assertIn('no files found matching', warning)
 
         # manifest also accepts file-like objects
-        with open(MANIFEST) as f:
-            manifest.read_template(f)
+        f = open(MANIFEST)
+        manifest.read_template(f)
+        f.close()
 
         # the manifest should have been read and 3 warnings issued
         # (we didn't provide the files)
diff --git a/distutils2/tests/test_markers.py b/distutils2/tests/test_markers.py
--- a/distutils2/tests/test_markers.py
+++ b/distutils2/tests/test_markers.py
@@ -17,7 +17,10 @@
         os_name = os.name
         platform_version = platform.version()
         platform_machine = platform.machine()
-        platform_python_implementation = platform.python_implementation()
+        try:
+            platform_python_implementation = platform.python_implementation()
+        except AttributeError: #assume CPython
+            platform_python_implementation = 'CPython'
 
         self.assertTrue(interpret("sys.platform == '%s'" % sys_platform))
         self.assertTrue(interpret(
diff --git a/distutils2/tests/test_metadata.py b/distutils2/tests/test_metadata.py
--- a/distutils2/tests/test_metadata.py
+++ b/distutils2/tests/test_metadata.py
@@ -18,8 +18,10 @@
 
     def test_instantiation(self):
         PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
-        with codecs.open(PKG_INFO, 'r', encoding='utf-8') as f:
-            contents = f.read()
+        f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+        contents = f.read()
+        f.close()
+
         fp = StringIO(contents)
 
         m = Metadata()
@@ -58,8 +60,9 @@
     def test_metadata_markers(self):
         # see if we can be platform-aware
         PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
-        with codecs.open(PKG_INFO, 'r', encoding='utf-8') as f:
-            content = f.read() % sys.platform
+        f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+        content = f.read() % sys.platform
+        f.close()
         metadata = Metadata(platform_dependent=True)
 
         metadata.read_file(StringIO(content))
@@ -78,15 +81,17 @@
 
     def test_description(self):
         PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
-        with codecs.open(PKG_INFO, 'r', encoding='utf-8') as f:
-            content = f.read() % sys.platform
+        f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+        content = f.read() % sys.platform
+        f.close()
         metadata = Metadata()
         metadata.read_file(StringIO(content))
 
         # see if we can read the description now
         DESC = os.path.join(os.path.dirname(__file__), 'LONG_DESC.txt')
-        with open(DESC) as f:
-            wanted = f.read()
+        f = open(DESC)
+        wanted = f.read()
+        f.close()
         self.assertEqual(wanted, metadata['Description'])
 
         # save the file somewhere and make sure we can read it back
@@ -98,8 +103,9 @@
 
     def test_mapping_api(self):
         PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
-        with codecs.open(PKG_INFO, 'r', encoding='utf-8') as f:
-            content = f.read() % sys.platform
+        f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+        content = f.read() % sys.platform
+        f.close()
         metadata = Metadata(fileobj=StringIO(content))
         self.assertIn('Version', metadata.keys())
         self.assertIn('0.5', metadata.values())
@@ -131,15 +137,18 @@
 
         PKG_INFO = os.path.join(os.path.dirname(__file__),
                                 'SETUPTOOLS-PKG-INFO')
-        with codecs.open(PKG_INFO, 'r', encoding='utf-8') as f:
-            content = f.read()
+        f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+        content = f.read()
+        f.close()
         metadata.read_file(StringIO(content))
         self.assertEqual(metadata['Metadata-Version'], '1.0')
 
         PKG_INFO = os.path.join(os.path.dirname(__file__),
                                 'SETUPTOOLS-PKG-INFO2')
-        with codecs.open(PKG_INFO, 'r', encoding='utf-8') as f:
-            content = f.read()
+        f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
+        content = f.read()
+        f.close()
+
         metadata.read_file(StringIO(content))
         self.assertEqual(metadata['Metadata-Version'], '1.1')
 
diff --git a/distutils2/tests/test_mixin2to3.py b/distutils2/tests/test_mixin2to3.py
--- a/distutils2/tests/test_mixin2to3.py
+++ b/distutils2/tests/test_mixin2to3.py
@@ -1,4 +1,3 @@
-import sys
 import textwrap
 
 from distutils2.tests import unittest, support
@@ -15,15 +14,17 @@
         # used to check if code gets converted properly.
         code = "print 'test'"
 
-        with self.mktempfile() as fp:
-            fp.write(code)
+        fp = self.mktempfile()
+        fp.write(code)
+        fp.close()
 
         mixin2to3 = Mixin2to3()
         mixin2to3._run_2to3([fp.name])
         expected = "print('test')"
 
-        with open(fp.name) as fp:
-            converted = fp.read()
+        fp = open(fp.name)
+        converted = fp.read()
+        fp.close()
 
         self.assertEqual(expected, converted)
 
@@ -40,8 +41,9 @@
             It works.
             """''')
 
-        with self.mktempfile() as fp:
-            fp.write(doctest)
+        fp = self.mktempfile()
+        fp.write(doctest)
+        fp.close()
 
         mixin2to3 = Mixin2to3()
         mixin2to3._run_2to3([fp.name])
@@ -54,8 +56,9 @@
             It works.
             """\n''')
 
-        with open(fp.name) as fp:
-            converted = fp.read()
+        fp = open(fp.name)
+        converted = fp.read()
+        fp.close()
 
         self.assertEqual(expected, converted)
 
@@ -65,8 +68,9 @@
         # used to check if use_2to3_fixers works
         code = 'type(x) is not T'
 
-        with self.mktempfile() as fp:
-            fp.write(code)
+        fp = self.mktempfile()
+        fp.write(code)
+        fp.close()
 
         mixin2to3 = Mixin2to3()
         mixin2to3._run_2to3(files=[fp.name], doctests=[fp.name],
@@ -74,8 +78,9 @@
 
         expected = 'not isinstance(x, T)'
 
-        with open(fp.name) as fp:
-            converted = fp.read()
+        fp = open(fp.name)
+        converted = fp.read()
+        fp.close()
 
         self.assertEqual(expected, converted)
 
diff --git a/distutils2/tests/test_msvc9compiler.py b/distutils2/tests/test_msvc9compiler.py
--- a/distutils2/tests/test_msvc9compiler.py
+++ b/distutils2/tests/test_msvc9compiler.py
@@ -118,16 +118,18 @@
         from distutils2.compiler.msvc9compiler import MSVCCompiler
         tempdir = self.mkdtemp()
         manifest = os.path.join(tempdir, 'manifest')
-        with open(manifest, 'w') as f:
-            f.write(_MANIFEST)
+        f = open(manifest, 'w')
+        f.write(_MANIFEST)
+        f.close()
 
         compiler = MSVCCompiler()
         compiler._remove_visual_c_ref(manifest)
 
         # see what we got
-        with open(manifest) as f:
-            # removing trailing spaces
-            content = '\n'.join(line.rstrip() for line in f.readlines())
+        f = open(manifest)
+        # removing trailing spaces
+        content = '\n'.join(line.rstrip() for line in f.readlines())
+        f.close()
 
         # makes sure the manifest was properly cleaned
         self.assertEqual(content, _CLEANED_MANIFEST)
diff --git a/distutils2/tests/test_pypi_server.py b/distutils2/tests/test_pypi_server.py
--- a/distutils2/tests/test_pypi_server.py
+++ b/distutils2/tests/test_pypi_server.py
@@ -13,8 +13,6 @@
 
 from distutils2.tests import unittest
 
-
- at unittest.skipIf(threading is None, "Needs threading")
 class PyPIServerTest(unittest.TestCase):
 
     def test_records_requests(self):
@@ -26,7 +24,7 @@
             server.start()
             self.assertEqual(len(server.requests), 0)
 
-            data = b'Rock Around The Bunker'
+            data = 'Rock Around The Bunker'
 
             headers = {"X-test-header": "Mister Iceberg"}
 
@@ -38,9 +36,10 @@
             self.assertIn("x-test-header", handler.headers)
             self.assertEqual(handler.headers["x-test-header"], "Mister Iceberg")
 
-        finally:
+        except:
             server.stop()
-
+            raise
+        server.stop()
 
     def test_serve_static_content(self):
         # PYPI Mocked server can serve static content from disk.
@@ -52,9 +51,11 @@
             url = server.full_address + url_path
             request = urllib2.Request(url)
             response = urllib2.urlopen(request)
-            with open(PYPI_DEFAULT_STATIC_PATH + "/test_pypi_server"
-                      + url_path) as file:
-                return response.read().decode() == file.read()
+            fp = open(PYPI_DEFAULT_STATIC_PATH + "/test_pypi_server"
+                    + url_path)
+            content = fp.read()
+            fp.close()
+            return response.read().decode() == content
 
         server = PyPIServer(static_uri_paths=["simple", "external"],
             static_filesystem_paths=["test_pypi_server"])
@@ -74,9 +75,13 @@
             # and another one in another root path
             self.assertTrue(uses_local_files_for(server, "/external/index.html"))
 
-        finally:
+        except:
             server.stop()
+            raise
+        server.stop()
 
+PyPIServerTest = unittest.skipIf(threading is None, "Needs threading")(
+        PyPIServerTest)
 
 def test_suite():
     return unittest.makeSuite(PyPIServerTest)
diff --git a/distutils2/tests/test_pypi_simple.py b/distutils2/tests/test_pypi_simple.py
--- a/distutils2/tests/test_pypi_simple.py
+++ b/distutils2/tests/test_pypi_simple.py
@@ -71,14 +71,14 @@
         url = 'http://example.org'
         try:
             v = crawler._open_url(url)
-        except Exception:
+        except:
+            urllib2.urlopen = old_urlopen
             self.assertIn('line', str(sys.exc_info()[1]))
         else:
             v.close()
             # TODO use self.assertRaises
             raise AssertionError('Should have raise here!')
-        finally:
-            urllib2.urlopen = old_urlopen
+        urllib2.urlopen = old_urlopen
 
         # issue 20
         url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk'
@@ -246,9 +246,12 @@
 
             # this should not raise a timeout
             self.assertEqual(4, len(crawler.get_releases("foo")))
-        finally:
+        except:
             mirror.stop()
             server.stop()
+            raise
+        mirror.stop()
+        server.stop()
 
     def test_simple_link_matcher(self):
         # Test that the simple link matcher finds the right links"""
@@ -273,21 +276,21 @@
         # Test that the simple link matcher yield the good links.
         generator = crawler._simple_link_matcher(content, crawler.index_url)
         self.assertEqual(('%stest/foobar-1.tar.gz#md5=abcdef' %
-                          crawler.index_url, True), next(generator))
-        self.assertEqual(('http://dl-link1', True), next(generator))
+                          crawler.index_url, True), generator.next())
+        self.assertEqual(('http://dl-link1', True), generator.next())
         self.assertEqual(('%stest' % crawler.index_url, False),
-                         next(generator))
+                         generator.next())
         self.assertRaises(StopIteration, generator.next)
 
         # Follow the external links is possible (eg. homepages)
         crawler.follow_externals = True
         generator = crawler._simple_link_matcher(content, crawler.index_url)
         self.assertEqual(('%stest/foobar-1.tar.gz#md5=abcdef' %
-                          crawler.index_url, True), next(generator))
-        self.assertEqual(('http://dl-link1', True), next(generator))
-        self.assertEqual(('http://dl-link2', False), next(generator))
+                          crawler.index_url, True), generator.next())
+        self.assertEqual(('http://dl-link1', True), generator.next())
+        self.assertEqual(('http://dl-link2', False), generator.next())
         self.assertEqual(('%stest' % crawler.index_url, False),
-                         next(generator))
+                         generator.next())
         self.assertRaises(StopIteration, generator.next)
 
     def test_browse_local_files(self):
diff --git a/distutils2/tests/test_pypi_xmlrpc.py b/distutils2/tests/test_pypi_xmlrpc.py
--- a/distutils2/tests/test_pypi_xmlrpc.py
+++ b/distutils2/tests/test_pypi_xmlrpc.py
@@ -13,7 +13,6 @@
     use_xmlrpc_server = fake_dec
 
 
- at unittest.skipIf(threading is None, "Needs threading")
 class TestXMLRPCClient(unittest.TestCase):
     def _get_client(self, server, *args, **kwargs):
         return Client(server.full_address, *args, **kwargs)
@@ -91,6 +90,9 @@
         self.assertEqual(['Foo'], release.metadata['requires_external'])
         self.assertEqual(['FooFoo'], release.metadata['obsoletes_dist'])
 
+#Compatibility Python pre-2.6
+TestXMLRPCClient = unittest.skipIf(threading is None, "Needs threading")(
+        TestXMLRPCClient)
 
 def test_suite():
     suite = unittest.TestSuite()
diff --git a/distutils2/tests/test_run.py b/distutils2/tests/test_run.py
--- a/distutils2/tests/test_run.py
+++ b/distutils2/tests/test_run.py
@@ -3,11 +3,11 @@
 import os
 import sys
 import shutil
-from tempfile import mkstemp
 from StringIO import StringIO
 
 from distutils2 import install
-from distutils2.tests import unittest, support, TESTFN
+from distutils2.tests import unittest, support
+from distutils2.tests.support import TESTFN
 from distutils2.run import main
 
 # setup script that uses __file__
@@ -53,8 +53,9 @@
             shutil.rmtree(path)
 
     def write_setup(self, text, path=TESTFN):
-        with open(path, "w") as fp:
-            fp.write(text)
+        fp = open(path, "w")
+        fp.write(text)
+        fp.close()
         return path
 
     # TODO restore the tests removed six months ago and port them to pysetup
diff --git a/distutils2/tests/test_util.py b/distutils2/tests/test_util.py
--- a/distutils2/tests/test_util.py
+++ b/distutils2/tests/test_util.py
@@ -55,20 +55,20 @@
 """
 
 EXPECTED_MULTIPART_OUTPUT = [
-    b'---x',
-    b'Content-Disposition: form-data; name="username"',
-    b'',
-    b'wok',
-    b'---x',
-    b'Content-Disposition: form-data; name="password"',
-    b'',
-    b'secret',
-    b'---x',
-    b'Content-Disposition: form-data; name="picture"; filename="wok.png"',
-    b'',
-    b'PNG89',
-    b'---x--',
-    b'',
+    '---x',
+    'Content-Disposition: form-data; name="username"',
+    '',
+    'wok',
+    '---x',
+    'Content-Disposition: form-data; name="password"',
+    '',
+    'secret',
+    '---x',
+    'Content-Disposition: form-data; name="picture"; filename="wok.png"',
+    '',
+    'PNG89',
+    '---x--',
+    '',
 ]
 
 
@@ -457,24 +457,24 @@
         if os.name == 'posix':
             exe = os.path.join(tmpdir, 'foo.sh')
             self.write_file(exe, '#!/bin/sh\nexit 1')
-            os.chmod(exe, 0o777)
+            os.chmod(exe, 00777)
         else:
             exe = os.path.join(tmpdir, 'foo.bat')
             self.write_file(exe, 'exit 1')
 
-        os.chmod(exe, 0o777)
+        os.chmod(exe, 00777)
         self.assertRaises(PackagingExecError, spawn, [exe])
 
         # now something that works
         if os.name == 'posix':
             exe = os.path.join(tmpdir, 'foo.sh')
             self.write_file(exe, '#!/bin/sh\nexit 0')
-            os.chmod(exe, 0o777)
+            os.chmod(exe, 00777)
         else:
             exe = os.path.join(tmpdir, 'foo.bat')
             self.write_file(exe, 'exit 0')
 
-        os.chmod(exe, 0o777)
+        os.chmod(exe, 00777)
         spawn([exe])  # should work without any error
 
     def test_server_registration(self):
@@ -506,8 +506,9 @@
         self.assertFalse(os.path.exists(rc))
         generate_pypirc('tarek', 'xxx')
         self.assertTrue(os.path.exists(rc))
-        with open(rc) as f:
-            content = f.read()
+        f = open(rc)
+        content = f.read()
+        f.close()
         self.assertEqual(content, WANTED)
 
     def test_cfg_to_args(self):
@@ -544,10 +545,10 @@
 
     def test_encode_multipart(self):
         fields = [('username', 'wok'), ('password', 'secret')]
-        files = [('picture', 'wok.png', b'PNG89')]
-        content_type, body = encode_multipart(fields, files, b'-x')
-        self.assertEqual(b'multipart/form-data; boundary=-x', content_type)
-        self.assertEqual(EXPECTED_MULTIPART_OUTPUT, body.split(b'\r\n'))
+        files = [('picture', 'wok.png', 'PNG89')]
+        content_type, body = encode_multipart(fields, files, '-x')
+        self.assertEqual('multipart/form-data; boundary=-x', content_type)
+        self.assertEqual(EXPECTED_MULTIPART_OUTPUT, body.split('\r\n'))
 
 
 class GlobTestCaseBase(support.TempdirManager,
@@ -793,16 +794,17 @@
             dir_paths.append(path)
         for f in files:
             path = os.path.join(tempdir, f)
-            with open(path, 'w') as _f:
-                _f.write(f)
+            _f = open(path, 'w')
+            _f.write(f)
+            _f.close()
             file_paths.append(path)
 
-        with open(record_file_path, 'w') as record_file:
-            for fpath in file_paths:
-                record_file.write(fpath + '\n')
-            for dpath in dir_paths:
-                record_file.write(dpath + '\n')
-
+        record_file = open(record_file_path, 'w')
+        for fpath in file_paths:
+            record_file.write(fpath + '\n')
+        for dpath in dir_paths:
+            record_file.write(dpath + '\n')
+        record_file.close()
         return (tempdir, record_file_path)
 
 
diff --git a/distutils2/util.py b/distutils2/util.py
--- a/distutils2/util.py
+++ b/distutils2/util.py
@@ -8,13 +8,19 @@
 import errno
 import shutil
 import string
-import hashlib
+try:
+    import hashlib
+except ImportError: #<2.5
+    from _backport import hashlib
 import tarfile
 import zipfile
 import posixpath
 import subprocess
 import sysconfig
-from glob import iglob as std_iglob
+try:
+    from glob import iglob as std_iglob
+except ImportError:#<2.5
+    from glob import glob as std_iglob
 from fnmatch import fnmatchcase
 from inspect import getsource
 from ConfigParser import RawConfigParser
@@ -359,34 +365,33 @@
             else:
                 script = codecs.open(script_name, "w", encoding='utf-8')
 
-            with script:
-                script.write("""\
+            script.write("""\
 from distutils2.util import byte_compile
 files = [
 """)
 
-                # XXX would be nice to write absolute filenames, just for
-                # safety's sake (script should be more robust in the face of
-                # chdir'ing before running it).  But this requires abspath'ing
-                # 'prefix' as well, and that breaks the hack in build_lib's
-                # 'byte_compile()' method that carefully tacks on a trailing
-                # slash (os.sep really) to make sure the prefix here is "just
-                # right".  This whole prefix business is rather delicate -- the
-                # problem is that it's really a directory, but I'm treating it
-                # as a dumb string, so trailing slashes and so forth matter.
+            # XXX would be nice to write absolute filenames, just for
+            # safety's sake (script should be more robust in the face of
+            # chdir'ing before running it).  But this requires abspath'ing
+            # 'prefix' as well, and that breaks the hack in build_lib's
+            # 'byte_compile()' method that carefully tacks on a trailing
+            # slash (os.sep really) to make sure the prefix here is "just
+            # right".  This whole prefix business is rather delicate -- the
+            # problem is that it's really a directory, but I'm treating it
+            # as a dumb string, so trailing slashes and so forth matter.
 
-                #py_files = map(os.path.abspath, py_files)
-                #if prefix:
-                #    prefix = os.path.abspath(prefix)
+            #py_files = map(os.path.abspath, py_files)
+            #if prefix:
+            #    prefix = os.path.abspath(prefix)
 
-                script.write(",\n".join(map(repr, py_files)) + "]\n")
-                script.write("""
+            script.write(",\n".join(map(repr, py_files)) + "]\n")
+            script.write("""
 byte_compile(files, optimize=%r, force=%r,
              prefix=%r, base_dir=%r,
              verbose=%r, dry_run=False,
              direct=True)
 """ % (optimize, force, prefix, base_dir, verbose))
-
+        script.close()
         cmd = [sys.executable, script_name]
         if optimize == 1:
             cmd.insert(1, "-O")
@@ -547,10 +552,10 @@
 
     *contents* is a sequence of strings without line terminators.
     """
-    with open(filename, "w") as f:
-        for line in contents:
-            f.write(line + "\n")
-
+    f = open(filename, "w")
+    for line in contents:
+        f.write(line + "\n")
+    f.close()
 
 def _is_package(path):
     return os.path.isdir(path) and os.path.isfile(
@@ -671,25 +676,28 @@
     """Unzip the file *filename* into the *location* directory."""
     if not os.path.exists(location):
         os.makedirs(location)
-    with open(filename, 'rb') as zipfp:
-        zip = zipfile.ZipFile(zipfp)
-        leading = has_leading_dir(zip.namelist()) and flatten
-        for name in zip.namelist():
-            data = zip.read(name)
-            fn = name
-            if leading:
-                fn = split_leading_dir(name)[1]
-            fn = os.path.join(location, fn)
-            dir = os.path.dirname(fn)
-            if not os.path.exists(dir):
-                os.makedirs(dir)
-            if fn.endswith('/') or fn.endswith('\\'):
-                # A directory
-                if not os.path.exists(fn):
-                    os.makedirs(fn)
-            else:
-                with open(fn, 'wb') as fp:
-                    fp.write(data)
+    zipfp = open(filename, 'rb')
+
+    zip = zipfile.ZipFile(zipfp)
+    leading = has_leading_dir(zip.namelist()) and flatten
+    for name in zip.namelist():
+        data = zip.read(name)
+        fn = name
+        if leading:
+            fn = split_leading_dir(name)[1]
+        fn = os.path.join(location, fn)
+        dir = os.path.dirname(fn)
+        if not os.path.exists(dir):
+            os.makedirs(dir)
+        if fn.endswith('/') or fn.endswith('\\'):
+            # A directory
+            if not os.path.exists(fn):
+                os.makedirs(fn)
+        else:
+            fp = open(fn, 'wb')
+            fp.write(data)
+            fp.close()
+    zipfp.close()
 
 
 def untar_file(filename, location):
@@ -705,31 +713,34 @@
         mode = 'r'
     else:
         mode = 'r:*'
-    with tarfile.open(filename, mode) as tar:
-        leading = has_leading_dir(member.name for member in tar.getmembers())
-        for member in tar.getmembers():
-            fn = member.name
-            if leading:
-                fn = split_leading_dir(fn)[1]
-            path = os.path.join(location, fn)
-            if member.isdir():
-                if not os.path.exists(path):
-                    os.makedirs(path)
-            else:
-                try:
-                    fp = tar.extractfile(member)
-                except (KeyError, AttributeError):
-                    # Some corrupt tar files seem to produce this
-                    # (specifically bad symlinks)
-                    continue
-                try:
-                    if not os.path.exists(os.path.dirname(path)):
-                        os.makedirs(os.path.dirname(path))
-                        with open(path, 'wb') as destfp:
-                            shutil.copyfileobj(fp, destfp)
-                finally:
-                    fp.close()
 
+    tar = tarfile.open(filename, mode)
+    leading = has_leading_dir(member.name for member in tar.getmembers())
+    for member in tar.getmembers():
+        fn = member.name
+        if leading:
+            fn = split_leading_dir(fn)[1]
+        path = os.path.join(location, fn)
+        if member.isdir():
+            if not os.path.exists(path):
+                os.makedirs(path)
+        else:
+            try:
+                fp = tar.extractfile(member)
+            except (KeyError, AttributeError):
+                # Some corrupt tar files seem to produce this
+                # (specifically bad symlinks)
+                continue
+            try:
+                if not os.path.exists(os.path.dirname(path)):
+                    os.makedirs(os.path.dirname(path))
+                    destfp = open(path, 'wb')
+                    shutil.copyfileobj(fp, destfp)
+                    destfp.close()
+            except:
+                fp.close()
+                raise
+            fp.close()
 
 def has_leading_dir(paths):
     """Return true if all the paths have the same leading path name.
@@ -860,10 +871,12 @@
 def generate_pypirc(username, password):
     """Create a default .pypirc file."""
     rc = get_pypirc_path()
-    with open(rc, 'w') as f:
-        f.write(DEFAULT_PYPIRC % (username, password))
+    f = open(rc, 'w')
+    f.write(DEFAULT_PYPIRC % (username, password))
+    f.close()
+
     try:
-        os.chmod(rc, 0o600)
+        os.chmod(rc, 00600)
     except OSError:
         # should do something better here
         pass
@@ -1070,8 +1083,9 @@
     if not os.path.exists(path):
         raise PackagingFileError("file '%s' does not exist" %
                                  os.path.abspath(path))
-    with codecs.open(path, encoding='utf-8') as f:
-        config.readfp(f)
+    f = codecs.open(path, encoding='utf-8')
+    config.readfp(f)
+    f.close()
 
     kwargs = {}
     for arg in D1_D2_SETUP_ARGS:
@@ -1093,8 +1107,9 @@
                     filenames = split_multiline(filenames)
                     in_cfg_value = []
                     for filename in filenames:
-                        with open(filename) as fp:
-                            in_cfg_value.append(fp.read())
+                        fp = open(filename)
+                        in_cfg_value.append(fp.read())
+                        fp.close()
                     in_cfg_value = '\n\n'.join(in_cfg_value)
             else:
                 continue
@@ -1131,8 +1146,9 @@
     if os.path.exists("setup.py"):
         raise PackagingFileError("a setup.py file already exists")
 
-    with codecs.open("setup.py", "w", encoding='utf-8') as fp:
-        fp.write(_SETUP_TMPL % {'func': getsource(cfg_to_args)})
+    fp = codecs.open("setup.py", "w", encoding='utf-8')
+    fp.write(_SETUP_TMPL % {'func': getsource(cfg_to_args)})
+    fp.close()
 
 
 # Taken from the pip project
@@ -1151,27 +1167,27 @@
 
 def _parse_record_file(record_file):
     distinfo, extra_metadata, installed = ({}, [], [])
-    with open(record_file, 'r') as rfile:
-        for path in rfile:
-            path = path.strip()
-            if path.endswith('egg-info') and os.path.isfile(path):
-                distinfo_dir = path.replace('egg-info', 'dist-info')
-                metadata = path
-                egginfo = path
-            elif path.endswith('egg-info') and os.path.isdir(path):
-                distinfo_dir = path.replace('egg-info', 'dist-info')
-                egginfo = path
-                for metadata_file in os.listdir(path):
-                    metadata_fpath = os.path.join(path, metadata_file)
-                    if metadata_file == 'PKG-INFO':
-                        metadata = metadata_fpath
-                    else:
-                        extra_metadata.append(metadata_fpath)
-            elif 'egg-info' in path and os.path.isfile(path):
-                # skip extra metadata files
-                continue
-            else:
-                installed.append(path)
+    rfile = open(record_file, 'r')
+    for path in rfile:
+        path = path.strip()
+        if path.endswith('egg-info') and os.path.isfile(path):
+            distinfo_dir = path.replace('egg-info', 'dist-info')
+            metadata = path
+            egginfo = path
+        elif path.endswith('egg-info') and os.path.isdir(path):
+            distinfo_dir = path.replace('egg-info', 'dist-info')
+            egginfo = path
+            for metadata_file in os.listdir(path):
+                metadata_fpath = os.path.join(path, metadata_file)
+                if metadata_file == 'PKG-INFO':
+                    metadata = metadata_fpath
+                else:
+                    extra_metadata.append(metadata_fpath)
+        elif 'egg-info' in path and os.path.isfile(path):
+            # skip extra metadata files
+            continue
+        else:
+            installed.append(path)
 
     distinfo['egginfo'] = egginfo
     distinfo['metadata'] = metadata
@@ -1187,24 +1203,26 @@
 
 
 def _write_record_file(record_path, installed_files):
-    with codecs.open(record_path, 'w', encoding='utf-8') as f:
-        writer = csv.writer(f, delimiter=',', lineterminator=os.linesep,
-                            quotechar='"')
+    f = codecs.open(record_path, 'w', encoding='utf-8')
+    writer = csv.writer(f, delimiter=',', lineterminator=os.linesep,
+                        quotechar='"')
 
-        for fpath in installed_files:
-            if fpath.endswith('.pyc') or fpath.endswith('.pyo'):
-                # do not put size and md5 hash, as in PEP-376
-                writer.writerow((fpath, '', ''))
-            else:
-                hash = hashlib.md5()
-                with open(fpath, 'rb') as fp:
-                    hash.update(fp.read())
-                md5sum = hash.hexdigest()
-                size = os.path.getsize(fpath)
-                writer.writerow((fpath, md5sum, size))
+    for fpath in installed_files:
+        if fpath.endswith('.pyc') or fpath.endswith('.pyo'):
+            # do not put size and md5 hash, as in PEP-376
+            writer.writerow((fpath, '', ''))
+        else:
+            hash = hashlib.md5()
+            fp = open(fpath, 'rb')
+            hash.update(fp.read())
+            fp.close()
+            md5sum = hash.hexdigest()
+            size = os.path.getsize(fpath)
+            writer.writerow((fpath, md5sum, size))
 
-        # add the RECORD file itself
-        writer.writerow((record_path, '', ''))
+    # add the RECORD file itself
+    writer.writerow((record_path, '', ''))
+    f.close()
     return record_path
 
 
@@ -1239,8 +1257,9 @@
 
     installer_path = distinfo['installer_path']
     logger.info('creating %s', installer_path)
-    with open(installer_path, 'w') as f:
-        f.write(installer)
+    f = open(installer_path, 'w')
+    f.write(installer)
+    f.close()
 
     if requested:
         requested_path = distinfo['requested_path']
@@ -1281,20 +1300,23 @@
 
 
 def _has_text(setup_py, installer):
-    installer_pattern = re.compile('import {0}|from {0}'.format(installer))
-    with codecs.open(setup_py, 'r', encoding='utf-8') as setup:
-        for line in setup:
-            if re.search(installer_pattern, line):
-                logger.debug("Found %s text in setup.py.", installer)
-                return True
+    installer_pattern = re.compile('import %s|from %s' % (
+        installer[0], installer[1]))
+    setup = codecs.open(setup_py, 'r', encoding='utf-8')
+    for line in setup:
+        if re.search(installer_pattern, line):
+            logger.debug("Found %s text in setup.py.", installer)
+            return True
+    setup.close()
     logger.debug("No %s text found in setup.py.", installer)
     return False
 
 
 def _has_required_metadata(setup_cfg):
     config = RawConfigParser()
-    with codecs.open(setup_cfg, 'r', encoding='utf8') as f:
-        config.readfp(f)
+    f = codecs.open(setup_cfg, 'r', encoding='utf8')
+    config.readfp(f)
+    f.close()
     return (config.has_section('metadata') and
             'name' in config.options('metadata') and
             'version' in config.options('metadata'))
@@ -1443,7 +1465,7 @@
 # I don't use os.makedirs because a) it's new to Python 1.5.2, and
 # b) it blows up if the directory already exists (I want to silently
 # succeed in that case).
-def _mkpath(name, mode=0o777, verbose=True, dry_run=False):
+def _mkpath(name, mode=00777, verbose=True, dry_run=False):
     # Detect a common bug -- name is None
     if not isinstance(name, basestring):
         raise PackagingInternalError(
@@ -1509,8 +1531,8 @@
 
     if boundary is None:
         boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
-    elif not isinstance(boundary, bytes):
-        raise TypeError('boundary must be bytes, not %r' % type(boundary))
+    elif not isinstance(boundary, str):
+        raise TypeError('boundary must be str, not %r' % type(boundary))
 
     l = []
     for key, values in fields:
@@ -1537,7 +1559,7 @@
     body = '\r\n'.join(l)
     content_type = 'multipart/form-data; boundary=' + boundary
     return content_type, body
-    
+
 # shutil stuff
 
 try:
@@ -1606,7 +1628,7 @@
     # flags for compression program, each element of list will be an argument
     if compress is not None and compress not in compress_ext.keys():
         raise ValueError("bad value for 'compress', or compression format not "
-                         "supported : {0}".format(compress))
+                         "supported : %s" % compress)
 
     archive_name = base_name + '.tar' + compress_ext.get(compress, '')
     archive_dir = os.path.dirname(archive_name)
@@ -1958,7 +1980,7 @@
         try:
             format_info = _UNPACK_FORMATS[format]
         except KeyError:
-            raise ValueError("Unknown unpack format '{0}'".format(format))
+            raise ValueError("Unknown unpack format '%s'" % format)
 
         func = format_info[1]
         func(filename, extract_dir, **dict(format_info[2]))
@@ -1966,12 +1988,12 @@
         # we need to look at the registered unpackers supported extensions
         format = _find_unpack_format(filename)
         if format is None:
-            raise ReadError("Unknown archive format '{0}'".format(filename))
+            raise ReadError("Unknown archive format '%s'" % filename)
 
         func = _UNPACK_FORMATS[format][1]
         kwargs = dict(_UNPACK_FORMATS[format][2])
         func(filename, extract_dir, **kwargs)
-        
+
 # tokenize stuff
 
 cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
@@ -2095,4 +2117,3 @@
         return filename.encode(sys.getfilesystemencoding())
     else:
         raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
-
diff --git a/sysconfig.py b/sysconfig.py
--- a/sysconfig.py
+++ b/sysconfig.py
@@ -209,10 +209,7 @@
     done = {}
     notdone = {}
 
-    with open(filename) as f:
-        lines = f.readlines()
-
-    for line in lines:
+    for line in open(filename).readlines():
         if line.startswith('#') or line.strip() == '':
             continue
         m = _variable_rx.match(line)
@@ -326,7 +323,7 @@
     makefile = get_makefile_filename()
     try:
         _parse_makefile(makefile, vars)
-    except IOError as e:
+    except IOError, e:
         msg = "invalid Python installation: unable to open %s" % makefile
         if hasattr(e, "strerror"):
             msg = msg + " (%s)" % e.strerror
@@ -334,9 +331,10 @@
     # load the installed pyconfig.h:
     config_h = get_config_h_filename()
     try:
-        with open(config_h) as f:
-            parse_config_h(f, vars)
-    except IOError as e:
+        f = open(config_h)
+        parse_config_h(f, vars)
+        f.close()
+    except IOError, e:
         msg = "invalid Python installation: unable to open %s" % config_h
         if hasattr(e, "strerror"):
             msg = msg + " (%s)" % e.strerror

-- 
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list