[Python-checkins] distutils2: Fix the backport fixes.

eric.araujo python-checkins at python.org
Mon Sep 19 15:12:39 CEST 2011


http://hg.python.org/distutils2/rev/12f3ba3cbac2
changeset: 1148:12f3ba3cbac2
user: Éric Araujo <merwok at netwok.org>
date: Sun Sep 18 20:20:13 2011 +0200
summary:
 Fix the backport fixes.
Backports:
- sysconfig is now always imported from our backports
- when hashlib is not found, our backport is used instead of the md5
 module (debatable; we could just drop hashlib)
Version-dependent features:
- PEP 370 features are only enabled for 2.6+
- the check for sys.dont_write_bytecode was fixed to use getattr
 with a default value instead of hasattr
Idioms/syntax:
- octal literals lost their extra 0
- misused try/except blocks have been changed back to try/finally
 (it’s legal in 2.4 too, it’s only try/except/finally that isn’t)
- exception catching uses the regular 2.x idiom instead of sys.exc_info
- file objects are closed within finally blocks (this causes much
 whitespace changes but actually makes diff with packaging easier)
Renamed modules:
- some missed renamings (_thread, Queue, isAlive, urllib.urlsplit, etc.)
 were fixed
Other:
- a few false positive replacements of “packaging” by “distutils2” in
 comments or docstrings were reverted
- util.is_packaging regained its name
- assorted whitespace/comment/import changes to match packaging
files:
 distutils2/__init__.py | 2 +-
 distutils2/_backport/tests/test_sysconfig.py | 3 +-
 distutils2/command/__init__.py | 5 +-
 distutils2/command/bdist.py | 12 +-
 distutils2/command/bdist_dumb.py | 15 +-
 distutils2/command/bdist_msi.py | 32 +-
 distutils2/command/bdist_wininst.py | 83 ++-
 distutils2/command/build_clib.py | 3 +-
 distutils2/command/build_ext.py | 30 +-
 distutils2/command/build_py.py | 4 +-
 distutils2/command/build_scripts.py | 10 +-
 distutils2/command/cmd.py | 7 +-
 distutils2/command/config.py | 43 +-
 distutils2/command/install_data.py | 5 +-
 distutils2/command/install_dist.py | 12 +-
 distutils2/command/install_distinfo.py | 4 +-
 distutils2/command/install_lib.py | 4 +-
 distutils2/command/install_scripts.py | 2 +-
 distutils2/command/register.py | 12 +-
 distutils2/command/sdist.py | 8 +-
 distutils2/command/upload.py | 23 +-
 distutils2/command/upload_docs.py | 27 +-
 distutils2/compiler/bcppcompiler.py | 20 +-
 distutils2/compiler/ccompiler.py | 14 +-
 distutils2/compiler/cygwinccompiler.py | 23 +-
 distutils2/compiler/msvc9compiler.py | 26 +-
 distutils2/compiler/msvccompiler.py | 22 +-
 distutils2/compiler/unixccompiler.py | 18 +-
 distutils2/config.py | 24 +-
 distutils2/create.py | 128 +++--
 distutils2/database.py | 61 +-
 distutils2/depgraph.py | 9 +-
 distutils2/dist.py | 57 +-
 distutils2/fancy_getopt.py | 6 +-
 distutils2/install.py | 37 +-
 distutils2/manifest.py | 21 +-
 distutils2/markers.py | 10 +-
 distutils2/metadata.py | 20 +-
 distutils2/pypi/dist.py | 10 +-
 distutils2/pypi/simple.py | 45 +-
 distutils2/pypi/wrapper.py | 4 +-
 distutils2/pypi/xmlrpc.py | 5 +-
 distutils2/run.py | 35 +-
 distutils2/tests/__main__.py | 8 +-
 distutils2/tests/pypi_server.py | 22 +-
 distutils2/tests/test_command_build.py | 2 +-
 distutils2/tests/test_command_build_ext.py | 9 +-
 distutils2/tests/test_command_upload_docs.py | 5 +-
 distutils2/tests/test_install.py | 3 +-
 distutils2/tests/test_mixin2to3.py | 10 +-
 distutils2/tests/test_pypi_simple.py | 4 +-
 distutils2/util.py | 203 +++++----
 distutils2/version.py | 1 -
 53 files changed, 646 insertions(+), 562 deletions(-)
diff --git a/distutils2/__init__.py b/distutils2/__init__.py
--- a/distutils2/__init__.py
+++ b/distutils2/__init__.py
@@ -1,4 +1,4 @@
-"""Support for distutils2, distribution and installation of Python projects.
+"""Support for packaging, distribution and installation of Python projects.
 
 Third-party tools can use parts of distutils2 as building blocks
 without causing the other modules to be imported:
diff --git a/distutils2/_backport/tests/test_sysconfig.py b/distutils2/_backport/tests/test_sysconfig.py
--- a/distutils2/_backport/tests/test_sysconfig.py
+++ b/distutils2/_backport/tests/test_sysconfig.py
@@ -254,7 +254,8 @@
 # Issue 7880
 def get(python):
 cmd = [python, '-c',
- 'import sysconfig; print sysconfig.get_platform()']
+ 'from distutils2._backport import sysconfig; '
+ 'print sysconfig.get_platform()']
 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=os.environ)
 return p.communicate()
 real = os.path.realpath(sys.executable)
diff --git a/distutils2/command/__init__.py b/distutils2/command/__init__.py
--- a/distutils2/command/__init__.py
+++ b/distutils2/command/__init__.py
@@ -28,8 +28,11 @@
 'bdist_wininst': 'distutils2.command.bdist_wininst.bdist_wininst',
 'register': 'distutils2.command.register.register',
 'upload': 'distutils2.command.upload.upload',
- 'upload_docs': 'distutils2.command.upload_docs.upload_docs'}
+ 'upload_docs': 'distutils2.command.upload_docs.upload_docs',
+}
 
+# XXX use OrderedDict to preserve the grouping (build-related, install-related,
+# distribution-related)
 STANDARD_COMMANDS = set(_COMMANDS)
 
 
diff --git a/distutils2/command/bdist.py b/distutils2/command/bdist.py
--- a/distutils2/command/bdist.py
+++ b/distutils2/command/bdist.py
@@ -58,7 +58,7 @@
 # This is of course very simplistic. The various UNIX family operating
 # systems have their specific formats, but they are out of scope for us;
 # bdist_dumb is, well, dumb; it's more a building block for other
- # distutils2 tools than a real end-user binary format.
+ # packaging tools than a real end-user binary format.
 default_format = {'posix': 'gztar',
 'nt': 'zip',
 'os2': 'zip'}
@@ -75,9 +75,8 @@
 'wininst': ('bdist_wininst',
 "Windows executable installer"),
 'zip': ('bdist_dumb', "ZIP file"),
- 'msi': ('bdist_msi', "Microsoft Installer")
- }
-
+ 'msi': ('bdist_msi', "Microsoft Installer"),
+ }
 
 def initialize_options(self):
 self.bdist_base = None
@@ -109,8 +108,9 @@
 try:
 self.formats = [self.default_format[os.name]]
 except KeyError:
- raise PackagingPlatformError("don't know how to create built distributions " + \
- "on platform %s" % os.name)
+ raise PackagingPlatformError(
+ "don't know how to create built distributions "
+ "on platform %s" % os.name)
 
 if self.dist_dir is None:
 self.dist_dir = "dist"
diff --git a/distutils2/command/bdist_dumb.py b/distutils2/command/bdist_dumb.py
--- a/distutils2/command/bdist_dumb.py
+++ b/distutils2/command/bdist_dumb.py
@@ -7,11 +7,12 @@
 import os
 
 from shutil import rmtree
-from sysconfig import get_python_version
 from distutils2.util import get_platform
 from distutils2.command.cmd import Command
 from distutils2.errors import PackagingPlatformError
 from distutils2 import logger
+from distutils2._backport.sysconfig import get_python_version
+
 
 class bdist_dumb(Command):
 
@@ -44,10 +45,9 @@
 
 boolean_options = ['keep-temp', 'skip-build', 'relative']
 
- default_format = { 'posix': 'gztar',
- 'nt': 'zip',
- 'os2': 'zip' }
-
+ default_format = {'posix': 'gztar',
+ 'nt': 'zip',
+ 'os2': 'zip'}
 
 def initialize_options(self):
 self.bdist_dir = None
@@ -69,8 +69,9 @@
 try:
 self.format = self.default_format[os.name]
 except KeyError:
- raise PackagingPlatformError(("don't know how to create dumb built distributions " +
- "on platform %s") % os.name)
+ raise PackagingPlatformError(
+ "don't know how to create dumb built distributions "
+ "on platform %s" % os.name)
 
 self.set_undefined_options('bdist', 'dist_dir', 'plat_name')
 
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
@@ -8,7 +8,7 @@
 import msilib
 
 
-from sysconfig import get_python_version
+from distutils2._backport.sysconfig import get_python_version
 from shutil import rmtree
 from distutils2.command.cmd import Command
 from distutils2.version import NormalizedVersion
@@ -391,19 +391,23 @@
 if self.pre_install_script:
 scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
 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()
+ try:
+ # 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)
+ try:
+ f.write(fp.read())
+ finally:
+ fp.close()
+ finally:
+ 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
@@ -6,11 +6,11 @@
 import os
 
 from shutil import rmtree
-from sysconfig import get_python_version
 from distutils2.command.cmd import Command
 from distutils2.errors import PackagingOptionError, PackagingPlatformError
 from distutils2 import logger
 from distutils2.util import get_platform
