69027[tip]:49366 7bcee1441718 2011-03-29 00:25 +0200 saffroy netrc: support more than one entry per host diff -r 95fff5a6a276 -r 7bcee1441718 Lib/netrc.py --- a/Lib/netrc.py Wed Oct 01 22:05:43 2008 +0000 +++ b/Lib/netrc.py Tue Mar 29 00:25:34 2011 +0200 @@ -28,6 +28,7 @@ raise IOError("Could not find .netrc: $HOME is not set") fp = open(file) self.hosts = {} + self.allhosts = {} self.macros = {} lexer = shlex.shlex(fp) lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" @@ -58,13 +59,17 @@ # We're looking at start of an entry for a named machine or default. login = '' account = password = None + if entryname not in self.allhosts: + self.allhosts[entryname] = [] self.hosts[entryname] = {} while 1: tt = lexer.get_token() if (tt=='' or tt == 'machine' or tt == 'default' or tt =='macdef'): if password: - self.hosts[entryname] = (login, account, password) + a = (login, account, password) + self.allhosts[entryname].append(a) + self.hosts[entryname] = a lexer.push_token(tt) break else: @@ -82,10 +87,16 @@ raise NetrcParseError("bad follower token %r" % tt, file, lexer.lineno) - def authenticators(self, host): + def authenticators(self, host, login=None): """Return a (user, account, password) tuple for given host.""" if host in self.hosts: - return self.hosts[host] + if login: + for a in self.allhosts[host]: + if a[0] == login: + return a + return None + else: + return self.hosts[host] elif 'default' in self.hosts: return self.hosts['default'] else: @@ -94,12 +105,12 @@ def __repr__(self): """Dump the class data in the format of a .netrc file.""" rep = "" - for host in self.hosts.keys(): - attrs = self.hosts[host] - rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n" - if attrs[1]: - rep = rep + "account " + repr(attrs[1]) - rep = rep + "\tpassword " + repr(attrs[2]) + "\n" + for host in self.allhosts.keys(): + for attrs in self.allhosts[host]: + rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n" + if attrs[1]: + rep = rep + "account " + repr(attrs[1]) + rep = rep + "\tpassword " + repr(attrs[2]) + "\n" for macro in self.macros.keys(): rep = rep + "macdef " + macro + "\n" for line in self.macros[macro]: diff -r 95fff5a6a276 -r 7bcee1441718 Lib/test/test_netrc.py --- a/Lib/test/test_netrc.py Wed Oct 01 22:05:43 2008 +0000 +++ b/Lib/test/test_netrc.py Tue Mar 29 00:25:34 2011 +0200 @@ -15,6 +15,9 @@ default login log2 password pass2 +machine bar login log3 password pass3 account acct3 +machine bar login log4 password pass4 account acct4 + """ temp_filename = test_support.TESTFN @@ -40,6 +43,9 @@ ) self.assert_(self.netrc.hosts['foo'] == ('log1', 'acct1', 'pass1')) self.assert_(self.netrc.hosts['default'] == ('log2', None, 'pass2')) + self.assert_(self.netrc.hosts['bar'] == ('log4', 'acct4', 'pass4')) + self.assert_(self.netrc.authenticators('bar') == ('log4', 'acct4', 'pass4')) + self.assert_(self.netrc.authenticators('bar', 'log3') == ('log3', 'acct3', 'pass3')) def test_main(): test_support.run_unittest(NetrcTestCase)