[Python-checkins] distutils2 (merge default -> python3): Merge fixes for #13462 and others from default

eric.araujo python-checkins at python.org
Fri Feb 10 05:11:17 CET 2012


http://hg.python.org/distutils2/rev/cc0f4d208193
changeset:   1284:cc0f4d208193
branch:      python3
parent:      1283:a22859e3ebb9
parent:      1282:0cc1fbbb473d
user:        Éric Araujo <merwok at netwok.org>
date:        Thu Feb 09 21:05:47 2012 +0100
summary:
  Merge fixes for #13462 and others from default

files:
  distutils2/command/__init__.py                |   48 +--
  distutils2/command/bdist_msi.py               |    2 +-
  distutils2/command/bdist_wininst.py           |    2 +-
  distutils2/command/build.py                   |    6 +-
  distutils2/command/install_dist.py            |    2 +-
  distutils2/compat.py                          |   17 +-
  distutils2/compiler/cygwinccompiler.py        |    4 +
  distutils2/markers.py                         |    4 +-
  distutils2/pypi/simple.py                     |    4 +-
  distutils2/run.py                             |    9 +-
  distutils2/tests/fixer/fix_echo.py            |   16 +
  distutils2/tests/fixer/fix_echo2.py           |   16 +
  distutils2/tests/fixer/fix_idioms.py          |  134 ----------
  distutils2/tests/support.py                   |   18 +-
  distutils2/tests/test_command_bdist_dumb.py   |    2 +-
  distutils2/tests/test_command_build.py        |    5 +-
  distutils2/tests/test_command_build_py.py     |    8 +-
  distutils2/tests/test_command_install_dist.py |    2 +-
  distutils2/tests/test_command_install_lib.py  |    2 +-
  distutils2/tests/test_markers.py              |   10 +-
  distutils2/tests/test_mixin2to3.py            |   92 +++---
  distutils2/tests/test_pypi_simple.py          |    2 +-
  distutils2/tests/test_run.py                  |   29 +-
  distutils2/util.py                            |   18 +-
  24 files changed, 185 insertions(+), 267 deletions(-)


diff --git a/distutils2/command/__init__.py b/distutils2/command/__init__.py
--- a/distutils2/command/__init__.py
+++ b/distutils2/command/__init__.py
@@ -6,38 +6,28 @@
 __all__ = ['get_command_names', 'set_command', 'get_command_class',
            'STANDARD_COMMANDS']
 
-_COMMANDS = {
-    'check': 'distutils2.command.check.check',
-    'test': 'distutils2.command.test.test',
-    'build': 'distutils2.command.build.build',
-    'build_py': 'distutils2.command.build_py.build_py',
-    'build_ext': 'distutils2.command.build_ext.build_ext',
-    'build_clib': 'distutils2.command.build_clib.build_clib',
-    'build_scripts': 'distutils2.command.build_scripts.build_scripts',
-    'clean': 'distutils2.command.clean.clean',
-    'install_dist': 'distutils2.command.install_dist.install_dist',
-    'install_lib': 'distutils2.command.install_lib.install_lib',
-    'install_headers': 'distutils2.command.install_headers.install_headers',
-    'install_scripts': 'distutils2.command.install_scripts.install_scripts',
-    'install_data': 'distutils2.command.install_data.install_data',
-    'install_distinfo':
-        'distutils2.command.install_distinfo.install_distinfo',
-    'sdist': 'distutils2.command.sdist.sdist',
-    'bdist': 'distutils2.command.bdist.bdist',
-    'bdist_dumb': 'distutils2.command.bdist_dumb.bdist_dumb',
-    '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',
-}
 
-# XXX this is crappy
+STANDARD_COMMANDS = [
+    # packaging
+    'check', 'test',
+    # building
+    'build', 'build_py', 'build_ext', 'build_clib', 'build_scripts', 'clean',
+    # installing
+    'install_dist', 'install_lib', 'install_headers', 'install_scripts',
+    'install_data', 'install_distinfo',
+    # distributing
+    'sdist', 'bdist', 'bdist_dumb', 'bdist_wininst',
+    'register', 'upload', 'upload_docs',
+    ]
+
 if os.name == 'nt':