+from distutils2._backport.sysconfig import get_python_version
 
 
 class bdist_wininst(Command):
@@ -246,49 +246,56 @@
 
 if bitmap:
 fp = open(bitmap, "rb")
- bitmapdata = fp.read()
- fp.close()
+ try:
+ bitmapdata = fp.read()
+ finally:
+ fp.close()
 bitmaplen = len(bitmapdata)
 else:
 bitmaplen = 0
 
 file = open(installer_name, "wb")
- file.write(self.get_exe_bytes())
- if bitmap:
- file.write(bitmapdata)
+ try:
+ 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
- cfgdata = cfgdata + "0円"
- if self.pre_install_script:
- fp = open(self.pre_install_script)
- script_data = fp.read()
- fp.close()
- cfgdata = cfgdata + script_data + "\n0円"
- else:
- # empty pre-install script
+ # Append the pre-install script
 cfgdata = cfgdata + "0円"
- file.write(cfgdata)
+ if self.pre_install_script:
+ fp = open(self.pre_install_script)
+ try:
+ script_data = fp.read()
+ finally:
+ fp.close()
+ cfgdata = cfgdata + script_data + "\n0円"
+ else:
+ # empty pre-install script
+ cfgdata = cfgdata + "0円"
+ 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)
- file.close()
-
- fp = open(arcname, "rb")
- file.write(fp.read())
- fp.close()
+ # 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)
+ fp = open(arcname, "rb")
+ try:
+ file.write(fp.read())
+ finally:
+ fp.close()
+ finally:
+ file.close()
 
 def get_installer_filename(self, fullname):
 # Factored out to allow overriding in subclasses
@@ -344,6 +351,8 @@
 
 filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix))
 fp = open(filename, "rb")
- content = fp.read()
- fp.close()
+ try:
+ content = fp.read()
+ finally:
+ fp.close()
 return content
diff --git a/distutils2/command/build_clib.py b/distutils2/command/build_clib.py
--- a/distutils2/command/build_clib.py
+++ b/distutils2/command/build_clib.py
@@ -16,7 +16,7 @@
 import os
 from distutils2.command.cmd import Command
 from distutils2.errors import PackagingSetupError
-from distutils2.compiler import customize_compiler
+from distutils2.compiler import customize_compiler, new_compiler
 from distutils2 import logger
 
 
@@ -93,7 +93,6 @@
 return
 
 # Yech -- this is cut 'n pasted from build_ext.py!
- from distutils2.compiler import new_compiler
 self.compiler = new_compiler(compiler=self.compiler,
 dry_run=self.dry_run,
 force=self.force)
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
@@ -1,9 +1,5 @@
 """Build extension modules."""
 
-# FIXME Is this module limited to C extensions or do C++ extensions work too?
-# The docstring of this module said that C++ was not supported, but other
-# comments contradict that.
-
 import os
 import re
 import sys
@@ -20,7 +16,10 @@
 from distutils2 import logger
 
 import site
-HAS_USER_SITE = True
+if sys.version_info[:2] >= (2, 6):
+ HAS_USER_SITE = True
+else:
+ HAS_USER_SITE = False
 
 if os.name == 'nt':
 from distutils2.compiler.msvccompiler import get_build_version
@@ -363,12 +362,11 @@
 for ext in self.extensions:
 try:
 self.build_extension(ext)
- except (CCompilerError, PackagingError, CompileError):
+ except (CCompilerError, PackagingError, CompileError), e:
 if not ext.optional:
 raise
 logger.warning('%s: building extension %r failed: %s',
- self.get_command_name(), ext.name,
- sys.exc_info()[1])
+ self.get_command_name(), ext.name, e)
 
 def build_extension(self, ext):
 sources = ext.sources
@@ -608,8 +606,7 @@
 template = "python%d%d"
 if self.debug:
 template = template + '_d'
- pythonlib = (template %
- (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+ pythonlib = template % sys.version_info[:2]
 # don't extend ext.libraries, it may be shared with other
 # extensions, it is a reference to the original list
 return ext.libraries + [pythonlib]
@@ -623,22 +620,19 @@
 # not at this time - AIM Apr01
 #if self.debug:
 # template = template + '_d'
- pythonlib = (template %
- (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+ pythonlib = template % sys.version_info[:2]
 # don't extend ext.libraries, it may be shared with other
 # extensions, it is a reference to the original list
 return ext.libraries + [pythonlib]
 elif sys.platform[:6] == "cygwin":
 template = "python%d.%d"
- pythonlib = (template %
- (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+ pythonlib = template % sys.version_info[:2]
 # don't extend ext.libraries, it may be shared with other
 # extensions, it is a reference to the original list
 return ext.libraries + [pythonlib]
 elif sys.platform[:6] == "atheos":
 template = "python%d.%d"
- pythonlib = (template %
- (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+ pythonlib = template % sys.version_info[:2]
 # Get SHLIBS from Makefile
 extra = []
 for lib in sysconfig.get_config_var('SHLIBS').split():
@@ -656,8 +650,8 @@
 
 else:
 if sysconfig.get_config_var('Py_ENABLE_SHARED'):
- pythonlib = 'python%s.%s' % (
- sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)
+ template = 'python%d.%d' + sys.abiflags
+ pythonlib = template % sys.version_info[:2]
 return ext.libraries + [pythonlib]
 else:
 return ext.libraries
diff --git a/distutils2/command/build_py.py b/distutils2/command/build_py.py
--- a/distutils2/command/build_py.py
+++ b/distutils2/command/build_py.py
@@ -388,12 +388,12 @@
 self.build_module(module, module_file, package)
 
 def byte_compile(self, files):
- if hasattr(sys, 'dont_write_bytecode') and sys.dont_write_bytecode:
+ if getattr(sys, 'dont_write_bytecode', False):
 logger.warning('%s: byte-compiling is disabled, skipping.',
 self.get_command_name())
 return
 
- from distutils2.util import byte_compile
+ from distutils2.util import byte_compile # FIXME use compileall
 prefix = self.build_lib
 if prefix[-1] != os.sep:
 prefix = prefix + os.sep
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
@@ -130,9 +130,11 @@
 "from the script encoding (%s)" % (
 shebang, encoding))
 outf = open(outfile, "wb")
- outf.write(shebang)
- outf.writelines(f.readlines())
- outf.close()
+ try:
+ outf.write(shebang)
+ outf.writelines(f.readlines())
+ finally:
+ outf.close()
 if f:
 f.close()
 else:
@@ -146,7 +148,7 @@
 logger.info("changing mode of %s", file)
 else:
 oldmode = os.stat(file).st_mode & 07777
- newmode = (oldmode | 00555) & 07777
+ newmode = (oldmode | 0555) & 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
@@ -5,6 +5,7 @@
 from shutil import copyfile, move
 from distutils2 import util
 from distutils2 import logger
+from distutils2.util import make_archive
 from distutils2.errors import PackagingOptionError
 
 
@@ -403,9 +404,9 @@
 
 def make_archive(self, base_name, format, root_dir=None, base_dir=None,
 owner=None, group=None):
- return util.make_archive(base_name, format, root_dir,
- base_dir, dry_run=self.dry_run,
- owner=owner, group=group)
+ return make_archive(base_name, format, root_dir,
+ base_dir, dry_run=self.dry_run,
+ owner=owner, group=group)
 
 def make_file(self, infiles, outfile, func, args,
 exec_msg=None, skip_msg=None, level=1):
diff --git a/distutils2/command/config.py b/distutils2/command/config.py
--- a/distutils2/command/config.py
+++ b/distutils2/command/config.py
@@ -111,14 +111,16 @@
 def _gen_temp_sourcefile(self, body, headers, lang):
 filename = "_configtest" + LANG_EXT[lang]
 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()
+ try:
+ 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")
+ finally:
+ file.close()
 return filename
 
 def _preprocess(self, body, headers, include_dirs, lang):
@@ -208,14 +210,17 @@
 pattern = re.compile(pattern)
 
 file = open(out)
- match = False
- while True:
- line = file.readline()
- if line == '':
- break
- if pattern.search(line):
- match = True
- break
+ try:
+ match = False
+ while True:
+ line = file.readline()
+ if line == '':
+ break
+ if pattern.search(line):
+ match = True
+ break
+ finally:
+ file.close()
 
 self._clean()
 return match
@@ -347,5 +352,7 @@
 else:
 logger.info(head)
 file = open(filename)
- logger.info(file.read())
- file.close()
+ try:
+ logger.info(file.read())
+ finally:
+ file.close()
diff --git a/distutils2/command/install_data.py b/distutils2/command/install_data.py
--- a/distutils2/command/install_data.py
+++ b/distutils2/command/install_data.py
@@ -2,7 +2,7 @@
 
 # Contributed by Bastian Kleineidam
 
-import os, sys
+import os
 from shutil import Error
 from distutils2 import logger
 from distutils2.util import convert_path
@@ -48,8 +48,7 @@
 self.mkpath(dir_dest)
 try:
 out = self.copy_file(_file[0], dir_dest)[0]
- except Error:
- e = sys.exc_info()[1]
+ except Error, e:
 logger.warning('%s: %s', self.get_command_name(), e)
 out = destination
 
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
@@ -295,9 +295,9 @@
 
 self.dump_dirs("post-expand_dirs()")
 
- # Create directories in the home dir:
+ # Create directories under USERBASE
 if HAS_USER_SITE and self.user:
- self.create_home_path()
+ self.create_user_dirs()
 
 # Pick the actual directory to install all modules to: either
 # install_purelib or install_platlib, depending on whether this
@@ -494,14 +494,12 @@
 attr = "install_" + name
 setattr(self, attr, change_root(self.root, getattr(self, attr)))
 
- def create_home_path(self):
- """Create directories under ~."""
- if HAS_USER_SITE and not self.user:
- return
+ def create_user_dirs(self):
+ """Create directories under USERBASE as needed."""
 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, 00700)
+ os.makedirs(path, 0700)
 
 # -- 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
@@ -8,7 +8,7 @@
 import re
 try:
 import hashlib
-except ImportError: #<2.5
+except ImportError:
 from distutils2._backport import hashlib
 
 from distutils2.command.cmd import Command
@@ -32,7 +32,7 @@
 ('no-record', None,
 "do not generate a RECORD file"),
 ('no-resources', None,
- "do not generate a RESSOURCES list installed file")
+ "do not generate a RESSOURCES list installed file"),
 ]
 
 boolean_options = ['requested', 'no-record', 'no-resources']
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 hasattr(sys, 'dont_write_bytecode'):
+ if getattr(sys, 'dont_write_bytecode', False):
 # XXX do we want this? because a Python runs without bytecode
 # doesn't mean that the *dists should not contain bytecode
 #--or does it?
@@ -122,7 +122,7 @@
 self.get_command_name())
 return
 
- from distutils2.util import byte_compile
+ from distutils2.util import byte_compile # FIXME use compileall
 
 # Get the "--root" directory supplied to the "install_dist" command,
 # and use it as a prefix to strip off the purported filename
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 | 00555) & 07777
+ mode = (os.stat(file).st_mode | 0555) & 07777
 logger.info("changing mode of %s to %o", file, mode)
 os.chmod(file, mode)
 
diff --git a/distutils2/command/register.py b/distutils2/command/register.py
--- a/distutils2/command/register.py
+++ b/distutils2/command/register.py
@@ -2,14 +2,13 @@
 
 # Contributed by Richard Jones
 
-import sys
 import getpass
+import urllib2
 import urlparse
-import urllib2
 
 from distutils2 import logger
 from distutils2.util import (read_pypirc, generate_pypirc, DEFAULT_REPOSITORY,
- DEFAULT_REALM, get_pypirc_path, encode_multipart)
+ DEFAULT_REALM, get_pypirc_path, encode_multipart)
 from distutils2.command.cmd import Command
 
 class register(Command):
@@ -246,13 +245,12 @@
 data = ''
 try:
 result = opener.open(req)
- except urllib2.HTTPError:
- e = sys.exc_info()[1]
+ except urllib2.HTTPError, e:
 if self.show_response:
 data = e.fp.read()
 result = e.code, e.msg
- except urllib2.URLError:
- result = 500, str(sys.exc_info()[1])
+ except urllib2.URLError, e:
+ result = 500, str(e)
 else:
 if self.show_response:
 data = result.read()
diff --git a/distutils2/command/sdist.py b/distutils2/command/sdist.py
--- a/distutils2/command/sdist.py
+++ b/distutils2/command/sdist.py
@@ -9,7 +9,7 @@
 from distutils2 import logger
 from distutils2.util import resolve_name, get_archive_formats
 from distutils2.errors import (PackagingPlatformError, PackagingOptionError,
- PackagingModuleError, PackagingFileError)
+ PackagingModuleError, PackagingFileError)
 from distutils2.command import get_command_names
 from distutils2.command.cmd import Command
 from distutils2.manifest import Manifest
