For some reason, the upload command is stricter than the register command when writing to PyPI. Upload requires a [server-login] section in .pypirc, but register does not. It seems like they should at least use the same logic. This was with 0.6.26. I don't know yet if it affects later versions of Distribute.
This is with a "[distutils] index-servers =" section in the .pypirc.
$ python setup.py register -r test using: version '0.6' of <module 'setuptools' from '.../python2.7/site-packages/distribute-0.6.26-py2.7.egg/setuptools/__init__.pyc'> Registering Foo to http://testpypi.python.org/pypi Server response (200): OK $ python setup.py upload -r test using: version '0.6' of <module 'setuptools' from '.../python2.7/site-packages/distribute-0.6.26-py2.7.egg/setuptools/__init__.pyc'> running upload Traceback (most recent call last): File "setup.py", line 99, in <module> main(sys.argv) File "setup.py", line 95, in main classifiers=CLASSIFIERS, File ".../python2.7/distutils/core.py", line 152, in setup dist.run_commands() File ".../python2.7/distutils/dist.py", line 953, in run_commands self.run_command(cmd) File ".../python2.7/distutils/dist.py", line 971, in run_command cmd_obj.ensure_finalized() File ".../python2.7/distutils/cmd.py", line 109, in ensure_finalized self.finalize_options() File ".../python2.7/site-packages/distribute-0.6.26-py2.7.egg/setuptools/command/upload.py", line 64, in finalize_options self.username = config.get('server-login', 'username') File ".../python2.7/ConfigParser.py", line 607, in get raise NoSectionError(section) ConfigParser.NoSectionError: No section: 'server-login'