-    _COMMANDS['bdist_msi'] = 'distutils2.command.bdist_msi.bdist_msi'
+    STANDARD_COMMANDS.insert(STANDARD_COMMANDS.index('bdist_wininst'),
+                             'bdist_msi')
 
-# XXX use OrderedDict to preserve the grouping (build-related, install-related,
-# distribution-related)
-STANDARD_COMMANDS = set(_COMMANDS)
+# XXX maybe we need more than one registry, so that --list-comands can display
+# standard, custom and overriden standard commands differently
+_COMMANDS = dict((name, 'distutils2.command.%s.%s' % (name, name))
+                 for name in STANDARD_COMMANDS)
 
 
 def get_command_names():
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
@@ -203,7 +203,7 @@
             target_version = self.target_version
             if not target_version:
                 assert self.skip_build, "Should have already checked this"
-                target_version = sys.version[0:3]
+                target_version = '%s.%s' % sys.version_info[:2]
             plat_specifier = ".%s-%s" % (self.plat_name, target_version)
             build = self.get_finalized_command('build')
             build.build_lib = os.path.join(build.build_base,
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
@@ -136,7 +136,7 @@
             target_version = self.target_version
             if not target_version:
                 assert self.skip_build, "Should have already checked this"
-                target_version = sys.version[0:3]
+                target_version = '%s.%s' % sys.version_info[:2]
             plat_specifier = ".%s-%s" % (self.plat_name, target_version)
             build = self.get_finalized_command('build')
             build.build_lib = os.path.join(build.build_base,
diff --git a/distutils2/command/build.py b/distutils2/command/build.py
--- a/distutils2/command/build.py
+++ b/distutils2/command/build.py
@@ -82,8 +82,8 @@
                 raise PackagingOptionError(
                             "--plat-name only supported on Windows (try "
                             "using './configure --help' on your platform)")
-
-        plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3])
+        pyversion = '%s.%s' % sys.version_info[:2]
+        plat_specifier = ".%s-%s" % (self.plat_name, pyversion)
 
         # Make it so Python 2.x and Python 2.x with --with-pydebug don't
         # share the same build directories. Doing so confuses the build
@@ -116,7 +116,7 @@
                                            'temp' + plat_specifier)
         if self.build_scripts is None:
             self.build_scripts = os.path.join(self.build_base,
-                                              'scripts-' + sys.version[0:3])
+                                              'scripts-' + pyversion)
 
         if self.executable is None:
             self.executable = os.path.normpath(sys.executable)
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
@@ -242,7 +242,7 @@
         # $platbase in the other installation directories and not worry
         # about needing recursive variable expansion (shudder).
 
-        py_version = sys.version.split()[0]
+        py_version = '%s.%s' % sys.version_info[:2]
         prefix, exec_prefix, srcdir, projectbase = get_config_vars(
             'prefix', 'exec_prefix', 'srcdir', 'projectbase')
 
diff --git a/distutils2/compat.py b/distutils2/compat.py
--- a/distutils2/compat.py
+++ b/distutils2/compat.py
@@ -25,7 +25,7 @@
     """
     if _CONVERT:
 
-        def _run_2to3(self, files, doctests=[], fixers=[]):
+        def _run_2to3(self, files=[], doctests=[], fixers=[]):
             """ Takes a list of files and doctests, and performs conversion
             on those.
               - First, the files which contain the code(`files`) are converted.
@@ -35,17 +35,16 @@
             if fixers:
                 self.fixer_names = fixers
 
-            logger.info('converting Python code')
-            _KLASS.run_2to3(self, files)
+            if files:
+                logger.info('converting Python code and doctests')
+                _KLASS.run_2to3(self, files)
+                _KLASS.run_2to3(self, files, doctests_only=True)
 