@@ -143,8 +143,8 @@
 continue
 try:
 builder = resolve_name(builder)
- except ImportError:
- raise PackagingModuleError(sys.exc_info()[1])
+ except ImportError, e:
+ raise PackagingModuleError(e)
 
 builders.append(builder)
 
@@ -337,7 +337,7 @@
 """
 return self.archive_files
 
- def create_tree(self, base_dir, files, mode=00777, verbose=1,
+ def create_tree(self, base_dir, files, mode=0777, 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
@@ -1,6 +1,6 @@
 """Upload a distribution to a project index."""
 
-import os, sys
+import os
 import socket
 import logging
 import platform
@@ -16,7 +16,7 @@
 from distutils2 import logger
 from distutils2.errors import PackagingOptionError
 from distutils2.util import (spawn, read_pypirc, DEFAULT_REPOSITORY,
- DEFAULT_REALM, encode_multipart)
+ DEFAULT_REALM, encode_multipart)
 from distutils2.command.cmd import Command
 
 
@@ -105,8 +105,10 @@
 # Fill in the data - send all the metadata in case we need to
 # register a new release
 f = open(filename, 'rb')
- content = f.read()
- f.close()
+ try:
+ content = f.read()
+ finally:
+ f.close()
 
 data = self.distribution.metadata.todict()
 
@@ -123,8 +125,10 @@
 
 if self.sign:
 fp = open(filename + '.asc')
- sig = fp.read()
- fp.close()
+ try:
+ sig = fp.read()
+ finally:
+ fp.close()
 data['gpg_signature'] = [
 (os.path.basename(filename) + ".asc", sig)]
 
@@ -156,11 +160,10 @@
 result = urlopen(request)
 status = result.code
 reason = result.msg
- except socket.error:
- logger.error(sys.exc_info()[1])
+ except socket.error, e:
+ logger.error(e)
 return
- except HTTPError:
- e = sys.exc_info()[1]
+ except HTTPError, e:
 status = e.code
 reason = e.msg
 
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
@@ -1,6 +1,6 @@
 """Upload HTML documentation to a project index."""
 
-import os, sys
+import os
 import base64
 import socket
 import zipfile
@@ -11,7 +11,7 @@
 
 from distutils2 import logger
 from distutils2.util import (read_pypirc, DEFAULT_REPOSITORY, DEFAULT_REALM,
- encode_multipart)
+ encode_multipart)
 from distutils2.errors import PackagingFileError
 from distutils2.command.cmd import Command
 
@@ -20,13 +20,15 @@
 """Compresses recursively contents of directory into a BytesIO object"""
 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()
+ try:
+ 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)
+ finally:
+ zip_file.close()
 return destination
 
 
@@ -88,7 +90,8 @@
 content_type, body = encode_multipart(fields, files)
 
 credentials = self.username + ':' + self.password
- auth = "Basic " + base64.encodebytes(credentials.encode()).strip()
+ # FIXME should use explicit encoding
+ auth = "Basic " + base64.encodestring(credentials.encode()).strip()
 
 logger.info("Submitting documentation to %s", self.repository)
 
@@ -110,8 +113,8 @@
 conn.endheaders()
 conn.send(body)
 
- except socket.error:
- logger.error(sys.exc_info()[1])
+ except socket.error, e:
+ logger.error(e)
 return
 
 r = conn.getresponse()
diff --git a/distutils2/compiler/bcppcompiler.py b/distutils2/compiler/bcppcompiler.py
--- a/distutils2/compiler/bcppcompiler.py
+++ b/distutils2/compiler/bcppcompiler.py
@@ -7,10 +7,10 @@
 # someone should sit down and factor out the common code as
 # WindowsCCompiler! --GPW
 
-import os, sys
+import os
 
 from distutils2.errors import (PackagingExecError, CompileError, LibError,
- LinkError, UnknownFileError)
+ LinkError, UnknownFileError)
 from distutils2.compiler.ccompiler import CCompiler
 from distutils2.compiler import gen_preprocess_options
 from distutils2.file_util import write_file
@@ -104,8 +104,8 @@
 # This needs to be compiled to a .res file -- do it now.
 try:
 self.spawn(["brcc32", "-fo", obj, src])
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 continue # the 'for' loop
 
 # The next two are both for the real compiler.
@@ -128,8 +128,8 @@
 self.spawn([self.cc] + compile_opts + pp_opts +
 [input_opt, output_opt] +
 extra_postargs + [src])
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 
 return objects
 
@@ -146,8 +146,8 @@
 pass # XXX what goes here?
 try:
 self.spawn([self.lib] + lib_args)
- except PackagingExecError:
- raise LibError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LibError(msg)
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
 
@@ -268,8 +268,8 @@
 self.mkpath(os.path.dirname(output_filename))
 try:
 self.spawn([self.linker] + ld_args)
- except PackagingExecError:
- raise LinkError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LinkError(msg)
 
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
diff --git a/distutils2/compiler/ccompiler.py b/distutils2/compiler/ccompiler.py
--- a/distutils2/compiler/ccompiler.py
+++ b/distutils2/compiler/ccompiler.py
@@ -8,7 +8,7 @@
 from shutil import move
 from distutils2 import logger
 from distutils2.util import split_quoted, execute, newer_group, spawn
-from distutils2.errors import (CompileError, LinkError, UnknownFileError)
+from distutils2.errors import CompileError, LinkError, UnknownFileError
 from distutils2.compiler import gen_preprocess_options
 
 
@@ -728,14 +728,16 @@
 library_dirs = []
 fd, fname = tempfile.mkstemp(".c", funcname, text=True)
 f = os.fdopen(fd, "w")
- for incl in includes:
- f.write("""#include "%s"\n""" % incl)
- f.write("""\
+ try:
+ for incl in includes:
+ f.write("""#include "%s"\n""" % incl)
+ f.write("""\
 main (int argc, char **argv) {
 %s();
 }
 """ % funcname)
- f.close()
+ finally:
+ f.close()
 try:
 objects = self.compile([fname], include_dirs=include_dirs)
 except CompileError:
@@ -852,7 +854,7 @@
 return
 return move(src, dst)
 
- def mkpath(self, name, mode=00777):
+ def mkpath(self, name, mode=0777):
 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
@@ -156,14 +156,14 @@
 # gcc needs '.res' and '.rc' compiled to object files !!!
 try:
 self.spawn(["windres", "-i", src, "-o", obj])
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 else: # for other files use the C-compiler
 try:
 self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
 extra_postargs)
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 
 def link(self, target_desc, objects, output_filename, output_dir=None,
 libraries=None, library_dirs=None, runtime_library_dirs=None,
@@ -345,12 +345,13 @@
 fn = sysconfig.get_config_h_filename()
 try:
 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]
