[Python-checkins] distutils2: Merge upstream. Fixing conflicts in util.py

tarek.ziade python-checkins at python.org
Sun Aug 8 11:50:47 CEST 2010


tarek.ziade pushed 2042fc40d324 to distutils2:

http://hg.python.org/distutils2/rev/2042fc40d324
changeset:   472:2042fc40d324
parent:      471:06cb3de6c55a
parent:      387:ba37b166e4f9
user:        Alexis Metaireau <ametaireau at gmail.com>
date:        Thu Jul 29 19:33:05 2010 +0200
summary:     Merge upstream. Fixing conflicts in util.py
files:       src/distutils2/config.py, src/distutils2/spawn.py, src/distutils2/tests/test_config.py, src/distutils2/tests/test_spawn.py, src/distutils2/util.py

diff --git a/src/check.sh b/src/check.sh
new file mode 100755
--- /dev/null
+++ b/src/check.sh
@@ -0,0 +1,2 @@
+pep8 distutils2
+pyflakes distutils2
diff --git a/src/distutils2/command/cmd.py b/src/distutils2/command/cmd.py
--- a/src/distutils2/command/cmd.py
+++ b/src/distutils2/command/cmd.py
@@ -411,7 +411,7 @@
 
     def spawn(self, cmd, search_path=1, level=1):
         """Spawn an external command respecting dry-run flag."""