-            logger.info('converting doctests in Python files')
-            _KLASS.run_2to3(self, files, doctests_only=True)
-
-            if doctests != []:
-                logger.info('converting doctest in text files')
+            if doctests:
+                logger.info('converting doctests in text files')
                 _KLASS.run_2to3(self, doctests, doctests_only=True)
     else:
         # If run on Python 2.x, there is nothing to do.
 
-        def _run_2to3(self, files, doctests=[], fixers=[]):
+        def _run_2to3(self, files=[], doctests=[], fixers=[]):
             pass
diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py
--- a/distutils2/compiler/cygwinccompiler.py
+++ b/distutils2/compiler/cygwinccompiler.py
@@ -56,6 +56,10 @@
 from distutils2.util import get_compiler_versions
 from distutils2._backport import sysconfig
 
+# TODO use platform instead of sys.version
+# (platform does unholy sys.version parsing too, but at least it gives other
+# VMs a chance to override the returned values)
+
 
 def get_msvcr():
     """Include the appropriate MSVC runtime library if Python was built
diff --git a/distutils2/markers.py b/distutils2/markers.py
--- a/distutils2/markers.py
+++ b/distutils2/markers.py
@@ -26,7 +26,9 @@
 
 # restricted set of variables
 _VARS = {'sys.platform': sys.platform,
-         'python_version': sys.version[:3],
+         'python_version': '%s.%s' % sys.version_info[:2],
+         # FIXME parsing sys.platform is not reliable, but there is no other
+         # way to get e.g. 2.7.2+, and the PEP is defined with sys.version
          'python_full_version': sys.version.split(' ', 1)[0],
          'os.name': os.name,
          'platform.version': platform.version(),
diff --git a/distutils2/pypi/simple.py b/distutils2/pypi/simple.py
--- a/distutils2/pypi/simple.py
+++ b/distutils2/pypi/simple.py
@@ -35,8 +35,8 @@
 DEFAULT_SIMPLE_INDEX_URL = "http://a.pypi.python.org/simple/"
 DEFAULT_HOSTS = ("*",)
 SOCKET_TIMEOUT = 15
-USER_AGENT = "Python-urllib/%s distutils2/%s" % (
-    sys.version[:3], distutils2_version)
+USER_AGENT = "Python-urllib/%s.%s distutils2/%s" % (
+    sys.version_info[0], sys.version_info[1], distutils2_version)
 
 # -- Regexps -------------------------------------------------
 EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$')
diff --git a/distutils2/run.py b/distutils2/run.py
--- a/distutils2/run.py
+++ b/distutils2/run.py
@@ -255,16 +255,13 @@
     parser = dispatcher.parser
     args = args[1:]
 
-    commands = STANDARD_COMMANDS  # + extra commands
+    commands = STANDARD_COMMANDS  # FIXME display extra commands
 
     if args == ['--list-commands']:
         print('List of available commands:')
-        cmds = sorted(commands)
-
-        for cmd in cmds:
+        for cmd in commands:
             cls = dispatcher.cmdclass.get(cmd) or get_command_class(cmd)
-            desc = getattr(cls, 'description',
-                            '(no description available)')
+            desc = getattr(cls, 'description', '(no description available)')
             print('  %s: %s' % (cmd, desc))
         return
 
diff --git a/distutils2/tests/fixer/fix_echo.py b/distutils2/tests/fixer/fix_echo.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fixer/fix_echo.py
@@ -0,0 +1,16 @@
+# Example custom fixer, derived from fix_raw_input by Andre Roberge
+
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Name
+
+
+class FixEcho(fixer_base.BaseFix):
+
+    BM_compatible = True
+    PATTERN = """
+              power< name='echo' trailer< '(' [any] ')' > any* >
+              """
+
+    def transform(self, node, results):
+        name = results['name']
+        name.replace(Name('print', prefix=name.prefix))
diff --git a/distutils2/tests/fixer/fix_echo2.py b/distutils2/tests/fixer/fix_echo2.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fixer/fix_echo2.py
@@ -0,0 +1,16 @@
+# Example custom fixer, derived from fix_raw_input by Andre Roberge
+
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Name
+
+
+class FixEcho2(fixer_base.BaseFix):
+
+    BM_compatible = True
+    PATTERN = """
+              power< name='echo2' trailer< '(' [any] ')' > any* >
+              """
+
+    def transform(self, node, results):
+        name = results['name']
+        name.replace(Name('print', prefix=name.prefix))
diff --git a/distutils2/tests/fixer/fix_idioms.py b/distutils2/tests/fixer/fix_idioms.py
deleted file mode 100644
--- a/distutils2/tests/fixer/fix_idioms.py
+++ /dev/null
@@ -1,134 +0,0 @@
-"""Adjust some old Python 2 idioms to their modern counterparts.
-
-* Change some type comparisons to isinstance() calls:
-    type(x) == T -> isinstance(x, T)
-    type(x) is T -> isinstance(x, T)
-    type(x) != T -> not isinstance(x, T)
-    type(x) is not T -> not isinstance(x, T)
-
-* Change "while 1:" into "while True:".
-
-* Change both
-
-    v = list(EXPR)
-    v.sort()
-    foo(v)
-
-and the more general
-
-    v = EXPR
-    v.sort()
-    foo(v)
-
-into
-
-    v = sorted(EXPR)
-    foo(v)
-"""
-# Author: Jacques Frechet, Collin Winter
-
-# Local imports
-from lib2to3 import fixer_base
-from lib2to3.fixer_util import Call, Comma, Name, Node, syms
-
-CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)"
-TYPE = "power< 'type' trailer< '(' x=any ')' > >"
-
-class FixIdioms(fixer_base.BaseFix):
-
-    explicit = False # The user must ask for this fixer
-
-    PATTERN = r"""
-        isinstance=comparison< %s %s T=any >
-        |
-        isinstance=comparison< T=any %s %s >
-        |
-        while_stmt< 'while' while='1' ':' any+ >
-        |
-        sorted=any<
-            any*
-            simple_stmt<
-              expr_stmt< id1=any '='
-                         power< list='list' trailer< '(' (not arglist<any+>) any ')' > >
-              >
-              '\n'
-            >
-            sort=
-            simple_stmt<
-              power< id2=any
-                     trailer< '.' 'sort' > trailer< '(' ')' >
-              >
-              '\n'
-            >
-            next=any*
-        >
-        |
-        sorted=any<
-            any*
-            simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' >
-            sort=
-            simple_stmt<
-              power< id2=any
-                     trailer< '.' 'sort' > trailer< '(' ')' >
-              >
-              '\n'
-            >
-            next=any*
-        >
-    """ % (TYPE, CMP, CMP, TYPE)
-
-    def match(self, node):
-        r = super(FixIdioms, self).match(node)
-        # If we've matched one of the sort/sorted subpatterns above, we
-        # want to reject matches where the initial assignment and the
-        # subsequent .sort() call involve different identifiers.
-        if r and "sorted" in r:
-            if r["id1"] == r["id2"]:
-                return r
-            return None
-        return r
-
-    def transform(self, node, results):
-        if "isinstance" in results:
-            return self.transform_isinstance(node, results)
-        elif "while" in results:
-            return self.transform_while(node, results)
-        elif "sorted" in results:
-            return self.transform_sort(node, results)
-        else:
-            raise RuntimeError("Invalid match")
-
-    def transform_isinstance(self, node, results):
-        x = results["x"].clone() # The thing inside of type()
-        T = results["T"].clone() # The type being compared against
-        x.prefix = ""
-        T.prefix = " "
-        test = Call(Name("isinstance"), [x, Comma(), T])
-        if "n" in results:
-            test.prefix = " "
-            test = Node(syms.not_test, [Name("not"), test])
-        test.prefix = getattr(node, 'prefix', ' ')
-        return test
-
-    def transform_while(self, node, results):
-        one = results["while"]
-        one.replace(Name("True", prefix=one.prefix))
-
-    def transform_sort(self, node, results):
-        sort_stmt = results["sort"]
-        next_stmt = results["next"]
-        list_call = results.get("list")
-        simple_expr = results.get("expr")
-
-        if list_call:
-            list_call.replace(Name("sorted", prefix=list_call.prefix))
-        elif simple_expr:
-            new = simple_expr.clone()
-            new.prefix = ""
-            simple_expr.replace(Call(Name("sorted"), [new],
-                                     prefix=simple_expr.prefix))
-        else:
-            raise RuntimeError("should not have reached here")
-        sort_stmt.remove()
-        if next_stmt:
-            next_stmt[0].prefix = sort_stmt._prefix
diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py
--- a/distutils2/tests/support.py
+++ b/distutils2/tests/support.py
@@ -62,8 +62,9 @@
     # misc. functions and decorators
     'fake_dec', 'create_distribution', 'use_command',
     'copy_xxmodule_c', 'fixup_build_ext',
+    'skip_2to3_optimize',
     # imported from this module for backport purposes
-    'unittest', 'requires_zlib', 'skip_2to3_optimize', 'skip_unless_symlink',
+    'unittest', 'requires_zlib', 'skip_unless_symlink',
 ]
 
 
@@ -361,16 +362,13 @@
     need their debug attribute set, and it is not done automatically for
     some reason.
 
-    This function handles both of these things.  Example use:
+    This function handles both of these things, and also fixes
+    cmd.distribution.include_dirs if the running Python is an uninstalled
+    build.  Example use:
 
         cmd = build_ext(dist)
         support.fixup_build_ext(cmd)
         cmd.ensure_finalized()
-
-    In addition, this function also fixes cmd.distribution.include_dirs if
-    the running Python is an uninstalled Python 3.3.  (This fix is not done in
-    packaging, which does not need it, nor in distutils2 for Python 2, which
-    has no in-development version that can't be expected to be installed.)
     """
     if os.name == 'nt':
         cmd.debug = sys.executable.endswith('_d.exe')