+ try:
+ 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
+ finally:
+ config_h.close()
+ except IOError, exc:
 return (CONFIG_H_UNCERTAIN,
 "couldn't read '%s': %s" % (fn, exc.strerror))
diff --git a/distutils2/compiler/msvc9compiler.py b/distutils2/compiler/msvc9compiler.py
--- a/distutils2/compiler/msvc9compiler.py
+++ b/distutils2/compiler/msvc9compiler.py
@@ -14,7 +14,7 @@
 import re
 
 from distutils2.errors import (PackagingExecError, PackagingPlatformError,
- CompileError, LibError, LinkError)
+ CompileError, LibError, LinkError)
 from distutils2.compiler.ccompiler import CCompiler
 from distutils2.compiler import gen_lib_options
 from distutils2 import logger
@@ -477,8 +477,8 @@
 try:
 self.spawn([self.rc] + pp_opts +
 [output_opt] + [input_opt])
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 continue
 elif ext in self._mc_extensions:
 # Compile .MC to .RC file to .RES file.
@@ -504,8 +504,8 @@
 self.spawn([self.rc] +
 ["/fo" + obj] + [rc_file])
 
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 continue
 else:
 # how to handle this file?
@@ -517,8 +517,8 @@
 self.spawn([self.cc] + compile_opts + pp_opts +
 [input_opt, output_opt] +
 extra_postargs)
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 
 return objects
 
@@ -542,8 +542,8 @@
 pass # XXX what goes here?
 try:
 self.spawn([self.lib] + lib_args)
- except PackagingExecError:
- raise LibError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LibError(msg)
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
 
@@ -620,8 +620,8 @@
 self.mkpath(os.path.dirname(output_filename))
 try:
 self.spawn([self.linker] + ld_args)
- except PackagingExecError:
- raise LinkError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LinkError(msg)
 
 # embed the manifest
 # XXX - this is somewhat fragile - if mt.exe fails, distutils
@@ -637,8 +637,8 @@
 try:
 self.spawn(['mt.exe', '-nologo', '-manifest',
 temp_manifest, out_arg])
- except PackagingExecError:
- raise LinkError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LinkError(msg)
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
 
diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py
--- a/distutils2/compiler/msvccompiler.py
+++ b/distutils2/compiler/msvccompiler.py
@@ -12,7 +12,7 @@
 import os
 
 from distutils2.errors import (PackagingExecError, PackagingPlatformError,
- CompileError, LibError, LinkError)
+ CompileError, LibError, LinkError)
 from distutils2.compiler.ccompiler import CCompiler
 from distutils2.compiler import gen_lib_options
 from distutils2 import logger
@@ -386,8 +386,8 @@
 try:
 self.spawn([self.rc] + pp_opts +
 [output_opt] + [input_opt])
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 continue
 elif ext in self._mc_extensions:
 
@@ -415,8 +415,8 @@
 self.spawn([self.rc] +
 ["/fo" + obj] + [rc_file])
 
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 continue
 else:
 # how to handle this file?
@@ -429,8 +429,8 @@
 self.spawn([self.cc] + compile_opts + pp_opts +
 [input_opt, output_opt] +
 extra_postargs)
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 
 return objects
 
@@ -448,8 +448,8 @@
 pass # XXX what goes here?
 try:
 self.spawn([self.lib] + lib_args)
- except PackagingExecError:
- raise LibError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LibError(msg)
 
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
@@ -515,8 +515,8 @@
 self.mkpath(os.path.dirname(output_filename))
 try:
 self.spawn([self.linker] + ld_args)
- except PackagingExecError:
- raise LinkError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LinkError(msg)
 
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
diff --git a/distutils2/compiler/unixccompiler.py b/distutils2/compiler/unixccompiler.py
--- a/distutils2/compiler/unixccompiler.py
+++ b/distutils2/compiler/unixccompiler.py
@@ -127,7 +127,7 @@
 executables['ranlib'] = ["ranlib"]
 
 # Needed for the filename generation methods provided by the base
- # class, CCompiler. NB. whoever instantiates/uses a particular
+ # class, CCompiler. XXX whoever instantiates/uses a particular
 # UnixCCompiler instance should set 'shared_lib_ext' -- we set a
 # reasonable common default here, but it's not necessarily used on all
 # Unices!
@@ -165,8 +165,8 @@
 self.mkpath(os.path.dirname(output_file))
 try:
 self.spawn(pp_args)
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 
 def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
 compiler_so = self.compiler_so
@@ -175,8 +175,8 @@
 try:
 self.spawn(compiler_so + cc_args + [src, '-o', obj] +
 extra_postargs)
- except PackagingExecError:
- raise CompileError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise CompileError(msg)
 
 def create_static_lib(self, objects, output_libname,
 output_dir=None, debug=False, target_lang=None):
@@ -199,8 +199,8 @@
 if self.ranlib:
 try:
 self.spawn(self.ranlib + [output_filename])
- except PackagingExecError:
- raise LibError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LibError(msg)
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
 
@@ -253,8 +253,8 @@
 linker = _darwin_compiler_fixup(linker, ld_args)
 
 self.spawn(linker + ld_args)
- except PackagingExecError:
- raise LinkError(sys.exc_info()[1])
+ except PackagingExecError, msg:
+ raise LinkError(msg)
 else:
 logger.debug("skipping %s (up-to-date)", output_filename)
 
diff --git a/distutils2/config.py b/distutils2/config.py
--- a/distutils2/config.py
+++ b/distutils2/config.py
@@ -1,8 +1,8 @@
 """Utilities to find and read config files used by distutils2."""
 
-import codecs
 import os
 import sys
+import codecs
 import logging
 
 from shlex import split
@@ -11,7 +11,7 @@
 from distutils2.errors import PackagingOptionError
 from distutils2.compiler.extension import Extension
 from distutils2.util import (check_environ, iglob, resolve_name, strtobool,
- split_multiline)
+ split_multiline)
 from distutils2.compiler import set_compiler
 from distutils2.command import set_command
 from distutils2.markers import interpret
@@ -142,9 +142,9 @@
 for line in setup_hooks:
 try:
 hook = resolve_name(line)
- except ImportError:
+ except ImportError, e:
 logger.warning('cannot find setup hook: %s',
- sys.exc_info()[1].args[0])
+ e.args[0])
 else:
 self.setup_hooks.append(hook)
 self.run_hooks(content)
@@ -178,8 +178,10 @@
 for filename in filenames:
 # will raise if file not found
 description_file = open(filename)
- value.append(description_file.read().strip())
- description_file.close()
+ try:
+ value.append(description_file.read().strip())
+ finally:
+ description_file.close()
 # add filename as a required file
 if filename not in metadata.requires_files:
 metadata.requires_files.append(filename)
@@ -290,8 +292,10 @@
 for filename in filenames:
 logger.debug(" reading %s", filename)
 f = codecs.open(filename, 'r', encoding='utf-8')
- parser.readfp(f)
- f.close()
+ try:
+ parser.readfp(f)
+ finally:
+ f.close()
 
 if os.path.split(filename)[-1] == 'setup.cfg':
 self._read_setup_cfg(parser, filename)
@@ -348,8 +352,8 @@
 setattr(self.dist, opt, strtobool(val))
 else:
 setattr(self.dist, opt, val)
- except ValueError:
- raise PackagingOptionError(sys.exc_info()[1])
+ except ValueError, msg:
+ raise PackagingOptionError(msg)
 
 def _load_compilers(self, compilers):
 compilers = split_multiline(compilers)
diff --git a/distutils2/create.py b/distutils2/create.py
--- a/distutils2/create.py
+++ b/distutils2/create.py
@@ -18,30 +18,33 @@
 # Ask for a description
 # Detect scripts (not sure how. #! outside of package?)
 
-import codecs
 import os
 import re
 import imp
 import sys
 import glob
+import codecs
 import shutil
-from distutils2._backport import sysconfig
-if 'any' not in dir(__builtins__):
- from distutils2._backport import any
-try:
- from hashlib import md5
-except ImportError: #<2.5
- from md5 import md5
 from textwrap import dedent
+from ConfigParser import RawConfigParser
 from distutils2.util import cmp_to_key, detect_encoding
-from ConfigParser import RawConfigParser
 # importing this with an underscore as it should be replaced by the
 # dict form or another structures for all purposes
 from distutils2._trove import all_classifiers as _CLASSIFIERS_LIST
 from distutils2.version import is_valid_version
+from distutils2._backport import sysconfig
+try:
+ any
+except NameError:
+ from distutils2._backport import any
+try:
+ from hashlib import md5
+except ImportError:
+ from distutils2._backport.hashlib import md5
+
 
 _FILENAME = 'setup.cfg'