-        from distutils2.spawn import spawn
+        from distutils2.util import spawn
         spawn(cmd, search_path, dry_run= self.dry_run)
 
     def make_archive(self, base_name, format, root_dir=None, base_dir=None,
diff --git a/src/distutils2/command/register.py b/src/distutils2/command/register.py
--- a/src/distutils2/command/register.py
+++ b/src/distutils2/command/register.py
@@ -13,28 +13,40 @@
 import StringIO
 from warnings import warn
 
-from distutils2.core import PyPIRCCommand
+from distutils2.command.cmd import Command
 from distutils2 import log
+from distutils2.util import (metadata_to_dict, read_pypirc, generate_pypirc,
+                             DEFAULT_REPOSITORY, DEFAULT_REALM,
+                             get_pypirc_path)
 
-class register(PyPIRCCommand):
+class register(Command):
 
     description = ("register the distribution with the Python package index")
-    user_options = PyPIRCCommand.user_options + [
+    user_options = [('repository=', 'r',
+         "url of repository [default: %s]" % DEFAULT_REPOSITORY),
+        ('show-response', None,
+         'display full response text from server'),
         ('list-classifiers', None,
          'list the valid Trove classifiers'),
         ('strict', None ,
          'Will stop the registering if the meta-data are not fully compliant')
         ]
-    boolean_options = PyPIRCCommand.boolean_options + [
-        'verify', 'list-classifiers', 'strict']
+
+    boolean_options = ['show-response', 'verify', 'list-classifiers',
+                       'strict']
 
     def initialize_options(self):
-        PyPIRCCommand.initialize_options(self)
+        self.repository = None
+        self.realm = None
+        self.show_response = 0
         self.list_classifiers = 0
         self.strict = 0
 
     def finalize_options(self):
-        PyPIRCCommand.finalize_options(self)
+        if self.repository is None:
+            self.repository = DEFAULT_REPOSITORY
+        if self.realm is None:
+            self.realm = DEFAULT_REALM
         # setting options for the `check` subcommand
         check_options = {'strict': ('register', self.strict),
                          'restructuredtext': ('register', 1)}
@@ -67,7 +79,7 @@
     def _set_config(self):
         ''' Reads the configuration file and set attributes.
         '''
-        config = self._read_pypirc()
+        config = read_pypirc(self.repository, self.realm)
         if config != {}:
             self.username = config['username']
             self.password = config['password']
@@ -75,10 +87,10 @@
             self.realm = config['realm']
             self.has_config = True
         else:
-            if self.repository not in ('pypi', self.DEFAULT_REPOSITORY):
+            if self.repository not in ('pypi', DEFAULT_REPOSITORY):
                 raise ValueError('%s not found in .pypirc' % self.repository)
             if self.repository == 'pypi':
-                self.repository = self.DEFAULT_REPOSITORY
+                self.repository = DEFAULT_REPOSITORY
             self.has_config = False
 
     def classifiers(self):
@@ -177,14 +189,14 @@
                     self.announce(('I can store your PyPI login so future '
                                    'submissions will be faster.'), log.INFO)
                     self.announce('(the login will be stored in %s)' % \
-                                  self._get_rc_file(), log.INFO)
+                                  get_pypirc_path(), log.INFO)
                     choice = 'X'
                     while choice.lower() not in 'yn':
                         choice = raw_input('Save your login (y/N)?')
                         if not choice:
                             choice = 'n'
                     if choice.lower() == 'y':
-                        self._store_pypirc(username, password)
+                        generate_pypirc(username, password)
 
         elif choice == '2':
             data = {':action': 'user'}
@@ -221,7 +233,7 @@
     def build_post_data(self, action):
         # figure the data to send - the metadata plus some additional
         # information used by the package server
-        data = self._metadata_to_pypy_dict()
+        data = metadata_to_dict(self.distribution.metadata)
         data[':action'] = action
         return data
 
diff --git a/src/distutils2/command/upload.py b/src/distutils2/command/upload.py
--- a/src/distutils2/command/upload.py
+++ b/src/distutils2/command/upload.py
@@ -14,24 +14,34 @@
     from md5 import md5
 
 from distutils2.errors import DistutilsOptionError
-from distutils2.core import PyPIRCCommand
-from distutils2.spawn import spawn
+from distutils2.util import spawn
 from distutils2 import log
+from distutils2.command.cmd import Command
+from distutils2 import log
+from distutils2.util import (metadata_to_dict, read_pypirc,
+                             DEFAULT_REPOSITORY, DEFAULT_REALM)
 
-class upload(PyPIRCCommand):
+
+class upload(Command):
 
     description = "upload binary package to PyPI"
 
-    user_options = PyPIRCCommand.user_options + [
+    user_options = [('repository=', 'r',
+         "url of repository [default: %s]" % \
+            DEFAULT_REPOSITORY),
+        ('show-response', None,
+         'display full response text from server'),
         ('sign', 's',
          'sign files to upload using gpg'),
         ('identity=', 'i', 'GPG identity used to sign files'),
         ]
 
-    boolean_options = PyPIRCCommand.boolean_options + ['sign']
+    boolean_options = ['show-response', 'sign']
 
     def initialize_options(self):
-        PyPIRCCommand.initialize_options(self)
+        self.repository = None
+        self.realm = None
+        self.show_response = 0
         self.username = ''
         self.password = ''
         self.show_response = 0
@@ -39,12 +49,15 @@
         self.identity = None
 
     def finalize_options(self):
-        PyPIRCCommand.finalize_options(self)
+        if self.repository is None:
+            self.repository = DEFAULT_REPOSITORY
+        if self.realm is None:
+            self.realm = DEFAULT_REALM
         if self.identity and not self.sign:
             raise DistutilsOptionError(
                 "Must use --sign for --identity to have meaning"
             )
-        config = self._read_pypirc()
+        config = read_pypirc(self.repository, self.realm)
         if config != {}:
             self.username = config['username']
             self.password = config['password']
@@ -85,7 +98,7 @@
         # register a new release
         content = open(filename,'rb').read()
 
-        data = self._metadata_to_pypy_dict()
+        data = metadata_to_dict(self.distribution.metadata)
 
         # extra upload infos
         data[':action'] = 'file_upload'
diff --git a/src/distutils2/command/upload_docs.py b/src/distutils2/command/upload_docs.py
--- a/src/distutils2/command/upload_docs.py
+++ b/src/distutils2/command/upload_docs.py
@@ -1,9 +1,11 @@
 import base64, httplib, os.path, socket, urlparse, zipfile
 from cStringIO import StringIO
+
 from distutils2 import log
 from distutils2.command.upload import upload
-from distutils2.core import PyPIRCCommand
+from distutils2.command.cmd import Command
 from distutils2.errors import DistutilsFileError
+from distutils2.util import read_pypirc, DEFAULT_REPOSITORY, DEFAULT_REALM
 
 def zip_dir(directory):
     """Compresses recursively contents of directory into a StringIO object"""
@@ -47,26 +49,33 @@
     content_type = 'multipart/form-data; boundary=%s' % boundary
     return content_type, body
 
-class upload_docs(PyPIRCCommand):
+class upload_docs(Command):
 
     user_options = [
-        ('repository=', 'r', "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY),
+        ('repository=', 'r', "url of repository [default: %s]" % DEFAULT_REPOSITORY),
         ('show-response', None, 'display full response text from server'),
         ('upload-dir=', None, 'directory to upload'),
         ]
 
     def initialize_options(self):
-        PyPIRCCommand.initialize_options(self)
+        self.repository = None
+        self.realm = None
+        self.show_response = 0
         self.upload_dir = "build/docs"
+        self.username = ''
+        self.password = ''
 
     def finalize_options(self):
-        PyPIRCCommand.finalize_options(self)
+        if self.repository is None:
+            self.repository = DEFAULT_REPOSITORY
+        if self.realm is None:
+            self.realm = DEFAULT_REALM
         if self.upload_dir == None:
             build = self.get_finalized_command('build')
             self.upload_dir = os.path.join(build.build_base, "docs")
         self.announce('Using upload directory %s' % self.upload_dir)
         self.verify_upload_dir(self.upload_dir)
-        config = self._read_pypirc()
+        config = read_pypirc(self.repository, self.realm)
         if config != {}:
             self.username = config['username']
             self.password = config['password']
diff --git a/src/distutils2/compiler/ccompiler.py b/src/distutils2/compiler/ccompiler.py
--- a/src/distutils2/compiler/ccompiler.py
+++ b/src/distutils2/compiler/ccompiler.py
@@ -11,8 +11,7 @@
 
 from distutils2.errors import (CompileError, LinkError, UnknownFileError,
                                DistutilsPlatformError, DistutilsModuleError)
-from distutils2.spawn import spawn
-from distutils2.util import split_quoted, execute, newer_group
+from distutils2.util import split_quoted, execute, newer_group, spawn
 from distutils2 import log
 from shutil import move
 
diff --git a/src/distutils2/config.py b/src/distutils2/config.py
deleted file mode 100644
--- a/src/distutils2/config.py
+++ /dev/null
@@ -1,155 +0,0 @@
-"""distutils.pypirc
-
-Provides the PyPIRCCommand class, the base class for the command classes
-that uses .pypirc in the distutils.command package.
-"""
-import os
-from ConfigParser import RawConfigParser
-
-from distutils2.command.cmd import Command
-
-DEFAULT_PYPIRC = """\
-[distutils]
-index-servers =
-    pypi
-
-[pypi]
-username:%s
-password:%s
-"""
-
-class PyPIRCCommand(Command):
-    """Base command that knows how to handle the .pypirc file
-    """
-    DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
-    DEFAULT_REALM = 'pypi'
-    repository = None
-    realm = None
-
-    user_options = [
-        ('repository=', 'r',
-         "url of repository [default: %s]" % \
-            DEFAULT_REPOSITORY),
-        ('show-response', None,
-         'display full response text from server')]
-
-    boolean_options = ['show-response']
-
-    def _get_rc_file(self):
-        """Returns rc file path."""
-        return os.path.join(os.path.expanduser('~'), '.pypirc')
-
-    def _store_pypirc(self, username, password):
-        """Creates a default .pypirc file."""
-        rc = self._get_rc_file()
-        f = open(rc, 'w')
-        try:
-            f.write(DEFAULT_PYPIRC % (username, password))
-        finally:
-            f.close()
-        try:
-            os.chmod(rc, 0600)
-        except OSError:
-            # should do something better here
-            pass
-
-    def _read_pypirc(self):
-        """Reads the .pypirc file."""
-        rc = self._get_rc_file()
-        if os.path.exists(rc):
-            self.announce('Using PyPI login from %s' % rc)
-            repository = self.repository or self.DEFAULT_REPOSITORY
-            config = RawConfigParser()
-            config.read(rc)
-            sections = config.sections()
-            if 'distutils' in sections:
-                # let's get the list of servers
-                index_servers = config.get('distutils', 'index-servers')
-                _servers = [server.strip() for server in
-                            index_servers.split('\n')
-                            if server.strip() != '']
-                if _servers == []:
-                    # nothing set, let's try to get the default pypi
-                    if 'pypi' in sections:
-                        _servers = ['pypi']
-                    else:
-                        # the file is not properly defined, returning
-                        # an empty dict
-                        return {}
-                for server in _servers:
-                    current = {'server': server}
-                    current['username'] = config.get(server, 'username')
-
-                    # optional params
-                    for key, default in (('repository',
-                                          self.DEFAULT_REPOSITORY),
-                                         ('realm', self.DEFAULT_REALM),
-                                         ('password', None)):
-                        if config.has_option(server, key):
-                            current[key] = config.get(server, key)
-                        else:
-                            current[key] = default
-                    if (current['server'] == repository or
-                        current['repository'] == repository):
-                        return current
-            elif 'server-login' in sections:
-                # old format
-                server = 'server-login'
-                if config.has_option(server, 'repository'):
-                    repository = config.get(server, 'repository')
-                else:
-                    repository = self.DEFAULT_REPOSITORY
-                return {'username': config.get(server, 'username'),
-                        'password': config.get(server, 'password'),
-                        'repository': repository,
-                        'server': server,
-                        'realm': self.DEFAULT_REALM}
-
-        return {}
-
-    def _metadata_to_pypy_dict(self):
-        meta = self.distribution.metadata
-        data = {
-            'metadata_version' : meta.version,
-            'name': meta['Name'],
-            'version': meta['Version'],
-            'summary': meta['Summary'],
-            'home_page': meta['Home-page'],
-            'author': meta['Author'],
-            'author_email': meta['Author-email'],
-            'license': meta['License'],
-            'description': meta['Description'],
-            'keywords': meta['Keywords'],
-            'platform': meta['Platform'],
-            'classifier': meta['Classifier'],
-            'download_url': meta['Download-URL'],
-        }
-
-        if meta.version == '1.2':
-            data['requires_dist'] = meta['Requires-Dist']
-            data['requires_python'] = meta['Requires-Python']
-            data['requires_external'] = meta['Requires-External']
-            data['provides_dist'] = meta['Provides-Dist']
-            data['obsoletes_dist'] = meta['Obsoletes-Dist']
-            data['project_url'] = [','.join(url) for url in
-                                   meta['Project-URL']]
-
-        elif meta.version == '1.1':
-            data['provides'] = meta['Provides']
-            data['requires'] = meta['Requires']
-            data['obsoletes'] = meta['Obsoletes']
-
-        return data
-
-    def initialize_options(self):
-        """Initialize options."""
-        self.repository = None
-        self.realm = None
-        self.show_response = 0
-
-    def finalize_options(self):
-        """Finalizes options."""
-        if self.repository is None:
-            self.repository = self.DEFAULT_REPOSITORY
-        if self.realm is None:
-            self.realm = self.DEFAULT_REALM
diff --git a/src/distutils2/core.py b/src/distutils2/core.py
--- a/src/distutils2/core.py
+++ b/src/distutils2/core.py
@@ -19,7 +19,6 @@
 # Mainly import these so setup scripts can "from distutils2.core import" them.
 from distutils2.dist import Distribution
 from distutils2.command.cmd import Command
-from distutils2.config import PyPIRCCommand
 from distutils2.extension import Extension
 from distutils2.util import find_packages
 
diff --git a/src/distutils2/spawn.py b/src/distutils2/spawn.py
deleted file mode 100644
--- a/src/distutils2/spawn.py
+++ /dev/null
@@ -1,192 +0,0 @@
-"""distutils.spawn
-
-Provides the 'spawn()' function, a front-end to various platform-
-specific functions for launching another program in a sub-process.
-Also provides the 'find_executable()' to search the path for a given
-executable name.
-"""
-
-__revision__ = "$Id: spawn.py 73147 2009-06-02 15:58:43Z tarek.ziade $"
-
-import sys
-import os
-
-from distutils2.errors import DistutilsPlatformError, DistutilsExecError
-from distutils2 import log
-
-def spawn(cmd, search_path=1, verbose=0, dry_run=0, 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.
-    cmd[0] is the program to run and cmd[1:] are the rest of its arguments.
-    There is no way to run a program with a name different from that of its
-    executable.
-
-    If 'search_path' is true (the default), the system's executable
-    search path will be used to find the program; otherwise, cmd[0]
-    must be the exact path to the executable.  If 'dry_run' is true,
-    the command will not actually be run.
-
-    If 'env' is given, it's a environment dictionary used for the execution
-    environment.
-
-    Raise DistutilsExecError if running the program fails in any way; just
-    return on success.
-    """
-    if os.name == 'posix':
-        _spawn_posix(cmd, search_path, dry_run=dry_run, env=env)
-    elif os.name == 'nt':
-        _spawn_nt(cmd, search_path, dry_run=dry_run, env=env)
-    elif os.name == 'os2':
-        _spawn_os2(cmd, search_path, dry_run=dry_run, env=env)
-    else:
-        raise DistutilsPlatformError, \
-              "don't know how to spawn programs on platform '%s'" % os.name
-
-def _nt_quote_args(args):
-    """Quote command-line arguments for DOS/Windows conventions.
-
-    Just wraps every argument which contains blanks in double quotes, and
-    returns a new argument list.
-    """
-    # XXX this doesn't seem very robust to me -- but if the Windows guys
-    # say it'll work, I guess I'll have to accept it.  (What if an arg
-    # contains quotes?  What other magic characters, other than spaces,
-    # have to be escaped?  Is there an escaping mechanism other than
-    # quoting?)
-    for i, arg in enumerate(args):
-        if ' ' in arg:
-            args[i] = '"%s"' % arg
-    return args
-
-def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0, env=None):
-    executable = cmd[0]
-    cmd = _nt_quote_args(cmd)
-    if search_path:
-        # either we find one or it stays the same
-        executable = find_executable(executable) or executable
-    log.info(' '.join([executable] + cmd[1:]))
-    if not dry_run:
-        # spawn for NT requires a full path to the .exe
-        try:
-            if env is None:
-                rc = os.spawnv(os.P_WAIT, executable, cmd)
-            else:
-                rc = os.spawnve(os.P_WAIT, executable, cmd, env)
-
-        except OSError, exc:
-            # this seems to happen when the command isn't found
-            raise DistutilsExecError, \
-                  "command '%s' failed: %s" % (cmd[0], exc[-1])
-        if rc != 0:
-            # and this reflects the command running but failing
-            raise DistutilsExecError, \
-                  "command '%s' failed with exit status %d" % (cmd[0], rc)
-
-def _spawn_os2(cmd, search_path=1, verbose=0, dry_run=0, env=None):
-    executable = cmd[0]
-    if search_path:
-        # either we find one or it stays the same
-        executable = find_executable(executable) or executable
-    log.info(' '.join([executable] + cmd[1:]))
-    if not dry_run:
-        # spawnv for OS/2 EMX requires a full path to the .exe
-        try:
-            if env is None:
-                rc = os.spawnv(os.P_WAIT, executable, cmd)
-            else:
-                rc = os.spawnve(os.P_WAIT, executable, cmd, env)
-
-        except OSError, exc:
-            # this seems to happen when the command isn't found
-            raise DistutilsExecError, \
-                  "command '%s' failed: %s" % (cmd[0], exc[-1])
-        if rc != 0:
-            # and this reflects the command running but failing
-            log.debug("command '%s' failed with exit status %d" % (cmd[0], rc))
-            raise DistutilsExecError, \
-                  "command '%s' failed with exit status %d" % (cmd[0], rc)
-
-
-def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0, env=None):
-    log.info(' '.join(cmd))
-    if dry_run:
-        return
-
-    if env is None:
-        exec_fn = search_path and os.execvp or os.execv
-    else:
-        exec_fn = search_path and os.execvpe or os.execve
-
-    pid = os.fork()
-
-    if pid == 0:  # in the child
-        try:
-            if env is None:
-                exec_fn(cmd[0], cmd)
-            else:
-                exec_fn(cmd[0], cmd, env)
-        except OSError, e:
-            sys.stderr.write("unable to execute %s: %s\n" %
-                             (cmd[0], e.strerror))
-            os._exit(1)
-
-        sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0])
-        os._exit(1)
-    else:   # in the parent
-        # Loop until the child either exits or is terminated by a signal
-        # (ie. keep waiting if it's merely stopped)
-        while 1:
-            try:
-                pid, status = os.waitpid(pid, 0)
-            except OSError, exc:
-                import errno
-                if exc.errno == errno.EINTR:
-                    continue
-                raise DistutilsExecError, \
-                      "command '%s' failed: %s" % (cmd[0], exc[-1])
-            if os.WIFSIGNALED(status):
-                raise DistutilsExecError, \
-                      "command '%s' terminated by signal %d" % \
-                      (cmd[0], os.WTERMSIG(status))
-
-            elif os.WIFEXITED(status):
-                exit_status = os.WEXITSTATUS(status)
-                if exit_status == 0:
-                    return   # hey, it succeeded!
-                else:
-                    raise DistutilsExecError, \
-                          "command '%s' failed with exit status %d" % \
-                          (cmd[0], exit_status)
-
-            elif os.WIFSTOPPED(status):
-                continue
-
-            else:
-                raise DistutilsExecError, \
-                      "unknown error executing '%s': termination status %d" % \
-                      (cmd[0], status)
-
-def find_executable(executable, path=None):
-    """Tries to find 'executable' in the directories listed in 'path'.
-
-    A string listing directories separated by 'os.pathsep'; defaults to
-    os.environ['PATH'].  Returns the complete filename or None if not found.
-    """
-    if path is None:
-        path = os.environ['PATH']
-    paths = path.split(os.pathsep)
-    base, ext = os.path.splitext(executable)
-
-    if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):
-        executable = executable + '.exe'
-
-    if not os.path.isfile(executable):
-        for p in paths:
-            f = os.path.join(p, executable)
-            if os.path.isfile(f):
-                # the file exists, we have a shot at spawn working
-                return f
-        return None
-    else:
-        return executable
diff --git a/src/distutils2/tests/test_bdist.py b/src/distutils2/tests/test_bdist.py
--- a/src/distutils2/tests/test_bdist.py
+++ b/src/distutils2/tests/test_bdist.py
@@ -8,8 +8,7 @@
 from distutils2.command.bdist import bdist
 from distutils2.tests import support
 from distutils2.tests.support import unittest
-from distutils2.spawn import find_executable
-from distutils2 import spawn
+from distutils2.util import find_executable
 from distutils2.errors import DistutilsExecError
 
 class BuildTestCase(support.TempdirManager,
diff --git a/src/distutils2/tests/test_build_clib.py b/src/distutils2/tests/test_build_clib.py
--- a/src/distutils2/tests/test_build_clib.py
+++ b/src/distutils2/tests/test_build_clib.py
@@ -5,7 +5,7 @@
 from distutils2.command.build_clib import build_clib
 from distutils2.errors import DistutilsSetupError
 from distutils2.tests import support
-from distutils2.spawn import find_executable
+from distutils2.util import find_executable
 from distutils2.tests.support import unittest
 
 class BuildCLibTestCase(support.TempdirManager,
diff --git a/src/distutils2/tests/test_config.py b/src/distutils2/tests/test_config.py
deleted file mode 100644
--- a/src/distutils2/tests/test_config.py
+++ /dev/null
@@ -1,117 +0,0 @@
-"""Tests for distutils.pypirc.pypirc."""
-import sys
-import os
-import shutil
-
-from distutils2.core import PyPIRCCommand
-from distutils2.core import Distribution
-from distutils2.log import set_threshold
-from distutils2.log import WARN
-
-from distutils2.tests import support
-from distutils2.tests.support import unittest
-
-PYPIRC = """\
-[distutils]
-
-index-servers =
-    server1
-    server2
-
-[server1]
-username:me
-password:secret
-
-[server2]
-username:meagain
-password: secret
-realm:acme
-repository:http://another.pypi/
-"""
-
-PYPIRC_OLD = """\
-[server-login]
-username:tarek
-password:secret
-"""
-
-WANTED = """\
-[distutils]
-index-servers =
-    pypi
-
-[pypi]
-username:tarek
-password:xxx
-"""
-
-
-class PyPIRCCommandTestCase(support.TempdirManager,
-                            support.LoggingSilencer,
-                            support.EnvironGuard,
-                            unittest.TestCase):
-
-    def setUp(self):
-        """Patches the environment."""
-        super(PyPIRCCommandTestCase, self).setUp()
-        self.tmp_dir = self.mkdtemp()
-        os.environ['HOME'] = self.tmp_dir
-        self.rc = os.path.join(self.tmp_dir, '.pypirc')
-        self.dist = Distribution()
-
-        class command(PyPIRCCommand):
-            def __init__(self, dist):
-                PyPIRCCommand.__init__(self, dist)
-            def initialize_options(self):
-                pass
-            finalize_options = initialize_options
-
-        self._cmd = command
-        self.old_threshold = set_threshold(WARN)
-
-    def tearDown(self):
-        """Removes the patch."""
-        set_threshold(self.old_threshold)
-        super(PyPIRCCommandTestCase, self).tearDown()
-
-    def test_server_registration(self):
-        # This test makes sure PyPIRCCommand knows how to:
-        # 1. handle several sections in .pypirc
-        # 2. handle the old format
-
-        # new format
-        self.write_file(self.rc, PYPIRC)
-        cmd = self._cmd(self.dist)
-        config = cmd._read_pypirc()
-
-        config = config.items()
-        config.sort()
-        expected = [('password', 'secret'), ('realm', 'pypi'),
-                    ('repository', 'http://pypi.python.org/pypi'),
-                    ('server', 'server1'), ('username', 'me')]
-        self.assertEqual(config, expected)
-
-        # old format
-        self.write_file(self.rc, PYPIRC_OLD)
-        config = cmd._read_pypirc()
-        config = config.items()
-        config.sort()
-        expected = [('password', 'secret'), ('realm', 'pypi'),
-                    ('repository', 'http://pypi.python.org/pypi'),
-                    ('server', 'server-login'), ('username', 'tarek')]
-        self.assertEqual(config, expected)
-
-    def test_server_empty_registration(self):
-        cmd = self._cmd(self.dist)
-        rc = cmd._get_rc_file()
-        self.assertTrue(not os.path.exists(rc))
-        cmd._store_pypirc('tarek', 'xxx')
-        self.assertTrue(os.path.exists(rc))
-        content = open(rc).read()
-        self.assertEqual(content, WANTED)
-
-def test_suite():
-    return unittest.makeSuite(PyPIRCCommandTestCase)
-
-if __name__ == "__main__":
-    unittest.main(defaultTest="test_suite")
diff --git a/src/distutils2/tests/test_register.py b/src/distutils2/tests/test_register.py
--- a/src/distutils2/tests/test_register.py
+++ b/src/distutils2/tests/test_register.py
@@ -19,7 +19,7 @@
 
 from distutils2.tests import support
 from distutils2.tests.support import unittest
-from distutils2.tests.test_config import PYPIRC, PyPIRCCommandTestCase
+
 
 PYPIRC_NOPASSWORD = """\
 [distutils]
@@ -68,10 +68,15 @@
     def read(self):
         return 'xxx'
 
-class RegisterTestCase(PyPIRCCommandTestCase):
+class RegisterTestCase(support.TempdirManager, support.EnvironGuard,
+                       unittest.TestCase):
 
     def setUp(self):
         super(RegisterTestCase, self).setUp()
+        self.tmp_dir = self.mkdtemp()
+        self.rc = os.path.join(self.tmp_dir, '.pypirc')
+        os.environ['HOME'] = self.tmp_dir
+
         # patching the password prompt
         self._old_getpass = getpass.getpass
         def _getpass(prompt):
@@ -148,8 +153,8 @@
 
         self.write_file(self.rc, PYPIRC_NOPASSWORD)
         cmd = self._get_cmd()
+        cmd.finalize_options()
         cmd._set_config()
-        cmd.finalize_options()
         cmd.send_metadata()
 
         # dist.password should be set
diff --git a/src/distutils2/tests/test_sdist.py b/src/distutils2/tests/test_sdist.py
--- a/src/distutils2/tests/test_sdist.py
+++ b/src/distutils2/tests/test_sdist.py
@@ -28,9 +28,8 @@
 from distutils2.command.sdist import show_formats
 from distutils2.core import Distribution
 from distutils2.tests.support import unittest
-from distutils2.tests.test_config import PyPIRCCommandTestCase
 from distutils2.errors import DistutilsExecError, DistutilsOptionError
-from distutils2.spawn import find_executable
+from distutils2.util import find_executable
 from distutils2.tests import support
 from distutils2.log import WARN
 try:
@@ -58,12 +57,15 @@
 somecode%(sep)sdoc.txt
 """
 
-class SDistTestCase(PyPIRCCommandTestCase):
+class SDistTestCase(support.TempdirManager, support.LoggingSilencer,
+                    support.EnvironGuard, unittest.TestCase):
 
     def setUp(self):
         # PyPIRCCommandTestCase creates a temp dir already
         # and put it in self.tmp_dir
         super(SDistTestCase, self).setUp()
+        self.tmp_dir = self.mkdtemp()
+        os.environ['HOME'] = self.tmp_dir
         # setting up an environment
         self.old_path = os.getcwd()
         os.mkdir(join(self.tmp_dir, 'somecode'))
diff --git a/src/distutils2/tests/test_spawn.py b/src/distutils2/tests/test_spawn.py
deleted file mode 100644
--- a/src/distutils2/tests/test_spawn.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""Tests for distutils.spawn."""
-import os
-import time
-from distutils2.tests import captured_stdout
-
-from distutils2.spawn import _nt_quote_args
-from distutils2.spawn import spawn, find_executable
-from distutils2.errors import DistutilsExecError
-from distutils2.tests import support
-from distutils2.tests.support import unittest
-
-class SpawnTestCase(support.TempdirManager,
-                    support.LoggingSilencer,
-                    unittest.TestCase):
-
-    def test_nt_quote_args(self):
-
-        for (args, wanted) in ((['with space', 'nospace'],
-                                ['"with space"', 'nospace']),
-                               (['nochange', 'nospace'],
-                                ['nochange', 'nospace'])):
-            res = _nt_quote_args(args)
-            self.assertEqual(res, wanted)
-
-
-    @unittest.skipUnless(os.name in ('nt', 'posix'),
-                         'Runs only under posix or nt')
-    def test_spawn(self):
-        tmpdir = self.mkdtemp()
-
-        # creating something executable
-        # through the shell that returns 1
-        if os.name == 'posix':
-            exe = os.path.join(tmpdir, 'foo.sh')
-            self.write_file(exe, '#!/bin/sh\nexit 1')
-            os.chmod(exe, 0777)
-        else:
-            exe = os.path.join(tmpdir, 'foo.bat')
-            self.write_file(exe, 'exit 1')
-
-        os.chmod(exe, 0777)
-        self.assertRaises(DistutilsExecError, spawn, [exe])
-
-        # now something that works
-        if os.name == 'posix':
-            exe = os.path.join(tmpdir, 'foo.sh')
-            self.write_file(exe, '#!/bin/sh\nexit 0')
-            os.chmod(exe, 0777)
-        else:
-            exe = os.path.join(tmpdir, 'foo.bat')
-            self.write_file(exe, 'exit 0')
-
-        os.chmod(exe, 0777)
-        spawn([exe])  # should work without any error
-
-def test_suite():
-    return unittest.makeSuite(SpawnTestCase)
-
-if __name__ == "__main__":
-    unittest.main(defaultTest="test_suite")
diff --git a/src/distutils2/tests/test_upload.py b/src/distutils2/tests/test_upload.py
--- a/src/distutils2/tests/test_upload.py
+++ b/src/distutils2/tests/test_upload.py
@@ -9,7 +9,6 @@
 from distutils2.tests import support
 from distutils2.tests.pypi_server import PyPIServer, PyPIServerTestCase
 from distutils2.tests.support import unittest
-from distutils2.tests.test_config import PYPIRC, PyPIRCCommandTestCase
 
 
 PYPIRC_NOPASSWORD = """\
@@ -22,7 +21,33 @@
 username:me
 """
 
-class UploadTestCase(PyPIServerTestCase, PyPIRCCommandTestCase):
+PYPIRC = """\
+[distutils]
+
+index-servers =
+    server1
+    server2
+
+[server1]
+username:me
+password:secret
+
+[server2]
+username:meagain
+password: secret
+realm:acme
+repository:http://another.pypi/
+"""
+
+
+class UploadTestCase(support.TempdirManager, support.EnvironGuard,
+                     PyPIServerTestCase):
+
+    def setUp(self):
+        super(UploadTestCase, self).setUp()
+        self.tmp_dir = self.mkdtemp()
+        self.rc = os.path.join(self.tmp_dir, '.pypirc')
+        os.environ['HOME'] = self.tmp_dir
 
     def test_finalize_options(self):
         # new format
diff --git a/src/distutils2/tests/test_upload_docs.py b/src/distutils2/tests/test_upload_docs.py
--- a/src/distutils2/tests/test_upload_docs.py
+++ b/src/distutils2/tests/test_upload_docs.py
@@ -12,7 +12,6 @@
 
 from distutils2.tests import support
 from distutils2.tests.pypi_server import PyPIServer, PyPIServerTestCase
-from distutils2.tests.test_config import PyPIRCCommandTestCase
 from distutils2.tests.support import unittest
 
 
@@ -47,10 +46,14 @@
 password = long_island
 """
 
-class UploadDocsTestCase(PyPIServerTestCase, PyPIRCCommandTestCase):
+class UploadDocsTestCase(support.TempdirManager, support.EnvironGuard,
+                         PyPIServerTestCase):
 
     def setUp(self):
         super(UploadDocsTestCase, self).setUp()
+        self.tmp_dir = self.mkdtemp()
+        self.rc = os.path.join(self.tmp_dir, '.pypirc')
+        os.environ['HOME'] = self.tmp_dir
         self.dist = Distribution()
         self.dist.metadata['Name'] = "distr-name"
         self.cmd = upload_docs(self.dist)
@@ -178,9 +181,13 @@
     def test_show_response(self):
         orig_stdout = sys.stdout
         write_args = []
+
         class MockStdIn(object):
             def write(self, arg):
                 write_args.append(arg)
+            def flush(self):
+                pass
+
         sys.stdout = MockStdIn()
         try:
             self.prepare_command()
@@ -188,8 +195,10 @@
             self.cmd.run()
         finally:
             sys.stdout = orig_stdout
+
         self.assertTrue(write_args[0], "should report the response")
-        self.assertIn(self.pypi.default_response_data + "\n", write_args[0])
+        self.assertIn(self.pypi.default_response_data + "\n",
+                      '\n'.join(write_args))
 
 def test_suite():
     return unittest.makeSuite(UploadDocsTestCase)
diff --git a/src/distutils2/tests/test_util.py b/src/distutils2/tests/test_util.py
--- a/src/distutils2/tests/test_util.py
+++ b/src/distutils2/tests/test_util.py
@@ -7,19 +7,58 @@
 import tempfile
 import time
 
+from distutils2.tests import captured_stdout
+from distutils2.tests.support import unittest
 from distutils2.errors import (DistutilsPlatformError,
                                DistutilsByteCompileError,
-                               DistutilsFileError)
+                               DistutilsFileError,
+                               DistutilsExecError)
+from distutils2.util import (convert_path, change_root,
+                             check_environ, split_quoted, strtobool,
+                             rfc822_escape, get_compiler_versions,
+                             _find_exe_version, _MAC_OS_X_LD_VERSION,
+                             byte_compile, find_packages, spawn, find_executable,
+                             _nt_quote_args, get_pypirc_path, generate_pypirc,
+                             read_pypirc)
 
-from distutils2.util import (convert_path, change_root,
-                            check_environ, split_quoted, strtobool,
-                            rfc822_escape, get_compiler_versions,
-                            _find_exe_version, _MAC_OS_X_LD_VERSION,
-                            byte_compile, find_packages)
 from distutils2 import util
 from distutils2.tests import support
 from distutils2.tests.support import unittest
 
+
+PYPIRC = """\
+[distutils]
+index-servers =
+    pypi
+    server1
+
+[pypi]
+username:me
+password:xxxx
+
+[server1]
+repository:http://example.com
+username:tarek
+password:secret
+"""
+
+PYPIRC_OLD = """\
+[server-login]
+username:tarek
+password:secret
+"""
+
+WANTED = """\
+[distutils]
+index-servers =
+    pypi
+
+[pypi]
+username:tarek
+password:xxx
+"""
+
+
 class FakePopen(object):
     test_class = None
     def __init__(self, cmd, shell, stdout, stderr):
@@ -40,6 +79,9 @@
 
     def setUp(self):
         super(UtilTestCase, self).setUp()
+        self.tmp_dir = self.mkdtemp()
+        self.rc = os.path.join(self.tmp_dir, '.pypirc')
+        os.environ['HOME'] = self.tmp_dir
         # saving the environment
         self.name = os.name
         self.platform = sys.platform
@@ -332,6 +374,80 @@
         file_handle.close()
         self.assertEquals(new_content, converted_content)
 
+    def test_nt_quote_args(self):
+
+        for (args, wanted) in ((['with space', 'nospace'],
+                                ['"with space"', 'nospace']),
+                               (['nochange', 'nospace'],
+                                ['nochange', 'nospace'])):
+            res = _nt_quote_args(args)
+            self.assertEqual(res, wanted)
+
+
+    @unittest.skipUnless(os.name in ('nt', 'posix'),
+                         'Runs only under posix or nt')
+    def test_spawn(self):
+        tmpdir = self.mkdtemp()
+
+        # creating something executable
+        # through the shell that returns 1
+        if os.name == 'posix':
+            exe = os.path.join(tmpdir, 'foo.sh')
+            self.write_file(exe, '#!/bin/sh\nexit 1')
+            os.chmod(exe, 0777)
+        else:
+            exe = os.path.join(tmpdir, 'foo.bat')
+            self.write_file(exe, 'exit 1')
+
+        os.chmod(exe, 0777)
+        self.assertRaises(DistutilsExecError, spawn, [exe])
+
+        # now something that works
+        if os.name == 'posix':
+            exe = os.path.join(tmpdir, 'foo.sh')
+            self.write_file(exe, '#!/bin/sh\nexit 0')
+            os.chmod(exe, 0777)
+        else:
+            exe = os.path.join(tmpdir, 'foo.bat')
+            self.write_file(exe, 'exit 0')
+
+        os.chmod(exe, 0777)
+        spawn([exe])  # should work without any error
+
+    def test_server_registration(self):
+        # This test makes sure we know how to:
+        # 1. handle several sections in .pypirc
+        # 2. handle the old format
+
+        # new format
+        self.write_file(self.rc, PYPIRC)
+        config = read_pypirc()
+
+        config = config.items()
+        config.sort()
+        expected = [('password', 'xxxx'), ('realm', 'pypi'),
+                    ('repository', 'http://pypi.python.org/pypi'),
+                    ('server', 'pypi'), ('username', 'me')]
+        self.assertEqual(config, expected)
+
+        # old format
+        self.write_file(self.rc, PYPIRC_OLD)
+        config = read_pypirc()
+        config = config.items()
+        config.sort()
+        expected = [('password', 'secret'), ('realm', 'pypi'),
+                    ('repository', 'http://pypi.python.org/pypi'),
+                    ('server', 'server-login'), ('username', 'tarek')]
+        self.assertEqual(config, expected)
+
+    def test_server_empty_registration(self):
+        rc = get_pypirc_path()
+        self.assertTrue(not os.path.exists(rc))
+        generate_pypirc('tarek', 'xxx')
+        self.assertTrue(os.path.exists(rc))
+        content = open(rc).read()
+        self.assertEqual(content, WANTED)
+
 
 def test_suite():
     return unittest.makeSuite(UtilTestCase)
diff --git a/src/distutils2/util.py b/src/distutils2/util.py
--- a/src/distutils2/util.py
+++ b/src/distutils2/util.py
@@ -15,10 +15,10 @@
 import zipfile
 from copy import copy
 from fnmatch import fnmatchcase
+from ConfigParser import RawConfigParser
 
 from distutils2.errors import (DistutilsPlatformError, DistutilsFileError,
-                               DistutilsByteCompileError)
-from distutils2.spawn import spawn, find_executable
+                               DistutilsByteCompileError, DistutilsExecError)
 from distutils2 import log
 from distutils2._backport import sysconfig as _sysconfig
 
@@ -805,3 +805,306 @@
         return path.split('\\', 1)
     else:
         return path, ''
+
+
+def spawn(cmd, search_path=1, verbose=0, dry_run=0, 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.
+    cmd[0] is the program to run and cmd[1:] are the rest of its arguments.
+    There is no way to run a program with a name different from that of its
+    executable.
+
+    If 'search_path' is true (the default), the system's executable
+    search path will be used to find the program; otherwise, cmd[0]
+    must be the exact path to the executable.  If 'dry_run' is true,
+    the command will not actually be run.
+
+    If 'env' is given, it's a environment dictionary used for the execution
+    environment.
+
+    Raise DistutilsExecError if running the program fails in any way; just
+    return on success.
+    """
+    if os.name == 'posix':
+        _spawn_posix(cmd, search_path, dry_run=dry_run, env=env)
+    elif os.name == 'nt':
+        _spawn_nt(cmd, search_path, dry_run=dry_run, env=env)
+    elif os.name == 'os2':
+        _spawn_os2(cmd, search_path, dry_run=dry_run, env=env)
+    else:
+        raise DistutilsPlatformError(
+              "don't know how to spawn programs on platform '%s'" % os.name)
+
+
+def _nt_quote_args(args):
+    """Quote command-line arguments for DOS/Windows conventions.
+
+    Just wraps every argument which contains blanks in double quotes, and
+    returns a new argument list.
+    """
+    # XXX this doesn't seem very robust to me -- but if the Windows guys
+    # say it'll work, I guess I'll have to accept it.  (What if an arg
+    # contains quotes?  What other magic characters, other than spaces,
+    # have to be escaped?  Is there an escaping mechanism other than
+    # quoting?)
+    for i, arg in enumerate(args):
+        if ' ' in arg:
+            args[i] = '"%s"' % arg
+    return args
+
+
+def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0, env=None):
+    executable = cmd[0]
+    cmd = _nt_quote_args(cmd)
+    if search_path:
+        # either we find one or it stays the same
+        executable = find_executable(executable) or executable
+    log.info(' '.join([executable] + cmd[1:]))
+    if not dry_run:
+        # spawn for NT requires a full path to the .exe
+        try:
+            if env is None:
+                rc = os.spawnv(os.P_WAIT, executable, cmd)
+            else:
+                rc = os.spawnve(os.P_WAIT, executable, cmd, env)
+
+        except OSError, exc:
+            # this seems to happen when the command isn't found
+            raise DistutilsExecError(
+                  "command '%s' failed: %s" % (cmd[0], exc[-1]))
+        if rc != 0:
+            # and this reflects the command running but failing
+            raise DistutilsExecError(
+                  "command '%s' failed with exit status %d" % (cmd[0], rc))
+
+
+def _spawn_os2(cmd, search_path=1, verbose=0, dry_run=0, env=None):
+    executable = cmd[0]
+    if search_path:
+        # either we find one or it stays the same
+        executable = find_executable(executable) or executable
+    log.info(' '.join([executable] + cmd[1:]))
+    if not dry_run:
+        # spawnv for OS/2 EMX requires a full path to the .exe
+        try:
+            if env is None:
+                rc = os.spawnv(os.P_WAIT, executable, cmd)
+            else:
+                rc = os.spawnve(os.P_WAIT, executable, cmd, env)
+
+        except OSError, exc:
+            # this seems to happen when the command isn't found
+            raise DistutilsExecError(
+                  "command '%s' failed: %s" % (cmd[0], exc[-1]))
+        if rc != 0:
+            # and this reflects the command running but failing
+            log.debug("command '%s' failed with exit status %d" % (cmd[0], rc))
+            raise DistutilsExecError(
+                  "command '%s' failed with exit status %d" % (cmd[0], rc))
+
+
+def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0, env=None):
+    log.info(' '.join(cmd))
+    if dry_run:
+        return
+
+    if env is None:
+        exec_fn = search_path and os.execvp or os.execv
+    else:
+        exec_fn = search_path and os.execvpe or os.execve
+
+    pid = os.fork()
+
+    if pid == 0:  # in the child
+        try:
+            if env is None:
+                exec_fn(cmd[0], cmd)
+            else:
+                exec_fn(cmd[0], cmd, env)
+        except OSError, e:
+            sys.stderr.write("unable to execute %s: %s\n" %
+                             (cmd[0], e.strerror))
+            os._exit(1)
+
+        sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0])
+        os._exit(1)
+    else:   # in the parent
+        # Loop until the child either exits or is terminated by a signal
+        # (ie. keep waiting if it's merely stopped)
+        while 1:
+            try:
+                pid, status = os.waitpid(pid, 0)
+            except OSError, exc:
+                import errno
+                if exc.errno == errno.EINTR:
+                    continue
+                raise DistutilsExecError(
+                      "command '%s' failed: %s" % (cmd[0], exc[-1]))
+            if os.WIFSIGNALED(status):
+                raise DistutilsExecError(
+                      "command '%s' terminated by signal %d" % \
+                      (cmd[0], os.WTERMSIG(status)))
+
+            elif os.WIFEXITED(status):
+                exit_status = os.WEXITSTATUS(status)
+                if exit_status == 0:
+                    return   # hey, it succeeded!
+                else:
+                    raise DistutilsExecError(
+                          "command '%s' failed with exit status %d" % \
+                          (cmd[0], exit_status))
+
+            elif os.WIFSTOPPED(status):
+                continue
+
+            else:
+                raise DistutilsExecError(
+                      "unknown error executing '%s': termination status %d" % \
+                      (cmd[0], status))
+
+
+def find_executable(executable, path=None):
+    """Tries to find 'executable' in the directories listed in 'path'.
+
+    A string listing directories separated by 'os.pathsep'; defaults to
+    os.environ['PATH'].  Returns the complete filename or None if not found.
+    """
+    if path is None:
+        path = os.environ['PATH']
+    paths = path.split(os.pathsep)
+    base, ext = os.path.splitext(executable)
+
+    if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):
+        executable = executable + '.exe'
+
+    if not os.path.isfile(executable):
+        for p in paths:
+            f = os.path.join(p, executable)
+            if os.path.isfile(f):
+                # the file exists, we have a shot at spawn working
+                return f
+        return None
+    else:
+        return executable
+
+
+DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
+DEFAULT_REALM = 'pypi'
+DEFAULT_PYPIRC = """\
+[distutils]
+index-servers =
+    pypi
+
+[pypi]
+username:%s
+password:%s
+"""
+
+def get_pypirc_path():
+    """Returns rc file path."""
+    return os.path.join(os.path.expanduser('~'), '.pypirc')
+
+
+def generate_pypirc(username, password):
+    """Creates a default .pypirc file."""
+    rc = get_pypirc_path()
+    f = open(rc, 'w')
+    try:
+        f.write(DEFAULT_PYPIRC % (username, password))
+    finally:
+        f.close()
+    try:
+        os.chmod(rc, 0600)
+    except OSError:
+        # should do something better here
+        pass
+
+
+def read_pypirc(repository=DEFAULT_REPOSITORY, realm=DEFAULT_REALM):
+    """Reads the .pypirc file."""
+    rc = get_pypirc_path()
+    if os.path.exists(rc):
+        config = RawConfigParser()
+        config.read(rc)
+        sections = config.sections()
+        if 'distutils' in sections:
+            # let's get the list of servers
+            index_servers = config.get('distutils', 'index-servers')
+            _servers = [server.strip() for server in
+                        index_servers.split('\n')
+                        if server.strip() != '']
+            if _servers == []:
+                # nothing set, let's try to get the default pypi
+                if 'pypi' in sections:
+                    _servers = ['pypi']
+                else:
+                    # the file is not properly defined, returning
+                    # an empty dict
+                    return {}
+            for server in _servers:
+                current = {'server': server}
+                current['username'] = config.get(server, 'username')
+
+                # optional params
+                for key, default in (('repository',
+                                       DEFAULT_REPOSITORY),
+                                     ('realm', DEFAULT_REALM),
+                                     ('password', None)):
+                    if config.has_option(server, key):
+                        current[key] = config.get(server, key)
+                    else:
+                        current[key] = default
+                if (current['server'] == repository or
+                    current['repository'] == repository):
+                    return current
+        elif 'server-login' in sections:
+            # old format
+            server = 'server-login'
+            if config.has_option(server, 'repository'):
+                repository = config.get(server, 'repository')
+            else:
+                repository = DEFAULT_REPOSITORY
+
+            return {'username': config.get(server, 'username'),
+                    'password': config.get(server, 'password'),
+                    'repository': repository,
+                    'server': server,
+                    'realm': DEFAULT_REALM}
+
+    return {}
+
+
+def metadata_to_dict(meta):
+    """XXX might want to move it to the Metadata class."""
+    data = {
+        'metadata_version' : meta.version,
+        'name': meta['Name'],
+        'version': meta['Version'],
+        'summary': meta['Summary'],
+        'home_page': meta['Home-page'],
+        'author': meta['Author'],
+        'author_email': meta['Author-email'],
+        'license': meta['License'],
+        'description': meta['Description'],
+        'keywords': meta['Keywords'],
+        'platform': meta['Platform'],
+        'classifier': meta['Classifier'],
+        'download_url': meta['Download-URL'],
+    }
+
+    if meta.version == '1.2':
+        data['requires_dist'] = meta['Requires-Dist']
+        data['requires_python'] = meta['Requires-Python']
+        data['requires_external'] = meta['Requires-External']
+        data['provides_dist'] = meta['Provides-Dist']
+        data['obsoletes_dist'] = meta['Obsoletes-Dist']
+        data['project_url'] = [','.join(url) for url in
+                                meta['Project-URL']]
+
+    elif meta.version == '1.1':
+        data['provides'] = meta['Provides']
+        data['requires'] = meta['Requires']
+        data['obsoletes'] = meta['Obsoletes']
+
+    return data
diff --git a/src/tests.sh b/src/tests.sh
--- a/src/tests.sh
+++ b/src/tests.sh
@@ -1,8 +1,9 @@
 #!/bin/sh
 echo -n "Running tests for Python 2.4... "
-rm -rf _hashlib.so
+rm -rf *.so
 python2.4 setup.py build_ext -i -q 2> /dev/null > /dev/null
 python2.4 -Wd runtests.py -q 2> /dev/null
+rm -rf *.so
 if [ $? -ne 0 ];then
     echo "Failed"
     exit 1
@@ -11,9 +12,9 @@
 fi
 
 echo -n "Running tests for Python 2.5... "
-rm -rf _hashlib.so
 python2.5 setup.py build_ext -i -q 2> /dev/null > /dev/null
 python2.5 -Wd runtests.py -q 2> /dev/null
+rm -rf *.so
 if [ $? -ne 0 ];then
     echo "Failed"
     exit 1

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


More information about the Python-checkins mailing list