[Python-checkins] distutils2 (merge default -> python3): Branch merge

eric.araujo python-checkins at python.org
Mon Nov 21 14:21:37 CET 2011


http://hg.python.org/distutils2/rev/49e4d8a859c9
changeset:   1260:49e4d8a859c9
branch:      python3
parent:      1251:7fe2f04a24cc
parent:      1259:c898ebb74f28
user:        Éric Araujo <merwok at netwok.org>
date:        Sun Nov 20 19:45:31 2011 +0100
summary:
  Branch merge

files:
  CHANGES.txt                                  |    3 +
  CONTRIBUTORS.txt                             |    1 +
  distutils2/_backport/shutil.py               |    7 +-
  distutils2/_backport/tarfile.py              |    7 +-
  distutils2/_backport/tests/test_sysconfig.py |    2 +-
  distutils2/command/bdist_dumb.py             |    2 +-
  distutils2/command/bdist_msi.py              |    3 +-
  distutils2/command/bdist_wininst.py          |    3 +-
  distutils2/command/build_ext.py              |    6 -
  distutils2/command/clean.py                  |    5 +-
  distutils2/command/cmd.py                    |   18 +-
  distutils2/command/install_distinfo.py       |    2 +-
  distutils2/command/sdist.py                  |    5 +-
  distutils2/command/test.py                   |    3 +-
  distutils2/compiler/__init__.py              |    9 +-
  distutils2/compiler/bcppcompiler.py          |    4 +-
  distutils2/compiler/ccompiler.py             |    5 +-
  distutils2/compiler/cygwinccompiler.py       |    8 +-
  distutils2/compiler/msvc9compiler.py         |    4 +-
  distutils2/compiler/msvccompiler.py          |    4 +-
  distutils2/config.py                         |    1 -
  distutils2/create.py                         |    3 +-
  distutils2/tests/__init__.py                 |  105 +------
  distutils2/tests/support.py                  |    3 +-
  distutils2/tests/test_command_bdist.py       |    7 +-
  distutils2/tests/test_command_sdist.py       |    7 +-
  distutils2/tests/test_command_test.py        |    2 +-
  distutils2/tests/test_command_upload_docs.py |    2 +-
  distutils2/tests/test_config.py              |    2 +-
  distutils2/tests/test_database.py            |    9 +-
  distutils2/tests/test_dist.py                |    1 -
  distutils2/tests/test_pypi_dist.py           |    5 +-
  distutils2/tests/test_support.py             |   85 +++++
  distutils2/util.py                           |   27 +-
  runtests.py                                  |  164 +++++++--
  35 files changed, 292 insertions(+), 232 deletions(-)


diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -157,6 +157,9 @@
 - Rename get_reinitialized_command back to reinitialize_command [éric]
 - Rename install_distinfo's option from distinfo-dir to the more usual
   install_dir [éric]
+- Remove verbose arguments for Command and Compiler classes as well as util
+  functions, obsoleted by logging [éric]
+- #12659: Add tests for tests.support [francisco]
 
 
 1.0a3 - 2010-10-08
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -17,6 +17,7 @@
 - Anthony Baxter
 - Erik Bray
 - C. Titus Brown
+- Francisco Martín Brugué
 - Nicolas Cadou
 - Godefroid Chapelle
 - Christophe Combelles
diff --git a/distutils2/_backport/shutil.py b/distutils2/_backport/shutil.py
--- a/distutils2/_backport/shutil.py
+++ b/distutils2/_backport/shutil.py
@@ -11,6 +11,7 @@
 import fnmatch
 import collections
 import errno
+from distutils2._backport import tarfile
 
 try:
     import bz2
@@ -402,10 +403,6 @@
             os.makedirs(archive_dir)
 
     # creating the tarball
-    # XXX late import because of circular dependency between shutil and
-    # tarfile :(
-    from distutils2._backport import tarfile
-
     if logger is not None:
         logger.info('Creating tar archive')
 
@@ -695,8 +692,6 @@
 def _unpack_tarfile(filename, extract_dir):
     """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir`
     """
-    # late import because of circular dependency
-    from distutils2._backport import tarfile
     try:
         tarobj = tarfile.open(filename)
     except tarfile.TarError:
diff --git a/distutils2/_backport/tarfile.py b/distutils2/_backport/tarfile.py
--- a/distutils2/_backport/tarfile.py
+++ b/distutils2/_backport/tarfile.py
@@ -42,7 +42,6 @@
 #---------
 import sys
 import os
-import shutil
 import stat
 import errno
 import time
@@ -255,7 +254,11 @@
     if length == 0:
         return
     if length is None:
-        shutil.copyfileobj(src, dst)
+        while True:
+            buf = src.read(16*1024)
+            if not buf:
+                break
+            dst.write(buf)
         return
 
     BUFSIZE = 16 * 1024
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
@@ -1,10 +1,10 @@
 import os
 import sys
 import subprocess
-import shutil
 from copy import copy
 from io import StringIO
 