-_DEFAULT_CFG = '.pypkgcreate'
+_DEFAULT_CFG = '.pypkgcreate' # FIXME use a section in user .pydistutils.cfg
 
 _helptext = {
 'name': '''
@@ -117,11 +120,16 @@
 been loaded before, because we are monkey patching its setup function with
 a particular one"""
 f = open("setup.py", "rb")
- encoding, lines = detect_encoding(f.readline)
- f.close()
+ try:
+ encoding, lines = detect_encoding(f.readline)
+ finally:
+ f.close()
 f = open("setup.py")
- imp.load_module("setup", f, "setup.py", (".py", "r", imp.PY_SOURCE))
- f.close()
+ try:
+ imp.load_module("setup", f, "setup.py", (".py", "r", imp.PY_SOURCE))
+ finally:
+ f.close()
+
 
 def ask_yn(question, default=None, helptext=None):
 question += ' (y/n)'
@@ -133,6 +141,10 @@
 print '\nERROR: You must select "Y" or "N".\n'
 
 
+# XXX use util.ask
+# FIXME: if prompt ends with '?', don't add ':'
+
+
 def ask(question, default=None, helptext=None, required=True,
 lengthy=False, multiline=False):
 prompt = u'%s: ' % (question,)
@@ -280,50 +292,52 @@
 shutil.move(_FILENAME, '%s.old' % _FILENAME)
 
 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
+ try:
+ 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(u'%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(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')))
+ # 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(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()
+ # 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')
+ finally:
+ fp.close()
 
- os.chmod(_FILENAME, 00644)
+ os.chmod(_FILENAME, 0644)
 print 'Wrote %r.' % _FILENAME
 
 def convert_py_to_cfg(self):
@@ -418,8 +432,10 @@
 ref = ref.digest()
 for readme in glob.glob('README*'):
 fp = codecs.open(readme, encoding='utf-8')
- contents = fp.read()
- fp.close()
+ try:
+ contents = fp.read()
+ finally:
+ 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
@@ -1,15 +1,16 @@
 """PEP 376 implementation."""
 
-from StringIO import StringIO
 import os
 import re
 import csv
 import sys
 import zipimport
+from StringIO import StringIO
 try:
 from hashlib import md5
-except ImportError: #<2.5
- from md5 import md5
+except ImportError:
+ from distutils2._backport.hashlib import md5
+
 from distutils2 import logger
 from distutils2.errors import PackagingError
 from distutils2.version import suggest_normalized_version, VersionPredicate
@@ -162,26 +163,30 @@
 def _get_records(self, local=False):
 results = []
 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()
+ try:
+ 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))
+ finally:
+ record.close()
 return results
 
 def get_resource_path(self, relative_path):
 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()
+ try:
+ resources_reader = csv.reader(resources_file, delimiter=',',
+ lineterminator='\n')
+ for relative, destination in resources_reader:
+ if relative == relative_path:
+ return destination
+ finally:
+ resources_file.close()
 raise KeyError(
 'no resource file with relative path %r is installed' %
 relative_path)
@@ -331,8 +336,10 @@
 try:
 req_path = os.path.join(path, 'EGG-INFO', 'requires.txt')
 fp = open(req_path, 'r')
- requires = fp.read()
- fp.close()
+ try:
+ requires = fp.read()
+ finally:
+ fp.close()
 except IOError:
 requires = None
 else:
@@ -353,8 +360,10 @@
 path = os.path.join(path, 'PKG-INFO')
 try:
 fp = open(os.path.join(path, 'requires.txt'), 'r')
- requires = fp.read()
- fp.close()
+ try:
+ requires = fp.read()
+ finally:
+ fp.close()
 except IOError:
 requires = None
 self.metadata = Metadata(path=path)
@@ -417,8 +426,10 @@
 
 def _md5(path):
 f = open(path, 'rb')
- content = f.read()
- f.close()
+ try:
+ content = f.read()
+ finally:
+ 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
@@ -234,8 +234,7 @@
 graph = generate_graph(dists)
 finally:
 sys.stderr = old
- except Exception:
- e = sys.exc_info()[1]
+ except Exception, e:
 tempout.seek(0)
 tempout = tempout.read()
 print 'Could not generate the graph'
@@ -259,8 +258,10 @@
 filename = 'depgraph.dot'
 
 f = open(filename, 'w')
- graph_to_dot(graph, f, True)
- f.close()
+ try:
+ graph_to_dot(graph, f, True)
+ finally:
+ f.close()
 tempout.seek(0)
 tempout = tempout.read()
 print tempout
diff --git a/distutils2/dist.py b/distutils2/dist.py
--- a/distutils2/dist.py
+++ b/distutils2/dist.py
@@ -1,21 +1,21 @@
-"""Class representing the distribution being built/installed/etc."""
+"""Class representing the project being built/installed/etc."""
 
 import os
 import re
-import sys
 
+from distutils2 import logger
+from distutils2.util import strtobool, resolve_name
 from distutils2.errors import (PackagingOptionError, PackagingArgError,
- PackagingModuleError, PackagingClassError)
-from distutils2.fancy_getopt import FancyGetopt
-from distutils2.util import strtobool, resolve_name
-from distutils2 import logger
-from distutils2.metadata import Metadata
+ PackagingModuleError, PackagingClassError)
 from distutils2.config import Config
 from distutils2.command import get_command_class, STANDARD_COMMANDS
+from distutils2.command.cmd import Command
+from distutils2.metadata import Metadata
+from distutils2.fancy_getopt import FancyGetopt
 
 # Regex to define acceptable Packaging command names. This is not *quite*
-# the same as a Python NAME -- I don't allow leading underscores. The fact
-# that they're very similar is no coincidence; the default naming scheme is
+# the same as a Python name -- leading underscores are not allowed. The fact
+# that they're very similar is no coincidence: the default naming scheme is
 # to look for a Python module named after the command.
 command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
 
@@ -33,17 +33,11 @@
 
 
 class Distribution(object):
- """The core of the Packaging. Most of the work hiding behind 'setup'
- is really done within a Distribution instance, which farms the work out
- to the Packaging commands specified on the command line.
+ """Class used to represent a project and work with it.
 
- Setup scripts will almost never instantiate Distribution directly,
- unless the 'setup()' function is totally inadequate to their needs.
- However, it is conceivable that a setup script might wish to subclass
- Distribution for some specialized purpose, and then pass the subclass
- to 'setup()' as the 'distclass' keyword argument. If so, it is
- necessary to respect the expectations that 'setup' has of Distribution.
- See the code for 'setup()', in run.py, for details.
+ Most of the work hiding behind 'pysetup run' is really done within a
+ Distribution instance, which farms the work out to the commands
+ specified on the command line.
 """
 
 # 'global_options' describes the command-line options that may be
@@ -64,8 +58,8 @@
 common_usage = """\
 Common commands: (see '--help-commands' for more)
 
- pysetup run build will build the package underneath 'build/'
- pysetup run install will install the package
+ pysetup run build will build the project underneath 'build/'
+ pysetup run install will install the project
 """
 
 # options that are not propagated to the commands
@@ -373,7 +367,7 @@
 commands=self.commands)
 return
 
- return 1
+ return True
 
 def _get_toplevel_options(self):
 """Return the non-display options recognized at the top level.
@@ -403,8 +397,8 @@
 # it takes.
 try:
 cmd_class = get_command_class(command)
- except PackagingModuleError:
- raise PackagingArgError(sys.exc_info()[1])
+ except PackagingModuleError, msg:
+ raise PackagingArgError(msg)
 
 # XXX We want to push this in distutils2.command
 #
@@ -501,9 +495,6 @@
 lists per-command help for every command name or command class
 in 'commands'.
 """
- # late import because of mutual dependence between these modules
- from distutils2.command.cmd import Command
-
 if global_options:
 if display_options:
 options = self._get_toplevel_options()
@@ -629,7 +620,7 @@
 """
 cmd_obj = self.command_obj.get(command)
 if not cmd_obj and create:
- logger.debug("Distribution.get_command_obj(): " \
+ logger.debug("Distribution.get_command_obj(): "
 "creating %r command object", command)
 
 cls = get_command_class(command)
@@ -685,8 +676,8 @@
 raise PackagingOptionError(
 "error in %s: command %r has no such option %r" %
 (source, command_name, option))
- except ValueError:
- raise PackagingOptionError(sys.exc_info()[1])
+ except ValueError, msg:
+ raise PackagingOptionError(msg)
 
 def get_reinitialized_command(self, command, reinit_subcommands=False):
 """Reinitializes a command to the state it was in when first
@@ -707,7 +698,6 @@
 
 Returns the reinitialized command object.
 """
- from distutils2.command.cmd import Command
 if not isinstance(command, Command):
 command_name = command
 command = self.get_command_obj(command_name)
@@ -716,6 +706,7 @@
 
 if not command.finalized:
 return command
+
 command.initialize_options()
 self.have_run[command_name] = 0
 command.finalized = False
@@ -780,8 +771,8 @@
 if isinstance(hook, basestring):
 try:
 hook_obj = resolve_name(hook)
- except ImportError:
- raise PackagingModuleError(sys.exc_info()[1])
+ except ImportError, e:
+ raise PackagingModuleError(e)
 else:
 hook_obj = hook
 
diff --git a/distutils2/fancy_getopt.py b/distutils2/fancy_getopt.py
--- a/distutils2/fancy_getopt.py
+++ b/distutils2/fancy_getopt.py
@@ -237,8 +237,8 @@
 
 try:
 opts, args = getopt.getopt(args, short_opts, self.long_opts)
- except getopt.error:
- raise PackagingArgError(sys.exc_info()[1])
+ except getopt.error, msg:
+ raise PackagingArgError(msg)
 
 for opt, val in opts:
 if len(opt) == 2 and opt[0] == '-': # it's a short option
@@ -368,7 +368,7 @@
 if file is None:
 file = sys.stdout
 for line in self.generate_help(header):
- file.write(line + u"\n")
+ file.write(line + "\n")
 
 
 def fancy_getopt(options, negative_opt, object, args):
diff --git a/distutils2/install.py b/distutils2/install.py
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -13,21 +13,22 @@
 import shutil
 import logging
 import tempfile
-from sysconfig import get_config_var, get_path, is_python_build
 
 from distutils2 import logger
 from distutils2.dist import Distribution
 from distutils2.util import (_is_archive_file, ask, get_install_method,
- egginfo_to_distinfo, unpack_archive)
+ egginfo_to_distinfo, unpack_archive)
 from distutils2.pypi import wrapper
 from distutils2.version import get_version_predicate
 from distutils2.database import get_distributions, get_distribution
 from distutils2.depgraph import generate_graph
 
 from distutils2.errors import (PackagingError, InstallationException,
- InstallationConflict, CCompilerError)
+ InstallationConflict, CCompilerError)
 from distutils2.pypi.errors import ProjectNotFound, ReleaseNotFound
 from distutils2 import database
+from distutils2._backport.sysconfig import (get_config_var, get_path,
+ is_python_build)
 
 
 __all__ = ['install_dists', 'install_from_infos', 'get_infos', 'remove',
@@ -50,8 +51,7 @@
 # try to make the paths.
 try:
 os.makedirs(os.path.dirname(new))
- except OSError:
- e = sys.exc_info()[1]
+ except OSError, e:
 if e.errno != errno.EEXIST:
 raise
 os.rename(old, new)
@@ -88,8 +88,8 @@
 dist.run_command('install_dist')
 name = dist.metadata['Name']
 return database.get_distribution(name) is not None
- except (IOError, os.error, PackagingError, CCompilerError):
- raise ValueError("Failed to install, " + str(sys.exc_info()[1]))
+ except (IOError, os.error, PackagingError, CCompilerError), msg:
+ raise ValueError("Failed to install, " + str(msg))
 
 
 def _install_dist(dist, path):
@@ -160,9 +160,9 @@
 try:
 func(source_dir)
 return True
- except ValueError:
+ except ValueError, err:
 # failed to install
- logger.info(str(sys.exc_info()[1]))
+ logger.info(str(err))
 return False
 finally:
 os.chdir(old_dir)
@@ -187,8 +187,8 @@
 try:
 _install_dist(dist, path)
 installed_dists.append(dist)
- except Exception:
- logger.info('Failed: %s', sys.exc_info()[1])
+ except Exception, e:
+ logger.info('Failed: %s', e)
 
 # reverting
 for installed_dist in installed_dists:
@@ -396,8 +396,8 @@
 def _move_file(source, target):
 try:
 os.rename(source, target)
- except OSError:
- return sys.exc_info()[1]
+ except OSError, err:
+ return err
 return None
 
 success = True
@@ -496,9 +496,11 @@
 # trying to write a file there
 try:
 testfile = tempfile.NamedTemporaryFile(suffix=project,
- dir=purelib_path)
- testfile.write('test')
- testfile.close()
+ dir=purelib_path)
+ try:
+ testfile.write('test')
+ finally:
+ testfile.close()
 except OSError:
 # FIXME this should check the errno, or be removed altogether (race
 # condition: the directory permissions could be changed between here
@@ -523,8 +525,7 @@
 install_from_infos(install_path,
 info['install'], info['remove'], info['conflict'])
 
- except InstallationConflict:
- e = sys.exc_info()[1]
+ except InstallationConflict, e:
 if logger.isEnabledFor(logging.INFO):
 projects = ('%r %s' % (p.name, p.version) for p in e.args[0])
 logger.info('%r conflicts with %s', project, ','.join(projects))
diff --git a/distutils2/manifest.py b/distutils2/manifest.py
--- a/distutils2/manifest.py
+++ b/distutils2/manifest.py
@@ -8,13 +8,12 @@
 # XXX todo: document + add tests
 import re
 import os
-import sys
 import fnmatch
 
 from distutils2 import logger
 from distutils2.util import write_file, convert_path
 from distutils2.errors import (PackagingTemplateError,
- PackagingInternalError)
+ PackagingInternalError)
 
 __all__ = ['Manifest']
 
@@ -90,8 +89,8 @@
 continue
 try:
 self._process_template_line(line)
- except PackagingTemplateError:
- logger.warning("%s, %s", path_or_file, sys.exc_info()[1])
+ except PackagingTemplateError, msg:
+ logger.warning("%s, %s", path_or_file, msg)
 
 def write(self, path):
 """Write the file list in 'self.filelist' (presumably as filled in
@@ -100,8 +99,10 @@
 """
 if os.path.isfile(path):
 fp = open(path)
- first_line = fp.readline()
- fp.close()
+ try:
+ first_line = fp.readline()
+ finally:
+ fp.close()
 
 if first_line != '# file GENERATED by distutils2, do NOT edit\n':
 logger.info("not writing to manually maintained "
@@ -122,9 +123,11 @@
 """
 logger.info("reading manifest file %r", path)
 manifest = open(path)
- for line in manifest.readlines():
- self.append(line)
- manifest.close()
+ try:
+ for line in manifest.readlines():
+ self.append(line)
+ finally:
+ 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
@@ -6,6 +6,11 @@
 
 from tokenize import generate_tokens, NAME, OP, STRING, ENDMARKER
 from StringIO import StringIO as BytesIO
+try:
+ python_implementation = platform.python_implementation()
+except AttributeError:
+ # FIXME import from compat
+ python_implementation = 'CPython'
 
 __all__ = ['interpret']
 
@@ -24,10 +29,7 @@
 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],
diff --git a/distutils2/metadata.py b/distutils2/metadata.py
--- a/distutils2/metadata.py
+++ b/distutils2/metadata.py
@@ -3,8 +3,8 @@
 Supports all metadata formats (1.0, 1.1, 1.2).
 """
 
+import re
 import codecs
-import re
 import logging
 
 from StringIO import StringIO
@@ -12,10 +12,10 @@
 from distutils2 import logger
 from distutils2.markers import interpret
 from distutils2.version import (is_valid_predicate, is_valid_version,
- is_valid_versions)
+ is_valid_versions)
 from distutils2.errors import (MetadataMissingError,
- MetadataConflictError,
- MetadataUnrecognizedVersionError)
+ MetadataConflictError,
+ MetadataUnrecognizedVersionError)
 
 try:
 # docutils is installed
@@ -311,8 +311,10 @@
 def read(self, filepath):
 """Read the metadata values from a file path."""
 fp = codecs.open(filepath, 'r', encoding='utf-8')
- self.read_file(fp)
- fp.close()
+ try:
+ self.read_file(fp)
+ finally:
+ fp.close()
 
 def read_file(self, fileob):
 """Read the metadata values from a file object."""
@@ -335,8 +337,10 @@
 def write(self, filepath):
 """Write the metadata fields to filepath."""
 fp = codecs.open(filepath, 'w', encoding='utf-8')
- self.write_file(fp)
- fp.close()
+ try:
+ self.write_file(fp)
+ finally:
+ 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
@@ -10,7 +10,7 @@
 import re
 try:
 import hashlib
-except ImportError: #<2.5
+except ImportError:
 from distutils2._backport import hashlib
 import tempfile
 import urllib
@@ -328,9 +328,11 @@
 expected_hashval = self.url['hashval']
 if None not in (expected_hashval, hashname):
 f = open(filename, 'rb')
- hashval = hashlib.new(hashname)
- hashval.update(f.read())
- f.close()
+ try:
+ hashval = hashlib.new(hashname)
+ hashval.update(f.read())
+ finally:
+ 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
@@ -161,16 +161,18 @@
 Return a list of names.
 """
 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 = []
+ try:
+ 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.close()
+ index_content = index.read()
+ finally:
+ index.close()
 
 # FIXME should use bytes I/O and regexes instead of decoding
 index_content = index_content.decode()
@@ -236,7 +238,9 @@
 self._mirrors_used.add(self.index_url)
 index_url = self._mirrors.pop()
 # XXX use urlparse for a real check of missing scheme part
- if not index_url.startswith(("http://", "https://", "file://")):
+ if not (index_url.startswith("http://") or
+ index_url.startswith("https://") or
+ index_url.startswith("file://")):
 index_url = "http://%s" % index_url
 
 if not index_url.endswith("/simple"):
@@ -327,8 +331,7 @@
 try:
 infos = get_infos_from_url(link, project_name,
 is_external=self.index_url not in url)
- except CantParseArchiveName:
- e = sys.exc_info()[1]
+ except CantParseArchiveName, e:
 if self.verbose:
 logger.warning(
 "version has not been parsed: %s", e)
@@ -410,7 +413,7 @@
 
 # authentication stuff
 if scheme in ('http', 'https'):
- auth, host = urlparse.splituser(netloc)
+ auth, host = urllib2.splituser(netloc)
 else:
 auth = None
 
@@ -432,21 +435,17 @@
 request.add_header('User-Agent', USER_AGENT)
 try:
 fp = urllib2.urlopen(request)
- except (ValueError, httplib.InvalidURL):
- v = sys.exc_info()[1]
+ except (ValueError, httplib.InvalidURL), v:
 msg = ' '.join([str(arg) for arg in v.args])
 raise PackagingPyPIError('%s %s' % (url, msg))
- except urllib2.HTTPError:
- return sys.exc_info()[1]
- except urllib2.URLError:
- v = sys.exc_info()[1]
+ except urllib2.HTTPError, v:
+ return v
+ except urllib2.URLError, v:
 raise DownloadError("Download error for %s: %s" % (url, v.reason))
- except httplib.BadStatusLine:
- v = sys.exc_info()[1]
+ except httplib.BadStatusLine, v:
 raise DownloadError('%s returned a bad status line. '
 'The server might be down, %s' % (url, v.line))
- except httplib.HTTPException:
- v = sys.exc_info()[1]
+ except httplib.HTTPException, v:
 raise DownloadError("Download error for %s: %s" % (url, v))
 except socket.timeout:
 raise DownloadError("The server timeouted")
diff --git a/distutils2/pypi/wrapper.py b/distutils2/pypi/wrapper.py
--- a/distutils2/pypi/wrapper.py
+++ b/distutils2/pypi/wrapper.py
@@ -31,8 +31,8 @@
 try:
 response = method(*args, **kwargs)
 retry = False
- except Exception:
- exception = sys.exc_info()[1]
+ except Exception, e:
+ exception = e
 if not retry:
 break
 if retry and exception:
diff --git a/distutils2/pypi/xmlrpc.py b/distutils2/pypi/xmlrpc.py
--- a/distutils2/pypi/xmlrpc.py
+++ b/distutils2/pypi/xmlrpc.py
@@ -13,7 +13,7 @@
 from distutils2.version import get_version_predicate
 from distutils2.pypi.base import BaseClient
 from distutils2.pypi.errors import (ProjectNotFound, InvalidSearchField,
- ReleaseNotFound)
+ ReleaseNotFound)
 from distutils2.pypi.dist import ReleaseInfo
 
 __all__ = ['Client', 'DEFAULT_XMLRPC_INDEX_URL']
@@ -171,8 +171,7 @@
 project.add_release(release=ReleaseInfo(p['name'],
 p['version'], metadata={'summary': p['summary']},
 index=self._index))
- except IrrationalVersionError:
- e = sys.exc_info()[1]
+ except IrrationalVersionError, e:
 logger.warning("Irrational version error found: %s", e)
 return [self._projects[p['name'].lower()] for p in projects]
 
diff --git a/distutils2/run.py b/distutils2/run.py
--- a/distutils2/run.py
+++ b/distutils2/run.py
@@ -15,8 +15,8 @@
 from distutils2.depgraph import generate_graph
 from distutils2.fancy_getopt import FancyGetopt
 from distutils2.errors import (PackagingArgError, PackagingError,
- PackagingModuleError, PackagingClassError,
- CCompilerError)
+ PackagingModuleError, PackagingClassError,
+ CCompilerError)
 
 
 command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
@@ -473,8 +473,8 @@
 # it takes.
 try:
 cmd_class = get_command_class(command)
- except PackagingModuleError:
- raise PackagingArgError(sys.exc_info()[1])
+ except PackagingModuleError, msg:
+ raise PackagingArgError(msg)
 
 # XXX We want to push this in distutils2.command
 #
@@ -674,22 +674,21 @@
 old_level = logger.level
 old_handlers = list(logger.handlers)
 try:
- dispatcher = Dispatcher(args)
- if dispatcher.action is None:
- return
- return dispatcher()
- except KeyboardInterrupt:
- logger.info('interrupted')
- return 1
- except (IOError, os.error, PackagingError, CCompilerError):
- logger.exception(sys.exc_info()[1])
- return 1
- except:
+ try:
+ dispatcher = Dispatcher(args)
+ if dispatcher.action is None:
+ return
+ return dispatcher()
+ except KeyboardInterrupt:
+ logger.info('interrupted')
+ return 1
+ except (IOError, os.error, PackagingError, CCompilerError), exc:
+ logger.exception(exc)
+ return 1
+ finally:
 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/__main__.py b/distutils2/tests/__main__.py
--- a/distutils2/tests/__main__.py
+++ b/distutils2/tests/__main__.py
@@ -4,8 +4,8 @@
 
 import os
 import sys
-import unittest2
-from .support import run_unittest, reap_children, reap_threads
+from distutils2.tests import unittest
+from distutils2.tests.support import reap_children, reap_threads, run_unittest
 
 
 @reap_threads
@@ -13,7 +13,9 @@
 try:
 start_dir = os.path.dirname(__file__)
 top_dir = os.path.dirname(os.path.dirname(start_dir))
- test_loader = unittest2.TestLoader()
+ test_loader = unittest.TestLoader()
+ # XXX find out how to use unittest.main, to get command-line options
+ # (failfast, catch, etc.)
 run_unittest(test_loader.discover(start_dir, top_level_dir=top_dir))
 finally:
 reap_children()
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
@@ -30,19 +30,21 @@
 """
 
 import os
-import queue
+import Queue
 import select
 import threading
-import socketserver
+import SocketServer
+from BaseHTTPServer import HTTPServer
+from SimpleHTTPServer import SimpleHTTPRequestHandler
+from SimpleXMLRPCServer import SimpleXMLRPCServer
+
+from distutils2.tests import unittest
+
 try:
 from functools import wraps
 except ImportError:
 from distutils2._backport.functools import wraps
 
-from http.server import HTTPServer, SimpleHTTPRequestHandler
-from xmlrpc.server import SimpleXMLRPCServer
-
-from distutils2.tests import unittest
 
 PYPI_DEFAULT_STATIC_PATH = os.path.join(
 os.path.dirname(os.path.abspath(__file__)), 'pypiserver')
@@ -117,7 +119,7 @@
 self.server = HTTPServer(('127.0.0.1', 0), PyPIRequestHandler)
 self.server.RequestHandlerClass.pypi_server = self
 
- self.request_queue = queue.Queue()
+ self.request_queue = Queue.Queue()
 self._requests = []
 self.default_response_status = 404
 self.default_response_headers = [('Content-type', 'text/plain')]
@@ -154,7 +156,7 @@
 def stop(self):
 """self shutdown is not supported for python < 2.6"""
 self._run = False
- if self.is_alive():
+ if self.isAlive():
 self.join()
 self.server.server_close()
 
@@ -171,7 +173,7 @@
 while True:
 try:
 self._requests.append(self.request_queue.get_nowait())
- except queue.Empty:
+ except Queue.Empty:
 break
 return self._requests
 
@@ -275,7 +277,7 @@
 class PyPIXMLRPCServer(SimpleXMLRPCServer):
 def server_bind(self):
 """Override server_bind to store the server name."""
- socketserver.TCPServer.server_bind(self)
+ SocketServer.TCPServer.server_bind(self)
 host, port = self.socket.getsockname()[:2]
 self.server_port = port
 
diff --git a/distutils2/tests/test_command_build.py b/distutils2/tests/test_command_build.py
--- a/distutils2/tests/test_command_build.py
+++ b/distutils2/tests/test_command_build.py
@@ -3,7 +3,7 @@
 import sys
 
 from distutils2.command.build import build
-from sysconfig import get_platform
+from distutils2._backport.sysconfig import get_platform
 from distutils2.tests import unittest, support
 
 
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
@@ -5,6 +5,7 @@
 import textwrap
 from StringIO import StringIO
 from distutils2._backport import sysconfig
+from distutils2._backport.sysconfig import _CONFIG_VARS
 from distutils2.dist import Distribution
 from distutils2.errors import (UnknownFileError, CompileError,
 PackagingPlatformError)
@@ -36,9 +37,10 @@
 filename = _get_source_filename()
 if os.path.exists(filename):
 shutil.copy(filename, self.tmp_dir)
- self.old_user_base = site.USER_BASE
- site.USER_BASE = self.mkdtemp()
- build_ext.USER_BASE = site.USER_BASE
+ if sys.version > "2.6":
+ self.old_user_base = site.USER_BASE
+ site.USER_BASE = self.mkdtemp()
+ build_ext.USER_BASE = site.USER_BASE
 
 def tearDown(self):
 # Get everything back to normal
@@ -122,7 +124,6 @@
 old = sys.platform
 
 sys.platform = 'sunos' # fooling finalize_options
- from sysconfig import _CONFIG_VARS
 
 old_var = _CONFIG_VARS.get('Py_ENABLE_SHARED')
 _CONFIG_VARS['Py_ENABLE_SHARED'] = 1
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
@@ -18,7 +18,7 @@
 from distutils2.tests.pypi_server import PyPIServerTestCase
 except ImportError:
 threading = None
- PyPIServerTestCase = object
+ PyPIServerTestCase = unittest.TestCase
 
 
 PYPIRC = """\
@@ -32,8 +32,7 @@
 """
 
 
-class UploadDocsTestCase(unittest.TestCase,
- support.TempdirManager,
+class UploadDocsTestCase(support.TempdirManager,
 support.EnvironRestorer,
 support.LoggingCatcher,
 PyPIServerTestCase):
diff --git a/distutils2/tests/test_install.py b/distutils2/tests/test_install.py
--- a/distutils2/tests/test_install.py
+++ b/distutils2/tests/test_install.py
@@ -1,7 +1,6 @@
 """Tests for the distutils2.install module."""
 import os
 import logging
-from sysconfig import is_python_build
 from tempfile import mkstemp
 
 from distutils2 import install
@@ -9,6 +8,8 @@
 from distutils2.metadata import Metadata
 from distutils2.tests.support import (LoggingCatcher, TempdirManager, unittest,
 fake_dec)
+from distutils2._backport.sysconfig import is_python_build
+
 try:
 import threading
 from distutils2.tests.pypi_server import use_xmlrpc_server
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,3 +1,4 @@
+import sys
 import textwrap
 
 from distutils2.tests import unittest, support
@@ -8,8 +9,7 @@
 support.LoggingCatcher,
 unittest.TestCase):
 
- #@unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
- @unittest.skipIf(True, 'Not needed for backport')
+ @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
 def test_convert_code_only(self):
 # used to check if code gets converted properly.
 code = "print 'test'"
@@ -28,8 +28,7 @@
 
 self.assertEqual(expected, converted)
 
- #@unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
- @unittest.skipIf(True, 'Not needed for backport')
+ @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
 def test_doctests_only(self):
 # used to check if doctests gets converted properly.
 doctest = textwrap.dedent('''\
@@ -62,8 +61,7 @@
 
 self.assertEqual(expected, converted)
 
- #@unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
- @unittest.skipIf(True, 'Not needed for backport')
+ @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
 def test_additional_fixers(self):
 # used to check if use_2to3_fixers works
 code = 'type(x) is not T'
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
@@ -12,9 +12,9 @@
 fake_dec)
 
 try:
- import _thread
+ import thread as _thread
 from distutils2.tests.pypi_server import (use_pypi_server, PyPIServer,
- PYPI_DEFAULT_STATIC_PATH)
+ PYPI_DEFAULT_STATIC_PATH)
 except ImportError:
 _thread = None
 use_pypi_server = fake_dec
diff --git a/distutils2/util.py b/distutils2/util.py
--- a/distutils2/util.py
+++ b/distutils2/util.py
@@ -180,8 +180,8 @@
 
 try:
 return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s)
- except KeyError:
- raise ValueError("invalid variable '$%s'" % sys.exc_info()[1])
+ except KeyError, e:
+ raise ValueError("invalid variable '$%s'" % e)
 
 
 # Needed by 'split_quoted()'
@@ -334,7 +334,7 @@
 """
 # nothing is done if sys.dont_write_bytecode is True
 # FIXME this should not raise an error
- if hasattr(sys, 'dont_write_bytecode') and sys.dont_write_bytecode:
+ if getattr(sys, 'dont_write_bytecode', False):
 raise PackagingByteCompileError('byte-compiling is disabled.')
 
 # First, if the caller didn't force us into direct or indirect mode,
@@ -354,7 +354,7 @@
 # run it with the appropriate flags.
 if not direct:
 from tempfile import mkstemp
- # XXX script_fd may leak, use something better than mkstemp
+ # XXX use something better than mkstemp
 script_fd, script_name = mkstemp(".py")
 os.close(script_fd)
 script_fd = None
@@ -365,33 +365,36 @@
 else:
 script = codecs.open(script_name, "w", encoding='utf-8')
 
- script.write("""\
+ try:
+ 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()
+ finally:
+ script.close()
+
 cmd = [sys.executable, script_name]
 if optimize == 1:
 cmd.insert(1, "-O")