@@ -389,8 +387,8 @@
                 name, equals, value = runshared.partition('=')
                 cmd.library_dirs = value.split(os.pathsep)
 
-    # Allow tests to run with an uninstalled Python 3.3
-    if sys.version_info[:2] == (3, 3) and sysconfig.is_python_build():
+    # Allow tests to run with an uninstalled Python
+    if sysconfig.is_python_build():
         pysrcdir = sysconfig.get_config_var('projectbase')
         cmd.distribution.include_dirs.append(os.path.join(pysrcdir, 'Include'))
 
@@ -401,11 +399,9 @@
     skip_unless_symlink = unittest.skip(
         'requires test.support.skip_unless_symlink')
 
-
 skip_2to3_optimize = unittest.skipIf(sys.flags.optimize,
                                      "2to3 doesn't work under -O")
 
-
 requires_zlib = unittest.skipUnless(zlib, 'requires zlib')
 
 
diff --git a/distutils2/tests/test_command_bdist_dumb.py b/distutils2/tests/test_command_bdist_dumb.py
--- a/distutils2/tests/test_command_bdist_dumb.py
+++ b/distutils2/tests/test_command_bdist_dumb.py
@@ -65,7 +65,7 @@
         finally:
             fp.close
 
-        if sys.version_info[1] == 1:
+        if sys.version_info[:2] == (3, 1):
             pyc = 'foo.pyc'
         else:
             pyc = 'foo.%s.pyc' % imp.get_tag()
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
@@ -26,7 +26,8 @@
         # build_platlib is 'build/lib.platform-x.x[-pydebug]'
         # examples:
         #   build/lib.macosx-10.3-i386-2.7