+from distutils2._backport import shutil
 from distutils2._backport import sysconfig
 from distutils2._backport.sysconfig import (
     get_paths, get_platform, get_config_vars, get_path, get_path_names,
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
@@ -5,12 +5,12 @@
 """
 
 import os
-from shutil import rmtree
 
 from distutils2.util import get_platform
 from distutils2.command.cmd import Command
 from distutils2.errors import PackagingPlatformError
 from distutils2 import logger
+from distutils2._backport.shutil import rmtree
 from distutils2._backport.sysconfig import get_python_version
 
 
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
@@ -7,9 +7,8 @@
 import os
 import msilib
 
-
+from distutils2._backport.shutil import rmtree
 from distutils2._backport.sysconfig import get_python_version
-from shutil import rmtree
 from distutils2.command.cmd import Command
 from distutils2.version import NormalizedVersion
 from distutils2.errors import PackagingOptionError
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
@@ -3,12 +3,11 @@
 import sys
 import os
 
-from shutil import rmtree
-
 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.shutil import rmtree
 from distutils2._backport.sysconfig import get_python_version
 
 
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
@@ -4,7 +4,6 @@
 import re
 import sys
 import site
-import logging
 
 from distutils2._backport import sysconfig
 from distutils2.util import get_platform
@@ -288,14 +287,9 @@
             self.libraries.extend(build_clib.get_library_names() or [])
             self.library_dirs.append(build_clib.build_clib)
 
-        # Temporary kludge until we remove the verbose arguments and use
-        # logging everywhere
-        verbose = logger.getEffectiveLevel() >= logging.DEBUG
-
         # Setup the CCompiler object that we'll use to do all the
         # compiling and linking
         self.compiler_obj = new_compiler(compiler=self.compiler,
-                                         verbose=verbose,
                                          dry_run=self.dry_run,
                                          force=self.force)
 
diff --git a/distutils2/command/clean.py b/distutils2/command/clean.py
--- a/distutils2/command/clean.py
+++ b/distutils2/command/clean.py
@@ -3,9 +3,10 @@
 # Contributed by Bastian Kleineidam <calvin at cs.uni-sb.de>
 
 import os
-from shutil import rmtree
+from distutils2 import logger
 from distutils2.command.cmd import Command
-from distutils2 import logger
+from distutils2._backport.shutil import rmtree
+
 
 class clean(Command):
 
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=0o777, dry_run=None):
         if dry_run is None:
             dry_run = self.dry_run
         name = os.path.normpath(name)
@@ -367,9 +367,11 @@
 
     def copy_file(self, infile, outfile,
                   preserve_mode=True, preserve_times=True, link=None, level=1):
-        """Copy a file respecting verbose, dry-run and force flags.  (The
-        former two default to whatever is in the Distribution object, and
-        the latter defaults to false for commands that don't define it.)"""
+        """Copy a file respecting dry-run and force flags.
+
+        (dry-run defaults to whatever is in the Distribution object, and
+        force to false for commands that don't define it.)
+        """
         if self.dry_run:
             # XXX add a comment
             return
@@ -380,11 +382,13 @@
 
     def copy_tree(self, infile, outfile, preserve_mode=True,
                   preserve_times=True, preserve_symlinks=False, level=1):
-        """Copy an entire directory tree respecting verbose, dry-run,
+        """Copy an entire directory tree respecting dry-run
         and force flags.
         """
         if self.dry_run:
-            return  # see if we want to display something
+            # XXX should not return but let copy_tree log and decide to execute
+            # or not based on its dry_run argument
+            return
 
         return util.copy_tree(infile, outfile, preserve_mode, preserve_times,
             preserve_symlinks, not self.force, dry_run=self.dry_run)
@@ -392,7 +396,7 @@
     def move_file(self, src, dst, level=1):
         """Move a file respecting the dry-run flag."""
         if self.dry_run:
-            return  # XXX log ?
+            return  # XXX same thing
         return move(src, dst)
 
     def spawn(self, cmd, search_path=True, level=1):
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
@@ -5,10 +5,10 @@
 import os
 import csv
 import hashlib
-from shutil import rmtree
 
 from distutils2 import logger
 from distutils2.command.cmd import Command
+from distutils2._backport.shutil import rmtree
 
 
 class install_distinfo(Command):
diff --git a/distutils2/command/sdist.py b/distutils2/command/sdist.py
--- a/distutils2/command/sdist.py
+++ b/distutils2/command/sdist.py
@@ -337,12 +337,11 @@
         """
         return self.archive_files
 
-    def create_tree(self, base_dir, files, mode=0o777, verbose=1,
-                    dry_run=False):
+    def create_tree(self, base_dir, files, mode=0o777, dry_run=False):
         need_dir = set()
         for file in files:
             need_dir.add(os.path.join(base_dir, os.path.dirname(file)))
 
         # Now create them
         for dir in sorted(need_dir):
-            self.mkpath(dir, mode, verbose=verbose, dry_run=dry_run)
+            self.mkpath(dir, mode, dry_run=dry_run)
diff --git a/distutils2/command/test.py b/distutils2/command/test.py
--- a/distutils2/command/test.py
+++ b/distutils2/command/test.py
@@ -60,8 +60,7 @@
             self.run_command('build')
             sys.path.insert(0, build.build_lib)
 
-            # Temporary kludge until we remove the verbose arguments and use
-            # logging everywhere
+            # XXX maybe we could pass the verbose argument of pysetup here
             logger = logging.getLogger('distutils2')
             verbose = logger.getEffectiveLevel() >= logging.DEBUG
             verbosity = verbose + 1
diff --git a/distutils2/compiler/__init__.py b/distutils2/compiler/__init__.py
--- a/distutils2/compiler/__init__.py
+++ b/distutils2/compiler/__init__.py
@@ -153,8 +153,7 @@
     pretty_printer.print_help("List of available compilers:")
 
 
-def new_compiler(plat=None, compiler=None, verbose=0, dry_run=False,
-                 force=False):
+def new_compiler(plat=None, compiler=None, dry_run=False, force=False):
     """Generate an instance of some CCompiler subclass for the supplied
     platform/compiler combination.  'plat' defaults to 'os.name'
     (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler
@@ -183,11 +182,7 @@
         cls = resolve_name(cls)
         _COMPILERS[compiler] = cls
 
-
-    # XXX The None is necessary to preserve backwards compatibility
-    # with classes that expect verbose to be the first positional
-    # argument.
-    return cls(None, dry_run, force)
+    return cls(dry_run, force)
 
 
 def gen_preprocess_options(macros, include_dirs):
diff --git a/distutils2/compiler/bcppcompiler.py b/distutils2/compiler/bcppcompiler.py
--- a/distutils2/compiler/bcppcompiler.py
+++ b/distutils2/compiler/bcppcompiler.py
@@ -47,8 +47,8 @@
     exe_extension = '.exe'
 
 
-    def __init__(self, verbose=0, dry_run=False, force=False):
-        super(BCPPCompiler, self).__init__(verbose, dry_run, force)
+    def __init__(self, dry_run=False, force=False):
+        super(BCPPCompiler, self).__init__(dry_run, force)
 
         # These executables are assumed to all be in the path.
         # Borland doesn't seem to use any special registry settings to
diff --git a/distutils2/compiler/ccompiler.py b/distutils2/compiler/ccompiler.py
--- a/distutils2/compiler/ccompiler.py
+++ b/distutils2/compiler/ccompiler.py
@@ -5,11 +5,11 @@
 """
 
 import os
-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.compiler import gen_preprocess_options
+from distutils2._backport.shutil import move
 
 
 class CCompiler:
@@ -79,10 +79,9 @@
                    }
     language_order = ["c++", "objc", "c"]
 
-    def __init__(self, verbose=0, dry_run=False, force=False):
+    def __init__(self, dry_run=False, force=False):
         self.dry_run = dry_run
         self.force = force
-        self.verbose = verbose
 
         # 'output_dir': a common output directory for object, library,
         # shared object, and shared library files
diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py
--- a/distutils2/compiler/cygwinccompiler.py
+++ b/distutils2/compiler/cygwinccompiler.py
@@ -92,8 +92,8 @@
     shared_lib_format = "%s%s"
     exe_extension = ".exe"
 
-    def __init__(self, verbose=0, dry_run=False, force=False):
-        super(CygwinCCompiler, self).__init__(verbose, dry_run, force)
+    def __init__(self, dry_run=False, force=False):
+        super(CygwinCCompiler, self).__init__(dry_run, force)
 
         status, details = check_config_h()
         logger.debug("Python's GCC status: %s (details: %s)", status, details)
@@ -270,8 +270,8 @@
     name = 'mingw32'
     description = 'MinGW32 compiler'
 
-    def __init__(self, verbose=0, dry_run=False, force=False):
-        super(Mingw32CCompiler, self).__init__(verbose, dry_run, force)
+    def __init__(self, dry_run=False, force=False):
+        super(Mingw32CCompiler, self).__init__(dry_run, force)
 
         # ld_version >= "2.13" support -shared so use it instead of
         # -mdll -static
diff --git a/distutils2/compiler/msvc9compiler.py b/distutils2/compiler/msvc9compiler.py
--- a/distutils2/compiler/msvc9compiler.py
+++ b/distutils2/compiler/msvc9compiler.py
@@ -309,8 +309,8 @@
     static_lib_format = shared_lib_format = '%s%s'
     exe_extension = '.exe'
 
-    def __init__(self, verbose=0, dry_run=False, force=False):
-        super(MSVCCompiler, self).__init__(verbose, dry_run, force)
+    def __init__(self, dry_run=False, force=False):
+        super(MSVCCompiler, self).__init__(dry_run, force)
         self.__version = VERSION
         self.__root = r"Software\Microsoft\VisualStudio"
         # self.__macros = MACROS
diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py
--- a/distutils2/compiler/msvccompiler.py
+++ b/distutils2/compiler/msvccompiler.py
@@ -236,8 +236,8 @@
     static_lib_format = shared_lib_format = '%s%s'
     exe_extension = '.exe'
 
-    def __init__(self, verbose=0, dry_run=False, force=False):
-        super(MSVCCompiler, self).__init__(verbose, dry_run, force)
+    def __init__(self, dry_run=False, force=False):
+        super(MSVCCompiler, self).__init__(dry_run, force)
         self.__version = get_build_version()
         self.__arch = get_build_architecture()
         if self.__arch == "Intel":
diff --git a/distutils2/config.py b/distutils2/config.py
--- a/distutils2/config.py
+++ b/distutils2/config.py
@@ -20,7 +20,6 @@
     if '.' not in name:
         return
     parts = name.split('.')
-    modname = parts[-1]
     parent = '.'.join(parts[:-1])
     if parent not in packages:
         # we could log a warning instead of raising, but what's the use
diff --git a/distutils2/create.py b/distutils2/create.py
--- a/distutils2/create.py
+++ b/distutils2/create.py
@@ -23,7 +23,6 @@
 import imp
 import sys
 import glob
-import shutil
 from hashlib import md5
 from textwrap import dedent
 from tokenize import detect_encoding
@@ -34,7 +33,7 @@
 # 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
+from distutils2._backport import shutil, sysconfig
 
 
 _FILENAME = 'setup.cfg'
diff --git a/distutils2/tests/__init__.py b/distutils2/tests/__init__.py
--- a/distutils2/tests/__init__.py
+++ b/distutils2/tests/__init__.py
@@ -14,17 +14,11 @@
 import os
 import sys
 import unittest2 as unittest
-from io import StringIO
-
-# XXX move helpers to support, add tests for them, remove things that
-# duplicate test.support (or keep them for the backport; needs thinking)
-
-here = os.path.dirname(__file__) or os.curdir
-verbose = 1
 
 
 def test_suite():
     suite = unittest.TestSuite()
+    here = os.path.dirname(__file__) or os.curdir
     for fn in os.listdir(here):
         if fn.startswith("test") and fn.endswith(".py"):
             modname = "distutils2.tests." + fn[:-3]
@@ -32,100 +26,3 @@
             module = sys.modules[modname]
             suite.addTest(module.test_suite())
     return suite
-
-
-class Error(Exception):
-    """Base class for regression test exceptions."""
-
-
-class TestFailed(Error):
-    """Test failed."""
-
-
-class BasicTestRunner:
-    def run(self, test):
-        result = unittest.TestResult()
-        test(result)
-        return result
-
-
-def _run_suite(suite, verbose_=1):
-    """Run tests from a unittest.TestSuite-derived class."""
-    global verbose
-    verbose = verbose_
-    if verbose_:
-        runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
-    else:
-        runner = BasicTestRunner()
-
-    result = runner.run(suite)
-    if not result.wasSuccessful():
-        if len(result.errors) == 1 and not result.failures:
-            err = result.errors[0][1]
-        elif len(result.failures) == 1 and not result.errors:
-            err = result.failures[0][1]
-        else:
-            err = "errors occurred; run in verbose mode for details"
-        raise TestFailed(err)
-
-
-def run_unittest(classes, verbose_=1):
-    """Run tests from unittest.TestCase-derived classes.
-
-    Originally extracted from stdlib test.support and modified to
-    support unittest2.
-    """
-    valid_types = (unittest.TestSuite, unittest.TestCase)
-    suite = unittest.TestSuite()
-    for cls in classes:
-        if isinstance(cls, str):
-            if cls in sys.modules:
-                suite.addTest(unittest.findTestCases(sys.modules[cls]))
-            else:
-                raise ValueError("str arguments must be keys in sys.modules")
-        elif isinstance(cls, valid_types):
-            suite.addTest(cls)
-        else:
-            suite.addTest(unittest.makeSuite(cls))
-    _run_suite(suite, verbose_)
-
-
-def reap_children():
-    """Use this function at the end of test_main() whenever sub-processes
-    are started.  This will help ensure that no extra children (zombies)
-    stick around to hog resources and create problems when looking
-    for refleaks.
-
-    Extracted from stdlib test.support.
-    """
-
-    # Reap all our dead child processes so we don't leave zombies around.
-    # These hog resources and might be causing some of the buildbots to die.
-    if hasattr(os, 'waitpid'):
-        any_process = -1
-        while True:
-            try:
-                # This will raise an exception on Windows.  That's ok.
-                pid, status = os.waitpid(any_process, os.WNOHANG)
-                if pid == 0:
-                    break
-            except:
-                break
-
-
-def captured_stdout(func, *args, **kw):
-    orig_stdout = getattr(sys, 'stdout')
-    setattr(sys, 'stdout', StringIO())
-    try:
-        res = func(*args, **kw)
-        sys.stdout.seek(0)
-        return res, sys.stdout.read()
-    finally:
-        setattr(sys, 'stdout', orig_stdout)
-
-
-def unload(name):
-    try:
-        del sys.modules[name]
-    except KeyError:
-        pass
diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py
--- a/distutils2/tests/support.py
+++ b/distutils2/tests/support.py
@@ -36,7 +36,6 @@
 import re
 import sys
 import errno
-import shutil
 import logging
 import logging.handlers
 import subprocess
@@ -52,7 +51,7 @@
 from distutils2.command import set_command, _COMMANDS
 
 from distutils2.tests import unittest
-from distutils2._backport import sysconfig
+from distutils2._backport import shutil, sysconfig
 
 # define __all__ to make pydoc more useful
 __all__ = [
diff --git a/distutils2/tests/test_command_bdist.py b/distutils2/tests/test_command_bdist.py
--- a/distutils2/tests/test_command_bdist.py
+++ b/distutils2/tests/test_command_bdist.py
@@ -1,7 +1,8 @@
 """Tests for distutils.command.bdist."""
 import os
+from test.support import captured_stdout
 from distutils2.command.bdist import bdist, show_formats
-from distutils2.tests import unittest, support, captured_stdout
+from distutils2.tests import unittest, support
 
 
 class BuildTestCase(support.TempdirManager,
@@ -42,7 +43,9 @@
                             '%s should take --skip-build from bdist' % name)
 
     def test_show_formats(self):
-        __, stdout = captured_stdout(show_formats)
+        with captured_stdout() as stdout:
+            show_formats()
+        stdout = stdout.getvalue()
 
         # the output should be a header line + one line per format
         num_formats = len(bdist.format_commands)
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
@@ -1,5 +1,6 @@
 """Tests for distutils2.command.sdist."""
 import os
+import sys
 import zipfile
 
 try:
@@ -17,8 +18,8 @@
 from distutils2._backport import tarfile
 from distutils2._backport.shutil import get_archive_formats
 
+from test.support import captured_stdout
 from distutils2.tests import support, unittest
-from distutils2.tests import captured_stdout
 from distutils2.tests.support import requires_zlib
 
 
@@ -240,7 +241,9 @@
         self.assertIn("'setup.cfg' file not found", warnings[1])
 
     def test_show_formats(self):
-        __, stdout = captured_stdout(show_formats)
+        with captured_stdout() as stdout:
+            show_formats()
+        stdout = stdout.getvalue()
 
         # the output should be a header line + one line per format
         num_formats = len(get_archive_formats())
diff --git a/distutils2/tests/test_command_test.py b/distutils2/tests/test_command_test.py
--- a/distutils2/tests/test_command_test.py
+++ b/distutils2/tests/test_command_test.py
@@ -1,7 +1,6 @@
 import os
 import re
 import sys
-import shutil
 import unittest as ut1
 import distutils2.database
 
@@ -14,6 +13,7 @@
 from distutils2.command.test import test
 from distutils2.command import set_command
 from distutils2.dist import Distribution
+from distutils2._backport import shutil
 
 
 EXPECTED_OUTPUT_RE = r'''FAIL: test_blah \(myowntestmodule.SomeTest\)
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 shutil
 import logging
 import zipfile
 try:
@@ -12,6 +11,7 @@
 from distutils2.command.upload_docs import upload_docs, zip_dir
 from distutils2.dist import Distribution
 from distutils2.errors import PackagingFileError, PackagingOptionError
+from distutils2._backport import shutil
 
 from distutils2.tests import unittest, support
 try:
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
@@ -119,7 +119,7 @@
     /usr/include/blitz
 extra_compile_args = -fPIC -O2
     -DGECODE_VERSION=$(./gecode_version) -- sys.platform != 'win32'
-    /DGECODE_VERSION='win32' -- sys.platform == 'win32'
+    /DGECODE_VERSION=win32 -- sys.platform == 'win32'
 language = cxx
 
 # corner case: if the parent package of an extension is declared but
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
@@ -2,7 +2,6 @@
 import io
 import csv
 import sys
-import shutil
 import tempfile
 from hashlib import md5
 from textwrap import dedent
@@ -10,6 +9,7 @@
 from distutils2.tests.test_util import GlobTestCaseBase
 from distutils2.tests.support import requires_zlib
 
+import distutils2.database
 from distutils2.config import get_resources_dests
 from distutils2.errors import PackagingError
 from distutils2.metadata import Metadata
@@ -19,6 +19,7 @@
     provides_distribution, obsoletes_distribution, get_file_users,
     enable_cache, disable_cache, distinfo_dirname, _yield_distributions,
     get_file, get_file_path)
+from distutils2._backport import shutil
 
 # TODO Add a test for getting a distribution provided by another distribution
 # TODO Add a test for absolute pathed RECORD items (e.g. /etc/myapp/config.ini)
@@ -279,6 +280,12 @@
         sys.path.insert(0, self.fake_dists_path)
         self.addCleanup(sys.path.remove, self.fake_dists_path)
 
+    def test_caches(self):
+        # sanity check for internal caches
+        for name in ('_cache_name', '_cache_name_egg',
+                     '_cache_path', '_cache_path_egg'):
+            self.assertEqual(getattr(distutils2.database, name), {})
+
     def test_distinfo_dirname(self):
         # Given a name and a version, we expect the distinfo_dirname function
         # to return a standard distribution information directory name.
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
@@ -8,7 +8,6 @@
 from distutils2.dist import Distribution
 from distutils2.command.cmd import Command
 from distutils2.errors import PackagingModuleError, PackagingOptionError
-from distutils2.tests import captured_stdout
 from distutils2.tests import support, unittest
 from distutils2.tests.support import create_distribution, use_command
 from distutils2.tests.support import unload
diff --git a/distutils2/tests/test_pypi_dist.py b/distutils2/tests/test_pypi_dist.py
--- a/distutils2/tests/test_pypi_dist.py
+++ b/distutils2/tests/test_pypi_dist.py
@@ -1,11 +1,11 @@
 """Tests for the distutils2.pypi.dist module."""
 
 import os
-import shutil
 from distutils2.version import VersionPredicate
 from distutils2.pypi.dist import (ReleaseInfo, ReleasesList, DistInfo,
-                                 split_archive_name, get_infos_from_url)
+                                  split_archive_name, get_infos_from_url)
 from distutils2.pypi.errors import HashDoesNotMatch, UnsupportedHashName
+from distutils2._backport import shutil
 
 from distutils2.tests import unittest
 from distutils2.tests.support import TempdirManager, requires_zlib, fake_dec
@@ -38,6 +38,7 @@
         # should not fail
         release['sdist']
 
+    @unittest.skip('needs to be written')
     def test_get_unknown_distribution(self):
         # should raise a KeyError
         pass
diff --git a/distutils2/tests/test_support.py b/distutils2/tests/test_support.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/test_support.py
@@ -0,0 +1,85 @@
+import os
+import tempfile
+
+from distutils2.dist import Distribution
+from distutils2.tests import support, unittest
+
+
+class TestingSupportTestCase(unittest.TestCase):
+
+    def test_fake_dec(self):
+        @support.fake_dec(1, 2, k=3)
+        def func(arg0, *args, **kargs):
+            return arg0, args, kargs
+        self.assertEqual(func(-1, -2, k=-3), (-1, (-2,), {'k': -3}))
+
+    def test_TempdirManager(self):
+        files = {}
+
+        class Tester(support.TempdirManager, unittest.TestCase):
+
+            def runTest(self):
+                # empty method required for the backport
+                pass
+
+            def test_mktempfile(self2):
+                tmpfile = self2.mktempfile()
+                files['test_mktempfile'] = tmpfile.name
+                self.assertTrue(os.path.isfile(tmpfile.name))
+
+            def test_mkdtemp(self2):
+                tmpdir = self2.mkdtemp()
+                files['test_mkdtemp'] = tmpdir
+                self.assertTrue(os.path.isdir(tmpdir))
+
+            def test_write_file(self2):
+                tmpdir = self2.mkdtemp()
+                files['test_write_file'] = tmpdir
+                self2.write_file((tmpdir, 'file1'), 'me file 1')
+                file1 = os.path.join(tmpdir, 'file1')
+                self.assertTrue(os.path.isfile(file1))
+                text = ''
+                f = open(file1, 'r')
+                try:
+                    text = f.read()
+                finally:
+                    f.close()
+                self.assertEqual(text, 'me file 1')
+
+            def test_create_dist(self2):
+                project_dir, dist = self2.create_dist()
+                files['test_create_dist'] = project_dir
+                self.assertTrue(os.path.isdir(project_dir))
+                self.assertIsInstance(dist, Distribution)
+
+            def test_assertIsFile(self2):
+                fd, fn = tempfile.mkstemp()
+                os.close(fd)
+                self.addCleanup(support.unlink, fn)
+                self2.assertIsFile(fn)
+                self.assertRaises(AssertionError, self2.assertIsFile, 'foO')
+
+            def test_assertIsNotFile(self2):
+                tmpdir = self2.mkdtemp()
+                self2.assertIsNotFile(tmpdir)
+
+        tester = Tester()
+        for name in ('test_mktempfile', 'test_mkdtemp', 'test_write_file',
+                     'test_create_dist', 'test_assertIsFile',
+                     'test_assertIsNotFile'):
+            tester.setUp()
+            try:
+                getattr(tester, name)()
+            finally:
+                tester.tearDown()
+
+            # check clean-up
+            if name in files:
+                self.assertFalse(os.path.exists(files[name]))
+
+
+def test_suite():
+    return unittest.makeSuite(TestingSupportTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")
diff --git a/distutils2/util.py b/distutils2/util.py
--- a/distutils2/util.py
+++ b/distutils2/util.py
@@ -3,11 +3,9 @@
 import os
 import re
 import csv
-import imp
 import sys
 import errno
 import codecs
-import shutil
 import string
 import hashlib
 import posixpath
@@ -22,7 +20,7 @@
 from distutils2.errors import (PackagingPlatformError, PackagingFileError,
                                PackagingExecError, InstallationException,
                                PackagingInternalError)
-from distutils2._backport import sysconfig
+from distutils2._backport import shutil, sysconfig
 
 __all__ = [
     # file dependencies
@@ -260,7 +258,7 @@
             if element]
 
 
-def execute(func, args, msg=None, verbose=0, dry_run=False):
+def execute(func, args, msg=None, dry_run=False):
     """Perform some action that affects the outside world.
 
     Some actions (e.g. writing to the filesystem) are special because
@@ -683,7 +681,7 @@
     _cfg_target_split = None
 
 
-def spawn(cmd, search_path=True, verbose=0, dry_run=False, env=None):
+def spawn(cmd, search_path=True, dry_run=False, env=None):
     """Run another program specified as a command list 'cmd' in a new process.
 
     'cmd' is just the argument list for the new process, ie.
@@ -1334,8 +1332,7 @@
 
 # XXX to be replaced by shutil.copytree
 def copy_tree(src, dst, preserve_mode=True, preserve_times=True,
-              preserve_symlinks=False, update=False, verbose=True,
-              dry_run=False):
+              preserve_symlinks=False, update=False, dry_run=False):
     # FIXME use of this function is why we get spurious logging message on
     # stdout when tests run; kill and replace by shutil!
     from distutils.file_util import copy_file
@@ -1354,7 +1351,7 @@
                   "error listing files in '%s': %s" % (src, errstr))
 
     if not dry_run:
-        _mkpath(dst, verbose=verbose)
+        _mkpath(dst)
 
     outputs = []
 
@@ -1364,8 +1361,7 @@
 
         if preserve_symlinks and os.path.islink(src_name):
             link_dest = os.readlink(src_name)
-            if verbose >= 1:
-                logger.info("linking %s -> %s", dst_name, link_dest)
+            logger.info("linking %s -> %s", dst_name, link_dest)
             if not dry_run:
                 os.symlink(link_dest, dst_name)
             outputs.append(dst_name)
@@ -1374,11 +1370,10 @@
             outputs.extend(
                 copy_tree(src_name, dst_name, preserve_mode,
                           preserve_times, preserve_symlinks, update,
-                          verbose=verbose, dry_run=dry_run))
+                          dry_run=dry_run))
         else:
             copy_file(src_name, dst_name, preserve_mode,
-                      preserve_times, update, verbose=verbose,
-                      dry_run=dry_run)
+                      preserve_times, update, dry_run=dry_run)
             outputs.append(dst_name)
 
     return outputs
@@ -1391,7 +1386,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=0o777, dry_run=False):
     # Detect a common bug -- name is None
     if not isinstance(name, str):
         raise PackagingInternalError(
@@ -1426,9 +1421,7 @@
         if abs_head in _path_created:
             continue
 
-        if verbose >= 1:
-            logger.info("creating %s", head)
-
+        logger.info("creating %s", head)
         if not dry_run:
             try:
                 os.mkdir(head, mode)
diff --git a/runtests.py b/runtests.py
--- a/runtests.py
+++ b/runtests.py
@@ -1,15 +1,110 @@
 #!/usr/bin/env python
-"""Tests for distutils2.
+"""Test runner for distutils2.
 
 The tests for distutils2 are defined in the distutils2.tests package.
+They can also be executed with the unittest2 runner or nose.
 """
 
+import os
 import sys
 from os.path import dirname, islink, realpath, join, abspath
 from optparse import OptionParser
+from distutils2.tests import unittest
+
+
+# unittest machinery copied from stdlib's test.regrtest and test.support
+
+class TestFailed(Exception):
+    """Test failed."""
+
+
+class BasicTestRunner:
+    def run(self, test):
+        result = unittest.TestResult()
+        test(result)
+        return result
+
+
+def reap_children():
+    """Use this function at the end of test_main() whenever sub-processes
+    are started.  This will help ensure that no extra children (zombies)
+    stick around to hog resources and create problems when looking
+    for refleaks.
+    """
+
+    # Reap all our dead child processes so we don't leave zombies around.
+    # These hog resources and might be causing some of the buildbots to die.
+    if hasattr(os, 'waitpid'):
+        any_process = -1
+        while True:
+            try:
+                # This will raise an exception on Windows.  That's ok.
+                pid, status = os.waitpid(any_process, os.WNOHANG)
+                if pid == 0:
+                    break
+            except:
+                break
+
+
+def _run_suite(suite, verbose=True):
+    """Run tests from a unittest.TestSuite-derived class."""
+    if verbose:
+        runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
+    else:
+        runner = BasicTestRunner()
+
+    result = runner.run(suite)
+    if not result.wasSuccessful():
+        if len(result.errors) == 1 and not result.failures:
+            err = result.errors[0][1]
+        elif len(result.failures) == 1 and not result.errors:
+            err = result.failures[0][1]
+        else:
+            err = "errors occurred; run in verbose mode for details"
+        raise TestFailed(err)
+
+
+def run_unittest(classes, verbose=True):
+    """Run tests from unittest.TestCase-derived classes.
+
+    Originally extracted from stdlib test.test_support and modified to
+    support unittest2.
+    """
+    valid_types = (unittest.TestSuite, unittest.TestCase)
+    suite = unittest.TestSuite()
+    for cls in classes:
+        if isinstance(cls, str):
+            if cls in sys.modules:
+                suite.addTest(unittest.findTestCases(sys.modules[cls]))
+            else:
+                raise ValueError("str arguments must be keys in sys.modules")
+        elif isinstance(cls, valid_types):
+            suite.addTest(cls)
+        else:
+            suite.addTest(unittest.makeSuite(cls))
+    _run_suite(suite, verbose)
+
+
+def run_tests(verbose):
+    # do NOT import those at the top level, coverage will be inaccurate if
+    # distutils2 modules are imported before coverage magic is started
+    from distutils2.tests import test_suite
+    from distutils2._backport.tests import test_suite as btest_suite
+    try:
+        try:
+            run_unittest([test_suite(), btest_suite()], verbose=verbose)
+            return 0
+        except TestFailed:
+            return 1
+    finally:
+        reap_children()
+
+
+# coverage-related code
 
 COVERAGE_FILE = join(dirname(abspath(__file__)), '.coverage')
 
+
 def get_coverage():
     """ Return a usable coverage object. """
     # deferred import because coverage is optional
@@ -19,52 +114,34 @@
         cov = coverage.coverage(COVERAGE_FILE)
     return cov
 
+
 def ignore_prefixes(module):
     """ Return a list of prefixes to ignore in the coverage report if
     we want to completely skip `module`.
     """
-    # A function like that is needed because some GNU/Linux
-    # distributions, such a Ubuntu, really like to build link farm in
-    # /usr/lib in order to save a few bytes on the disk.
+    # A function like that is needed because some operating systems like Debian
+    # and derivatives use symlinks directory in order to save disk space
     dirnames = [dirname(module.__file__)]
 
-    pymod = module.__file__.rstrip("c")
+    pymod = module.__file__.rstrip('co')
     if islink(pymod):
         dirnames.append(dirname(realpath(pymod)))
     return dirnames
 
 
-def parse_opts():
-    parser = OptionParser(usage="%prog [OPTIONS]",
-                          description="run the distutils2 unittests")
-
-    parser.add_option("-q", "--quiet", help="do not print verbose messages",
-                      action="store_true", default=False)
-    parser.add_option("-c", "--coverage", action="store_true", default=False,
-                      help="produce a coverage report at the end of the run")
-    parser.add_option("-r", "--report", action="store_true", default=False,
-                      help="produce a coverage report from the last test run")
-    parser.add_option("-m", "--show-missing", action="store_true",
-                      default=False,
-                      help=("Show line numbers of statements in each module "
-                            "that weren't executed."))
-
-    opts, args = parser.parse_args()
-    return opts, args
-
-
 def coverage_report(opts):
     from distutils2.tests.support import unittest
     cov = get_coverage()
     if hasattr(cov, "load"):
         # running coverage 3.x
         cov.load()
+        # morfs means modules or files
         morfs = None
     else:
         # running coverage 2.x
         cov.cache = COVERAGE_FILE
         cov.restore()
-        morfs = [m for m in list(cov.cexecuted.keys()) if "distutils2" in m]
+        morfs = [m for m in cov.cexecuted if "distutils2" in m]
 
     prefixes = ["runtests", "distutils2/tests", "distutils2/_backport"]
     prefixes += ignore_prefixes(unittest)
@@ -93,6 +170,28 @@
                    omit=[p + "*" for p in prefixes],
                    show_missing=opts.show_missing)
 
+
+# command-line parsing
+
+def parse_opts():
+    parser = OptionParser(usage="%prog [OPTIONS]",
+                          description="run the distutils2 unittests")
+
+    parser.add_option("-q", "--quiet", help="do not print verbose messages",
+                      action="store_true", default=False)
+    parser.add_option("-c", "--coverage", action="store_true", default=False,
+                      help="produce a coverage report at the end of the run")
+    parser.add_option("-r", "--report", action="store_true", default=False,
+                      help="produce a coverage report from the last test run")
+    parser.add_option("-m", "--show-missing", action="store_true",
+                      default=False,
+                      help=("Show line numbers of statements in each module "
+                            "that weren't executed."))
+
+    opts, args = parser.parse_args()
+    return opts, args
+
+
 def test_main():
     opts, args = parse_opts()
     # FIXME when we run with --quiet, we still want to see errors and failures
@@ -115,20 +214,5 @@
     return ret
 
 
-def run_tests(verbose):
-    # do NOT import those at the top level, coverage will be inaccurate if
-    # modules are imported before its magic is started
-    from distutils2.tests import run_unittest, test_suite, reap_children, TestFailed
-    from distutils2._backport.tests import test_suite as btest_suite
-    try:
-        try:
-            run_unittest([test_suite(), btest_suite()], verbose_=verbose)
-            return 0
-        except TestFailed:
-            return 1
-    finally:
-        reap_children()
-
-
 if __name__ == "__main__":
     sys.exit(test_main())

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


More information about the Python-checkins mailing list