@@ -553,9 +556,11 @@
 *contents* is a sequence of strings without line terminators.
 """
 f = open(filename, "w")
- for line in contents:
- f.write(line + "\n")
- f.close()
+ try:
+ for line in contents:
+ f.write(line + "\n")
+ finally:
+ f.close()
 
 def _is_package(path):
 return os.path.isdir(path) and os.path.isfile(
@@ -657,8 +662,8 @@
 for part in parts[1:]:
 try:
 ret = getattr(ret, part)
- except AttributeError:
- raise ImportError(sys.exc_info()[1])
+ except AttributeError, exc:
+ raise ImportError(exc)
 
 return ret
 
@@ -775,6 +780,7 @@
 _cfg_target = None
 _cfg_target_split = None
 
+
 def spawn(cmd, search_path=True, verbose=0, dry_run=False, env=None):
 """Run another program specified as a command list 'cmd' in a new process.
 
@@ -872,11 +878,12 @@
 """Create a default .pypirc file."""
 rc = get_pypirc_path()
 f = open(rc, 'w')
- f.write(DEFAULT_PYPIRC % (username, password))
- f.close()
-
 try:
- os.chmod(rc, 00600)
+ f.write(DEFAULT_PYPIRC % (username, password))
+ finally:
+ f.close()
+ try:
+ os.chmod(rc, 0600)
 except OSError:
 # should do something better here
 pass
