[Python-checkins] r68417 - in python/branches/py3k: Doc/distutils/packageindex.rst Doc/distutils/uploading.rst Doc/whatsnew/2.7.rst Lib/distutils/command/register.py Lib/distutils/command/upload.py Lib/distutils/config.py Lib/distutils/dist.py Lib/distutils/tests/test_register.py Lib/distutils/tests/test_upload.py

tarek.ziade python-checkins at python.org
Fri Jan 9 01:15:46 CET 2009


Author: tarek.ziade
Date: Fri Jan 9 01:15:45 2009
New Revision: 68417
Log:
Merged revisions 68415 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk
........
 r68415 | tarek.ziade | 2009年01月09日 00:56:31 +0100 (2009年1月09日) | 1 line
 
 fixed #4394 make the storage of the password optional in .pypirc
........
Modified:
 python/branches/py3k/ (props changed)
 python/branches/py3k/Doc/distutils/packageindex.rst
 python/branches/py3k/Doc/distutils/uploading.rst
 python/branches/py3k/Doc/whatsnew/2.7.rst
 python/branches/py3k/Lib/distutils/command/register.py
 python/branches/py3k/Lib/distutils/command/upload.py
 python/branches/py3k/Lib/distutils/config.py
 python/branches/py3k/Lib/distutils/dist.py
 python/branches/py3k/Lib/distutils/tests/test_register.py
 python/branches/py3k/Lib/distutils/tests/test_upload.py
Modified: python/branches/py3k/Doc/distutils/packageindex.rst
==============================================================================
--- python/branches/py3k/Doc/distutils/packageindex.rst	(original)
+++ python/branches/py3k/Doc/distutils/packageindex.rst	Fri Jan 9 01:15:45 2009
@@ -8,17 +8,17 @@
 packaged with distutils. The distutils command :command:`register` is used to
 submit your distribution's meta-data to the index. It is invoked as follows::
 
- python setup.py register
+ python setup.py register
 
 Distutils will respond with the following prompt::
 
- running register
- We need to know who you are, so please choose either:
- 1. use your existing login,
- 2. register as a new user,
- 3. have the server generate a new password for you (and email it to you), or
- 4. quit
- Your selection [default 1]:
+ running register
+ We need to know who you are, so please choose either:
+ 1. use your existing login,
+ 2. register as a new user,
+ 3. have the server generate a new password for you (and email it to you), or
+ 4. quit
+ Your selection [default 1]:
 
 Note: if your username and password are saved locally, you will not see this
 menu.
@@ -55,40 +55,50 @@
 
 The format of the :file:`.pypirc` file is as follows::
 
- [distutils]
- index-servers =
- pypi
+ [distutils]
+ index-servers =
+ pypi
 
- [pypi]
- repository: <repository-url>
- username: <username>
- password: <password>
+ [pypi]
+ repository: <repository-url>
+ username: <username>
+ password: <password>
 
-*repository* can be omitted and defaults to ``http://www.python.org/pypi``.
+The *distutils* section defines a *index-servers* variable that lists the
+name of all sections describing a repository.
 
-If you want to define another server a new section can be created::
+Each section describing a repository defines three variables:
 
- [distutils]
- index-servers =
- pypi
- other
+- *repository*, that defines the url of the PyPI server. Defaults to
+ ``http://www.python.org/pypi``.
+- *username*, which is the registered username on the PyPI server.
+- *password*, that will be used to authenticate. If omitted the user
+ will be prompt to type it when needed.
 
- [pypi]
- repository: <repository-url>
- username: <username>
- password: <password>
+If you want to define another server a new section can be created and
+listed in the *index-servers* variable::
 
- [other]
- repository: http://example.com/pypi
- username: <username>
- password: <password>
+ [distutils]
+ index-servers =
+ pypi
+ other
 
-The command can then be called with the -r option::
+ [pypi]
+ repository: <repository-url>
+ username: <username>
+ password: <password>
 
- python setup.py register -r http://example.com/pypi
+ [other]
+ repository: http://example.com/pypi
+ username: <username>
+ password: <password>
 
-Or even with the section name::
+:command:`register` can then be called with the -r option to point the
+repository to work with::
 
