diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2013-11-14 10:40:32 -0500 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2013-11-14 10:40:32 -0500 |
commit | 6797a9d07f8aa4db29d0ac7e343bf04898514e67 (patch) | |
tree | 80c2484b56c5cbc4879dff2624d9cb6c3f7dcd1e /setuptools/package_index.py | |
parent | e91750870026844cb8729f99182d9707625ae0fa (diff) | |
parent | 915b99c8440fe0aa04609ce249a0e845f5b97e44 (diff) | |
download | external_python_setuptools-6797a9d07f8aa4db29d0ac7e343bf04898514e67.tar.gz external_python_setuptools-6797a9d07f8aa4db29d0ac7e343bf04898514e67.tar.bz2 external_python_setuptools-6797a9d07f8aa4db29d0ac7e343bf04898514e67.zip |
Merge support for loading credentials from .pypirc (based on pull request #11). Fixes #27.
Diffstat (limited to 'setuptools/package_index.py')
-rwxr-xr-x | setuptools/package_index.py | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 4c9e40a7..26d1d4ad 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -17,7 +17,8 @@ from distutils.errors import DistutilsError from setuptools.compat import (urllib2, httplib, StringIO, HTTPError, urlparse, urlunparse, unquote, splituser, url2pathname, name2codepoint, - unichr, urljoin, urlsplit, urlunsplit) + unichr, urljoin, urlsplit, urlunsplit, + ConfigParser) from setuptools.compat import filterfalse from fnmatch import translate from setuptools.py24compat import hashlib @@ -920,6 +921,60 @@ def _encode_auth(auth): # strip the trailing carriage return return encoded.rstrip() +class Credential(object): + """ + A username/password pair. Use like a namedtuple. + """ + def __init__(self, username, password): + self.username = username + self.password = password + + def __iter__(self): + yield self.username + yield self.password + + def __str__(self): + return '%(username)s:%(password)s' % vars(self) + +class PyPIConfig(ConfigParser.ConfigParser): + + def __init__(self): + """ + Load from ~/.pypirc + """ + defaults = dict.fromkeys(['username', 'password', 'repository'], '') + super(PyPIConfig, self).__init__(defaults) + + rc = os.path.join(os.path.expanduser('~'), '.pypirc') + if os.path.exists(rc): + self.read(rc) + + @property + def creds_by_repository(self): + sections_with_repositories = [ + section for section in self.sections() + if self.get(section, 'repository').strip() + ] + + return dict(map(self._get_repo_cred, sections_with_repositories)) + + def _get_repo_cred(self, section): + repo = self.get(section, 'repository').strip() + return repo, Credential( + self.get(section, 'username').strip(), + self.get(section, 'password').strip(), + ) + + def find_credential(self, url): + """ + If the URL indicated appears to be a repository defined in this + config, return the credential for that repository. + """ + for repository, cred in self.creds_by_repository.items(): + if url.startswith(repository): + return cred + + def open_with_auth(url, opener=urllib2.urlopen): """Open a urllib2 request, handling HTTP authentication""" @@ -935,6 +990,13 @@ def open_with_auth(url, opener=urllib2.urlopen): else: auth = None + if not auth: + cred = PyPIConfig().find_credential(url) + if cred: + auth = str(cred) + info = cred.username, url + log.info('Authenticating as %s for %s (from .pypirc)' % info) + if auth: auth = "Basic " + _encode_auth(auth) new_url = urlunparse((scheme,host,path,params,query,frag)) |