-        plat_spec = '.%s-%s' % (cmd.plat_name, sys.version[0:3])
+        pyversion = '%s.%s' % sys.version_info[:2]
+        plat_spec = '.%s-%s' % (cmd.plat_name, pyversion)
         if hasattr(sys, 'gettotalrefcount'):
             self.assertTrue(cmd.build_platlib.endswith('-pydebug'))
             plat_spec += '-pydebug'
@@ -41,7 +42,7 @@
         self.assertEqual(cmd.build_temp, wanted)
 
         # build_scripts is build/scripts-x.x
-        wanted = os.path.join(cmd.build_base, 'scripts-' + sys.version[0:3])
+        wanted = os.path.join(cmd.build_base, 'scripts-' + pyversion)
         self.assertEqual(cmd.build_scripts, wanted)
 
         # executable is os.path.normpath(sys.executable)
diff --git a/distutils2/tests/test_command_build_py.py b/distutils2/tests/test_command_build_py.py
--- a/distutils2/tests/test_command_build_py.py
+++ b/distutils2/tests/test_command_build_py.py
@@ -69,12 +69,12 @@
         pkgdest = os.path.join(destination, "pkg")
         files = os.listdir(pkgdest)
         wanted = ["__init__.py", "HACKING.txt", "README.txt"]
-        if sys.version_info[1] == 1:
+        if sys.version_info[:2] == (3, 1):
             wanted.append("__init__.pyc")
         else:
             wanted.append("__pycache__")
         self.assertEqual(sorted(files), sorted(wanted))
-        if sys.version_info[1] >= 2:
+        if sys.version_info[:2] >= (3, 2):
             pycache_dir = os.path.join(pkgdest, "__pycache__")
             pyc_files = os.listdir(pycache_dir)
             self.assertEqual(["__init__.%s.pyc" % imp.get_tag()], pyc_files)
@@ -113,7 +113,7 @@
         cmd.run()
 
         found = os.listdir(cmd.build_lib)
-        if sys.version_info[1] == 1:
+        if sys.version_info[:2] == (3, 1):
             self.assertEqual(sorted(found),
                              ['boiledeggs.py', 'boiledeggs.pyc'])
         else:
@@ -133,7 +133,7 @@
         cmd.run()
 
         found = os.listdir(cmd.build_lib)
-        if sys.version_info[1] == 1:
+        if sys.version_info[:2] == (3, 1):
             self.assertEqual(sorted(found), ['boiledeggs.py', 'boiledeggs.pyc',
                                              'boiledeggs.pyo'])
         else:
diff --git a/distutils2/tests/test_command_install_dist.py b/distutils2/tests/test_command_install_dist.py
--- a/distutils2/tests/test_command_install_dist.py
+++ b/distutils2/tests/test_command_install_dist.py
@@ -197,7 +197,7 @@
         with open(cmd.record) as f:
             content = f.read()
 
-        if sys.version_info[1] == 1:
+        if sys.version_info[:2] == (3, 1):
             pyc = 'hello.pyc'
         else:
             pyc = 'hello.%s.pyc' % imp.get_tag()
diff --git a/distutils2/tests/test_command_install_lib.py b/distutils2/tests/test_command_install_lib.py
--- a/distutils2/tests/test_command_install_lib.py
+++ b/distutils2/tests/test_command_install_lib.py
@@ -44,7 +44,7 @@
         f = os.path.join(project_dir, 'foo.py')
         self.write_file(f, '# python file')
         cmd.byte_compile([f])
-        if sys.version_info[1] == 1:
+        if sys.version_info[:2] == (3, 1):
             pyc_file = 'foo.pyc'
             pyo_file = 'foo.pyo'
         else:
diff --git a/distutils2/tests/test_markers.py b/distutils2/tests/test_markers.py
--- a/distutils2/tests/test_markers.py
+++ b/distutils2/tests/test_markers.py
@@ -21,8 +21,6 @@
 
         self.assertTrue(interpret("sys.platform == '%s'" % sys_platform))
         self.assertTrue(interpret(
-            "sys.platform == '%s' or python_version == '2.4'" % sys_platform))
-        self.assertTrue(interpret(
             "sys.platform == '%s' and python_full_version == '%s'" %
             (sys_platform, version)))
         self.assertTrue(interpret("'%s' == sys.platform" % sys_platform))
@@ -41,12 +39,18 @@
 
         # combined operations
         OP = 'os.name == "%s"' % os_name
