[Python-checkins] distutils2: removed the config module

tarek.ziade python-checkins at python.org
Thu Jul 29 11:11:19 CEST 2010


tarek.ziade pushed ba37b166e4f9 to distutils2:

http://hg.python.org/distutils2/rev/ba37b166e4f9
changeset:   387:ba37b166e4f9
tag:         tip
user:        Tarek Ziade <tarek at ziade.org>
date:        Thu Jul 29 11:10:45 2010 +0200
summary:     removed the config module
files:       src/distutils2/command/register.py, src/distutils2/command/upload.py, src/distutils2/command/upload_docs.py, src/distutils2/config.py, src/distutils2/core.py, src/distutils2/tests/test_config.py, src/distutils2/tests/test_register.py, src/distutils2/tests/test_sdist.py, src/distutils2/tests/test_upload.py, src/distutils2/tests/test_upload_docs.py, src/distutils2/tests/test_util.py, src/distutils2/util.py

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.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/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/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,7 +28,6 @@
 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.util import find_executable
 from distutils2.tests import support
@@ -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_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
@@ -18,11 +18,47 @@
                              rfc822_escape, get_compiler_versions,
                              _find_exe_version, _MAC_OS_X_LD_VERSION,
                              byte_compile, find_packages, spawn, find_executable,
-                             _nt_quote_args)
+                             _nt_quote_args, get_pypirc_path, generate_pypirc,
+                             read_pypirc)
+
 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):
@@ -43,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
@@ -375,6 +414,40 @@
         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
@@ -11,6 +11,7 @@
 import re
 from copy import copy
 from fnmatch import fnmatchcase
+from ConfigParser import RawConfigParser
 
 from distutils2.errors import (DistutilsPlatformError, DistutilsFileError,
                                DistutilsByteCompileError, DistutilsExecError)
@@ -869,3 +870,124 @@
         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

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


More information about the Python-checkins mailing list