When you launch such a command:
$ python setup.py register sdist upload
There’s no way to give to Distutils your PyPI password in the prompt, so you distribution is uploaded to the server. You have to store your password in the .pypirc file:
[distutils]
index-servers =
pypi
[pypi]
username: <username>
password: <password>
The password is stored in clear text, so it can be used by Distutils to authenticate. This is rather unsecure, since anyone who has a read access to your home can get your password.
I have detected this problem this summer while listing the possible enhancements in Distutils. Nathan Van Gheem sent me a mail a month ago to ask for that same feature in collective.dist; which is a port of the latest Distutils features into Python 2.4 so Zope can use them. So before having it into collective.dist, the first step was to introduce it into Python itself.
The idea is to be able to remove from .pypirc the password so it’s asked at the prompt. Nothing fancy here : the Distribution object that is created before you launch any command is the place where you can share a context between commands.
So when you launch:
$ python setup.py register sdist upload
Here’s what is happening:
- register looks into .pypirc, if no password is found, it asks it to the user using getpass
- register use it then store it in the Distribution instance
- upload look into the Distribution instance to see if the password was stored, and use it
This is now available in Python 2.7 and 3.1, and heavily tested.
I’d like to go further and to think about a ssh-agent like system, so there’s no need to enter the pasword everytime you work with PyPI in the same session.
Does anyone knows what would be the way to do it properly ? I think a ssh-agent like mechanism in Python’s getpass would be a great feature itself.



This is something that Zope also lacks for its “adduser” command, if I remember correctly — so if you have done this to collective.dist and Python, maybe it’s easy to apply that to Zope too. It always bothered me to execute a command with the password in the command line.
Comment by Alexander Limi — January 9, 2009 @ 10:07 am |
If you’re going to look at an ssh agent system, I’d suggest you go native and use existing solutions. Have python look for ssh agent, or keychain on the mac, or the Gnome/KDE keychain. Secure key storage is a large problem in and of itself, and it would be a real boon to integrate with tools that users already use…
Comment by Douglas — January 9, 2009 @ 3:20 pm |
I already have to unlock my ssh-agent keyring, my GNOME keyring, and my Firefox keyring when I log in. I’m not looking forward to also having a new one (distutils-keyring?). Having getpass optionally use the system’s native keyring (which would be the GNOME one on my laptop) sounds like it’s not a bad idea.
Another alternative would be to use ssh for authentication — there are modules out there that let you implement a virtual SSH server in Python without having to mess with system user accounts.
Comment by Marius Gedminas — January 9, 2009 @ 4:23 pm |
Please retain the facility for storing the pypi password in the .pypirc, thanks.
Comment by Richard Jones — January 10, 2009 @ 7:34 am |
@Alex : Imho that would be fairly easy by adding a getpass call where required.
@Douglas and Marius : thanks for the tips ! From what I read here and on the distutils mailing list, I think there are two different options that raise:
1/ make getpass.getpass use system native keyrings
2/ implement on PyPI server a SSH server that can be use by regular ssh
3/ add a way to use the ssh version in Distutils’ register/upload (or a set of new commands)
@Richard : Yes indeed, this facility should not be removed
Comment by Tarek Ziadé — January 10, 2009 @ 10:32 am |
Is this available in collective.dist, yet? I’m having terrible trouble using “python setup.py bdist_egg upload” on my new Vista machine as I keep on getting an error saying that I “must be identified to edit package information”. I thought I had my .pypirc file correctly setup, but apparently not. Just being able to circumvent that config minefield and login with a prompt would be *great*.
Comment by Tim Hicks — January 24, 2009 @ 11:05 pm |
@Tim it’s in the trunk, expect a release this week. It should fix your troubles also, since there’s a bug in Python’s distutils regarding the location of .pypirc
Comment by Tarek Ziadé — January 26, 2009 @ 10:33 am |
Tarek, that’s great. I look forward to the release. At the moment, I have things tagged in svn for my own long-promised software release (Quills, the weblog software for Plone), but I’m unable to get eggs onto pypi. Thanks for your work on this.
Comment by Tim Hicks — January 26, 2009 @ 2:15 pm |
@Tim : released !
Comment by Tarek Ziadé — January 31, 2009 @ 1:01 pm |
Tarek, I just tried it out, but get an error (below). Any idea what the problem is?
D:\dev\qe.trunk\src\quills.core>python setup.py sdist mupload
Using PyPI login from setup.cfg
Traceback (most recent call last):
File “setup.py”, line 31, in ?
entry_points=”"”
File “C:\Python24\lib\distutils\core.py”, line 149, in setup
dist.run_commands()
File “C:\Python24\lib\distutils\dist.py”, line 946, in run_commands
self.run_command(cmd)
File “C:\Python24\lib\distutils\dist.py”, line 965, in run_command
cmd_obj.ensure_finalized()
File “C:\Python24\lib\distutils\cmd.py”, line 117, in ensure_finalized
self.finalize_options()
File “c:\python24\lib\site-packages\collective.dist-0.2.1-py2.4.egg\collective
\dist\mupload.py”, line 61, in finalize_options
if not self.password and self.distribution.password:
AttributeError: Distribution instance has no attribute ‘password’
D:\dev\qe.trunk\src\quills.core>
Comment by Tim Hicks — February 3, 2009 @ 5:38 pm |