+        FALSEOP = 'os.name == "buuuu"'
         AND = ' and '
         OR = ' or '
         self.assertTrue(interpret(OP + AND + OP))
         self.assertTrue(interpret(OP + AND + OP + AND + OP))
         self.assertTrue(interpret(OP + OR + OP))
-        self.assertTrue(interpret(OP + OR + OP + OR + OP))
+        self.assertTrue(interpret(OP + OR + FALSEOP))
+        self.assertTrue(interpret(OP + OR + OP + OR + FALSEOP))
+        self.assertTrue(interpret(OP + OR + FALSEOP + OR + FALSEOP))
+        self.assertTrue(interpret(FALSEOP + OR + OP))
+        self.assertFalse(interpret(FALSEOP + AND + FALSEOP))
+        self.assertFalse(interpret(FALSEOP + OR + FALSEOP))
 
         # other operators
         self.assertTrue(interpret("os.name != 'buuuu'"))
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
@@ -8,70 +8,76 @@
                         support.LoggingCatcher,
                         unittest.TestCase):
 
-    @support.skip_2to3_optimize
-    def test_convert_code_only(self):
-        # used to check if code gets converted properly.
-        code = "print 'test'"
+    def setUp(self):
+        super(Mixin2to3TestCase, self).setUp()
+        self.filename = self.mktempfile().name
 
-        with self.mktempfile() as fp:
-            fp.write(code)
+    def check(self, source, wanted, **kwargs):
+        source = textwrap.dedent(source)
+        with open(self.filename, 'w') as fp:
+            fp.write(source)
 
-        mixin2to3 = Mixin2to3()
-        mixin2to3._run_2to3([fp.name])
-        expected = "print('test')"
+        Mixin2to3()._run_2to3(**kwargs)
 
-        with open(fp.name) as fp:
+        wanted = textwrap.dedent(wanted)
+        with open(self.filename) as fp:
             converted = fp.read()
+        self.assertMultiLineEqual(converted, wanted)
 
-        self.assertEqual(expected, converted)
-
-    def test_doctests_only(self):
-        # used to check if doctests gets converted properly.
-        doctest = textwrap.dedent('''\
+    def test_conversion(self):
+        # check that code and doctests get converted
+        self.check('''\
             """Example docstring.
 
             >>> print test
             test
 
             It works.
-            """''')
-
-        with self.mktempfile() as fp:
-            fp.write(doctest)
-
-        mixin2to3 = Mixin2to3()
-        mixin2to3._run_2to3([fp.name])
-        expected = textwrap.dedent('''\
+            """
+            print 'test'
+            ''',
+            '''\
             """Example docstring.
 
             >>> print(test)
             test
 
             It works.
-            """\n''')
+            """
+            print('test')
 
-        with open(fp.name) as fp:
-            converted = fp.read()
+            ''',  # 2to3 adds a newline here
+            files=[self.filename])
 
-        self.assertEqual(expected, converted)
+    def test_doctests_conversion(self):
+        # check that doctest files are converted
+        self.check('''\
+            Welcome to the doc.
+
+            >>> print test
+            test
+            ''',
+            '''\
+            Welcome to the doc.
+
+            >>> print(test)
+            test
+
+            ''',
+            doctests=[self.filename])
 
     def test_additional_fixers(self):
-        # used to check if use_2to3_fixers works
-        code = 'type(x) is not T'
-
-        with self.mktempfile() as fp:
-            fp.write(code)
-
-        mixin2to3 = Mixin2to3()
-        mixin2to3._run_2to3(files=[fp.name], doctests=[fp.name],
-                            fixers=['distutils2.tests.fixer'])
-
-        expected = 'not isinstance(x, T)'
-
-        with open(fp.name) as fp:
-            converted = fp.read()
-
-        self.assertEqual(expected, converted)
+        # make sure the fixers argument works
+        self.check("""\
+            echo('42')
+            echo2('oh no')
+            """,
+            """\
+            print('42')
+            print('oh no')
+            """,
+            files=[self.filename],
+            fixers=['distutils2.tests.fixer'])
 
 
 def test_suite():
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
@@ -87,7 +87,7 @@
         try:
             crawler._open_url(url)
         except Exception as v:
-            if sys.version_info[:2] < (3, 2, 3):
+            if sys.version_info[:3] < (3, 2, 3):  # XXX check versions again
                 wanted = 'nonnumeric port'
             else:
                 wanted = 'Download error'
diff --git a/distutils2/tests/test_run.py b/distutils2/tests/test_run.py
--- a/distutils2/tests/test_run.py
+++ b/distutils2/tests/test_run.py
@@ -60,21 +60,42 @@
             os.chmod(install_path, old_mod)
             install.get_path = old_get_path
 
-    def test_show_help(self):
-        # smoke test, just makes sure some help is displayed
+    def get_pythonpath(self):
         pythonpath = os.environ.get('PYTHONPATH')
         d2parent = os.path.dirname(os.path.dirname(__file__))
         if pythonpath is not None:
             pythonpath = os.pathsep.join((pythonpath, d2parent))
         else:
             pythonpath = d2parent
+        return pythonpath
 
-        status, out, err = assert_python_ok('-m', 'distutils2.run', '--help',
-                                            PYTHONPATH=pythonpath)
+    def test_show_help(self):
+        # smoke test, just makes sure some help is displayed
+        status, out, err = assert_python_ok(
+            '-m', 'distutils2.run', '--help',
+            PYTHONPATH=self.get_pythonpath())
         self.assertEqual(status, 0)
         self.assertGreater(out, b'')
         self.assertEqual(err, b'')
 
+    def test_list_commands(self):
+        status, out, err = assert_python_ok(
+            '-m', 'distutils2.run', 'run',
+            '--list-commands', PYTHONPATH=self.get_pythonpath())
+        # check that something is displayed
+        self.assertEqual(status, 0)
+        self.assertGreater(out, b'')
+        self.assertEqual(err, b'')
+
+        # make sure the manual grouping of commands is respected
+        check_position = out.find(b'  check: ')
+        build_position = out.find(b'  build: ')
+        self.assertTrue(check_position, out)  # "out" printed as debugging aid
+        self.assertTrue(build_position, out)
+        self.assertLess(check_position, build_position, out)
+
+        # TODO test that custom commands don't break --list-commands
+
 
 def test_suite():
     return unittest.makeSuite(RunTestCase)
diff --git a/distutils2/util.py b/distutils2/util.py
--- a/distutils2/util.py
+++ b/distutils2/util.py
@@ -853,13 +853,11 @@
 
     # Make this class local, to delay import of 2to3
     from lib2to3.refactor import get_fixers_from_package, RefactoringTool
-    fixers = []
     fixers = get_fixers_from_package('lib2to3.fixes')
 
     if fixer_names:
         for fixername in fixer_names:
-            fixers.extend(fixer for fixer in
-                          get_fixers_from_package(fixername))
+            fixers.extend(get_fixers_from_package(fixername))
     r = RefactoringTool(fixers, options=options)
     r.refactor(files, write=True, doctests_only=doctests_only)
 
@@ -870,21 +868,23 @@
     the class variables, or inherit from this class
     to override how 2to3 is invoked.
     """
-    # provide list of fixers to run.
-    # defaults to all from lib2to3.fixers
+    # list of fixers to run; defaults to all implicit from lib2to3.fixers
     fixer_names = None
-
-    # options dictionary
+    # dict of options
     options = None
-
-    # list of fixers to invoke even though they are marked as explicit
+    # list of extra fixers to invoke
     explicit = None
+    # TODO need a better way to add just one fixer from a package
+    # TODO need a way to exclude individual fixers
 
     def run_2to3(self, files, doctests_only=False):
         """ Issues a call to util.run_2to3. """
         return run_2to3(files, doctests_only, self.fixer_names,
                         self.options, self.explicit)
 
+    # TODO provide initialize/finalize_options
+
+
 RICH_GLOB = re.compile(r'\{([^}]*)\}')
 _CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]')
 _CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$')

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


More information about the Python-checkins mailing list