@@ -1084,8 +1091,10 @@
 raise PackagingFileError("file '%s' does not exist" %
 os.path.abspath(path))
 f = codecs.open(path, encoding='utf-8')
- config.readfp(f)
- f.close()
+ try:
+ config.readfp(f)
+ finally:
+ f.close()
 
 kwargs = {}
 for arg in D1_D2_SETUP_ARGS:
@@ -1108,8 +1117,10 @@
 in_cfg_value = []
 for filename in filenames:
 fp = open(filename)
- in_cfg_value.append(fp.read())
- fp.close()
+ try:
+ in_cfg_value.append(fp.read())
+ finally:
+ fp.close()
 in_cfg_value = '\n\n'.join(in_cfg_value)
 else:
 continue
@@ -1147,8 +1158,10 @@
 raise PackagingFileError("a setup.py file already exists")
 
 fp = codecs.open("setup.py", "w", encoding='utf-8')
- fp.write(_SETUP_TMPL % {'func': getsource(cfg_to_args)})
- fp.close()
+ try:
+ fp.write(_SETUP_TMPL % {'func': getsource(cfg_to_args)})
+ finally:
+ fp.close()
 
 
 # Taken from the pip project
@@ -1168,26 +1181,29 @@
 def _parse_record_file(record_file):
 distinfo, extra_metadata, installed = ({}, [], [])
 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)
+ try:
+ 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)
+ finally:
+ rfile.close()
 
 distinfo['egginfo'] = egginfo
 distinfo['metadata'] = metadata
@@ -1204,25 +1220,29 @@
 
 def _write_record_file(record_path, installed_files):
 f = codecs.open(record_path, 'w', encoding='utf-8')
- writer = csv.writer(f, delimiter=',', lineterminator=os.linesep,
- quotechar='"')
+ try:
+ 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()
- fp = open(fpath, 'rb')
- hash.update(fp.read())
- fp.close()
- 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')
+ try:
+ hash.update(fp.read())
+ finally:
+ fp.close()
+ md5sum = hash.hexdigest()
+ size = os.path.getsize(fpath)
+ writer.writerow((fpath, md5sum, size))
 
- # add the RECORD file itself
- writer.writerow((record_path, '', ''))
- f.close()
+ # add the RECORD file itself
+ writer.writerow((record_path, '', ''))
+ finally:
+ f.close()
 return record_path
 
 
@@ -1258,8 +1278,10 @@
 installer_path = distinfo['installer_path']
 logger.info('creating %s', installer_path)
 f = open(installer_path, 'w')
- f.write(installer)
- f.close()
+ try:
+ f.write(installer)
+ finally:
+ f.close()
 
 if requested:
 requested_path = distinfo['requested_path']
@@ -1301,13 +1323,15 @@
 
 def _has_text(setup_py, installer):
 installer_pattern = re.compile('import %s|from %s' % (
- installer[0], installer[1]))
+ installer[0], installer[0]))
 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()
+ try:
+ for line in setup:
+ if re.search(installer_pattern, line):
+ logger.debug("Found %s text in setup.py.", installer)
+ return True
+ finally:
+ setup.close()
 logger.debug("No %s text found in setup.py.", installer)
 return False
 
@@ -1315,8 +1339,10 @@
 def _has_required_metadata(setup_cfg):
 config = RawConfigParser()
 f = codecs.open(setup_cfg, 'r', encoding='utf8')
- config.readfp(f)
- f.close()
+ try:
+ config.readfp(f)
+ finally:
+ f.close()
 return (config.has_section('metadata') and
 'name' in config.options('metadata') and
 'version' in config.options('metadata'))
@@ -1377,7 +1403,7 @@
 _has_distutils_text(setup_py))
 
 
-def is_distutils2(path):
+def is_packaging(path):
 """Check if the project is based on distutils2
 
 :param path: path to source directory containing a setup.cfg file.
@@ -1398,7 +1424,7 @@
 
 Returns a string representing the best install method to use.
 """
- if is_distutils2(path):
+ if is_packaging(path):
 return "distutils2"
 elif is_setuptools(path):
 return "setuptools"
@@ -1419,8 +1445,8 @@
 "cannot copy tree '%s': not a directory" % src)
 try:
 names = os.listdir(src)
- except os.error:
- errstr = sys.exc_info()[1][1]
+ except os.error, e:
+ errstr = e[1]
 if dry_run:
 names = []
 else:
@@ -1465,7 +1491,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=00777, verbose=True, dry_run=False):
+def _mkpath(name, mode=0777, verbose=True, dry_run=False):
 # Detect a common bug -- name is None
 if not isinstance(name, basestring):
 raise PackagingInternalError(
@@ -1506,8 +1532,7 @@
 if not dry_run:
 try:
 os.mkdir(head, mode)
- except OSError:
- exc = sys.exc_info()[1]
+ except OSError, exc:
 if not (exc.errno == errno.EEXIST and os.path.isdir(head)):
 raise PackagingFileError(
 "could not create '%s': %s" % (head, exc.args[-1]))
diff --git a/distutils2/version.py b/distutils2/version.py
--- a/distutils2/version.py
+++ b/distutils2/version.py
@@ -182,7 +182,6 @@
 return "%s('%s')" % (self.__class__.__name__, self)
 
 def _cannot_compare(self, other):
- import pdb; pdb.set_trace()
 raise TypeError("cannot compare %s and %s"
 % (type(self).__name__, type(other).__name__))
 
-- 
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /