Merged revisions 68415 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r68415 | tarek.ziade | 2009-01-09 00:56:31 +0100 (Fri, 09 Jan 2009) | 1 line

  fixed #4394 make the storage of the password optional in .pypirc
........
diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py
index 30e9a37..c271b18 100644
--- a/Lib/distutils/command/register.py
+++ b/Lib/distutils/command/register.py
@@ -174,19 +174,23 @@
                           log.INFO)
 
             # possibly save the login
-            if not self.has_config and code == 200:
-                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)
-
-                choice = 'X'
-                while choice.lower() not in 'yn':
-                    choice = input('Save your login (y/N)?')
-                    if not choice:
-                        choice = 'n'
-                if choice.lower() == 'y':
-                    self._store_pypirc(username, password)
+            if code == 200:
+                if self.has_config:
+                    # sharing the password in the distribution instance
+                    # so the upload command can reuse it
+                    self.distribution.password = password
+                else:
+                    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)
+                    choice = 'X'
+                    while choice.lower() not in 'yn':
+                        choice = input('Save your login (y/N)?')
+                        if not choice:
+                            choice = 'n'
+                    if choice.lower() == 'y':
+                        self._store_pypirc(username, password)
 
         elif choice == '2':
             data = {':action': 'user'}
diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py
index 7ba7f58..020e860 100644
--- a/Lib/distutils/command/upload.py
+++ b/Lib/distutils/command/upload.py
@@ -48,6 +48,11 @@
             self.repository = config['repository']
             self.realm = config['realm']
 
+        # getting the password from the distribution
+        # if previously set by the register command
+        if not self.password and self.distribution.password:
+            self.password = self.distribution.password
+
     def run(self):
         if not self.distribution.dist_files:
             raise DistutilsOptionError("No dist file created in earlier command")
diff --git a/Lib/distutils/config.py b/Lib/distutils/config.py
index 73f3260..5b625f3 100644
--- a/Lib/distutils/config.py
+++ b/Lib/distutils/config.py
@@ -82,12 +82,12 @@
                 for server in _servers:
                     current = {'server': server}
                     current['username'] = config.get(server, 'username')
-                    current['password'] = config.get(server, 'password')
 
                     # optional params
                     for key, default in (('repository',
                                           self.DEFAULT_REPOSITORY),
-                                         ('realm', self.DEFAULT_REALM)):
+                                         ('realm', self.DEFAULT_REALM),
+                                         ('password', None)):
                         if config.has_option(server, key):
                             current[key] = config.get(server, key)
                         else:
diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py
index 7903c2a..6c4b4af 100644
--- a/Lib/distutils/dist.py
+++ b/Lib/distutils/dist.py
@@ -199,6 +199,7 @@
         self.extra_path = None
         self.scripts = None
         self.data_files = None
+        self.password = ''
 
         # And now initialize bookkeeping stuff that can't be supplied by
         # the caller at all.  'command_obj' maps command names to
diff --git a/Lib/distutils/tests/test_register.py b/Lib/distutils/tests/test_register.py
index 021b3ea..8826e90 100644
--- a/Lib/distutils/tests/test_register.py
+++ b/Lib/distutils/tests/test_register.py
@@ -2,6 +2,7 @@
 import sys
 import os
 import unittest
+import getpass
 
 from distutils.command.register import register
 from distutils.core import Distribution
@@ -9,7 +10,27 @@
 from distutils.tests import support
 from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
 
-class RawInputs(object):
+PYPIRC_NOPASSWORD = """\
+[distutils]
+
+index-servers =
+    server1
+
+[server1]
+username:me
+"""
+
+WANTED_PYPIRC = """\
+[distutils]
+index-servers =
+    pypi
+
+[pypi]
+username:tarek
+password:password
+"""
+
+class Inputs(object):
     """Fakes user inputs."""
     def __init__(self, *answers):
         self.answers = answers
@@ -21,18 +42,33 @@
         finally:
             self.index += 1
 
-WANTED_PYPIRC = """\
-[distutils]
-index-servers =
-    pypi
+class FakeServer(object):
+    """Fakes a PyPI server"""
+    def __init__(self):
+        self.calls = []
 
-[pypi]
-username:tarek
-password:xxx
-"""
+    def __call__(self, *args):
+        # we want to compare them, so let's store
+        # something comparable
+        els = list(args[0].items())
+        els.sort()
+        self.calls.append(tuple(els))
+        return 200, 'OK'
 
 class registerTestCase(PyPIRCCommandTestCase):
 
+    def setUp(self):
+        PyPIRCCommandTestCase.setUp(self)
+        # patching the password prompt
+        self._old_getpass = getpass.getpass
+        def _getpass(prompt):
+            return 'password'
+        getpass.getpass = _getpass
+
+    def tearDown(self):
+        getpass.getpass = self._old_getpass
+        PyPIRCCommandTestCase.tearDown(self)
+
     def test_create_pypirc(self):
         # this test makes sure a .pypirc file
         # is created when requested.
@@ -50,30 +86,17 @@
         # we shouldn't have a .pypirc file yet
         self.assert_(not os.path.exists(self.rc))
 
-        # patching raw_input and getpass.getpass
+        # patching input and getpass.getpass
         # so register gets happy
         #
         # Here's what we are faking :
         # use your existing login (choice 1.)
         # Username : 'tarek'
-        # Password : 'xxx'
+        # Password : 'password'
         # Save your login (y/N)? : 'y'
-        inputs = RawInputs('1', 'tarek', 'y')
+        inputs = Inputs('1', 'tarek', 'y')
         from distutils.command import register as register_module
         register_module.input = inputs.__call__
-        def _getpass(prompt):
-            return 'xxx'
-        register_module.getpass.getpass = _getpass
-        class FakeServer(object):
-            def __init__(self):
-                self.calls = []
-
-            def __call__(self, *args):
-                # we want to compare them, so let's store
-                # something comparable
-                els = sorted(args[0].items())
-                self.calls.append(tuple(els))
-                return 200, 'OK'
 
         cmd.post_to_server = pypi_server = FakeServer()
 
@@ -101,6 +124,24 @@
         self.assert_(len(pypi_server.calls), 2)
         self.assert_(pypi_server.calls[0], pypi_server.calls[1])
 
+    def test_password_not_in_file(self):
+
+        f = open(self.rc, 'w')
+        f.write(PYPIRC_NOPASSWORD)
+        f.close()
+
+        dist = Distribution()
+        cmd = register(dist)
+        cmd.post_to_server = FakeServer()
+
+        cmd._set_config()
+        cmd.finalize_options()
+        cmd.send_metadata()
+
+        # dist.password should be set
+        # therefore used afterwards by other commands
+        self.assertEquals(dist.password, 'password')
+
 def test_suite():
     return unittest.makeSuite(registerTestCase)
 
diff --git a/Lib/distutils/tests/test_upload.py b/Lib/distutils/tests/test_upload.py
index b05ab1f..3f8ca6d 100644
--- a/Lib/distutils/tests/test_upload.py
+++ b/Lib/distutils/tests/test_upload.py
@@ -9,6 +9,17 @@
 from distutils.tests import support
 from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
 
+PYPIRC_NOPASSWORD = """\
+[distutils]
+
+index-servers =
+    server1
+
+[server1]
+username:me
+"""
+
+
 class uploadTestCase(PyPIRCCommandTestCase):
 
     def test_finalize_options(self):
@@ -26,6 +37,24 @@
                              ('repository', 'http://pypi.python.org/pypi')):
             self.assertEquals(getattr(cmd, attr), waited)
 
+    def test_saved_password(self):
+        # file with no password
+        f = open(self.rc, 'w')
+        f.write(PYPIRC_NOPASSWORD)
+        f.close()
+
+        # make sure it passes
+        dist = Distribution()
+        cmd = upload(dist)
+        cmd.finalize_options()
+        self.assertEquals(cmd.password, None)
+
+        # make sure we get it as well, if another command
+        # initialized it at the dist level
+        dist.password = 'xxx'
+        cmd = upload(dist)
+        cmd.finalize_options()
+        self.assertEquals(cmd.password, 'xxx')
 
 def test_suite():
     return unittest.makeSuite(uploadTestCase)