- python setup.py register -r other
+ python setup.py register -r http://example.com/pypi
 
+The name of the section that describes the repository may also be used
+for conveniency::
 
+ python setup.py register -r other
Modified: python/branches/py3k/Doc/distutils/uploading.rst
==============================================================================
--- python/branches/py3k/Doc/distutils/uploading.rst	(original)
+++ python/branches/py3k/Doc/distutils/uploading.rst	Fri Jan 9 01:15:45 2009
@@ -11,7 +11,7 @@
 The command is invoked immediately after building one or more distribution
 files. For example, the command ::
 
- python setup.py sdist bdist_wininst upload
+ python setup.py sdist bdist_wininst upload
 
 will cause the source distribution and the Windows installer to be uploaded to
 PyPI. Note that these will be uploaded even if they are built using an earlier
@@ -20,11 +20,14 @@
 
 The :command:`upload` command uses the username, password, and repository URL
 from the :file:`$HOME/.pypirc` file (see section :ref:`pypirc` for more on this
-file).
+file). If a :command:`register` command was previously called in the same command,
+and if the password was entered in the prompt, :command:`upload` will reuse the
+entered password. This is useful if you do not want to store a clear text
+password in the :file:`$HOME/.pypirc` file.
 
 You can specify another PyPI server with the :option:`--repository=*url*` option::
 
- python setup.py sdist bdist_wininst upload -r http://example.com/pypi
+ python setup.py sdist bdist_wininst upload -r http://example.com/pypi
 
 See section :ref:`pypirc` for more on defining several servers.
 
@@ -38,4 +41,3 @@
 *section* the name of the section in :file:`$HOME/.pypirc`, and
 :option:`--show-response` (which displays the full response text from the PyPI
 server for help in debugging upload problems).
-
Modified: python/branches/py3k/Doc/whatsnew/2.7.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/2.7.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/2.7.rst	Fri Jan 9 01:15:45 2009
@@ -120,6 +120,12 @@
 
 (Contributed by Gregory P. Smith.)
 
+* It is not mandatory anymore to store clear text passwords in the
+ :file:`.pypirc` file when registering and uploading packages to PyPI. As
+ long as the username is present in that file, the :mod:`distutils` package
+ will prompt for the password if not present.
+ (Added by tarek, with the initial contribution of Nathan Van Gheem;
+ :issue:`4394`.)
 
 .. ======================================================================
 .. whole new modules get described in subsections here
Modified: python/branches/py3k/Lib/distutils/command/register.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/register.py	(original)
+++ python/branches/py3k/Lib/distutils/command/register.py	Fri Jan 9 01:15:45 2009
@@ -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'}
Modified: python/branches/py3k/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/upload.py	(original)
+++ python/branches/py3k/Lib/distutils/command/upload.py	Fri Jan 9 01:15:45 2009
@@ -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")
Modified: python/branches/py3k/Lib/distutils/config.py
==============================================================================
--- python/branches/py3k/Lib/distutils/config.py	(original)
+++ python/branches/py3k/Lib/distutils/config.py	Fri Jan 9 01:15:45 2009
@@ -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:
Modified: python/branches/py3k/Lib/distutils/dist.py
==============================================================================
--- python/branches/py3k/Lib/distutils/dist.py	(original)
+++ python/branches/py3k/Lib/distutils/dist.py	Fri Jan 9 01:15:45 2009
@@ -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
Modified: python/branches/py3k/Lib/distutils/tests/test_register.py
==============================================================================
--- python/branches/py3k/Lib/distutils/tests/test_register.py	(original)
+++ python/branches/py3k/Lib/distutils/tests/test_register.py	Fri Jan 9 01:15:45 2009
@@ -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
-
-[pypi]
-username:tarek
-password:xxx
-"""
+class FakeServer(object):
+ """Fakes a PyPI server"""
+ def __init__(self):
+ self.calls = []
+
+ 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)
 
Modified: python/branches/py3k/Lib/distutils/tests/test_upload.py
==============================================================================
--- python/branches/py3k/Lib/distutils/tests/test_upload.py	(original)
+++ python/branches/py3k/Lib/distutils/tests/test_upload.py	Fri Jan 9 01:15:45 2009
@@ -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)


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /