ยปCore Development>Code coverage>Lib/netrc.py

Python code coverage for Lib/netrc.py

#countcontent
1n/a"""An object-oriented interface to .netrc files."""
2n/a
3n/a# Module and documentation by Eric S. Raymond, 21 Dec 1998
4n/a
5n/aimport os, shlex, stat
6n/a
7n/a__all__ = ["netrc", "NetrcParseError"]
8n/a
9n/a
10n/aclass NetrcParseError(Exception):
11n/a """Exception raised on syntax errors in the .netrc file."""
12n/a def __init__(self, msg, filename=None, lineno=None):
13n/a self.filename = filename
14n/a self.lineno = lineno
15n/a self.msg = msg
16n/a Exception.__init__(self, msg)
17n/a
18n/a def __str__(self):
19n/a return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno)
20n/a
21n/a
22n/aclass netrc:
23n/a def __init__(self, file=None):
24n/a default_netrc = file is None
25n/a if file is None:
26n/a try:
27n/a file = os.path.join(os.environ['HOME'], ".netrc")
28n/a except KeyError:
29n/a raise OSError("Could not find .netrc: $HOME is not set")
30n/a self.hosts = {}
31n/a self.macros = {}
32n/a with open(file) as fp:
33n/a self._parse(file, fp, default_netrc)
34n/a
35n/a def _parse(self, file, fp, default_netrc):
36n/a lexer = shlex.shlex(fp)
37n/a lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
38n/a lexer.commenters = lexer.commenters.replace('#', '')
39n/a while 1:
40n/a # Look for a machine, default, or macdef top-level keyword
41n/a saved_lineno = lexer.lineno
42n/a toplevel = tt = lexer.get_token()
43n/a if not tt:
44n/a break
45n/a elif tt[0] == '#':
46n/a if lexer.lineno == saved_lineno and len(tt) == 1:
47n/a lexer.instream.readline()
48n/a continue
49n/a elif tt == 'machine':
50n/a entryname = lexer.get_token()
51n/a elif tt == 'default':
52n/a entryname = 'default'
53n/a elif tt == 'macdef': # Just skip to end of macdefs
54n/a entryname = lexer.get_token()
55n/a self.macros[entryname] = []
56n/a lexer.whitespace = ' \t'
57n/a while 1:
58n/a line = lexer.instream.readline()
59n/a if not line or line == '\012':
60n/a lexer.whitespace = ' \t\r\n'
61n/a break
62n/a self.macros[entryname].append(line)
63n/a continue
64n/a else:
65n/a raise NetrcParseError(
66n/a "bad toplevel token %r" % tt, file, lexer.lineno)
67n/a
68n/a # We're looking at start of an entry for a named machine or default.
69n/a login = ''
70n/a account = password = None
71n/a self.hosts[entryname] = {}
72n/a while 1:
73n/a tt = lexer.get_token()
74n/a if (tt.startswith('#') or
75n/a tt in {'', 'machine', 'default', 'macdef'}):
76n/a if password:
77n/a self.hosts[entryname] = (login, account, password)
78n/a lexer.push_token(tt)
79n/a break
80n/a else:
81n/a raise NetrcParseError(
82n/a "malformed %s entry %s terminated by %s"
83n/a % (toplevel, entryname, repr(tt)),
84n/a file, lexer.lineno)
85n/a elif tt == 'login' or tt == 'user':
86n/a login = lexer.get_token()
87n/a elif tt == 'account':
88n/a account = lexer.get_token()
89n/a elif tt == 'password':
90n/a if os.name == 'posix' and default_netrc:
91n/a prop = os.fstat(fp.fileno())
92n/a if prop.st_uid != os.getuid():
93n/a import pwd
94n/a try:
95n/a fowner = pwd.getpwuid(prop.st_uid)[0]
96n/a except KeyError:
97n/a fowner = 'uid %s' % prop.st_uid
98n/a try:
99n/a user = pwd.getpwuid(os.getuid())[0]
100n/a except KeyError:
101n/a user = 'uid %s' % os.getuid()
102n/a raise NetrcParseError(
103n/a ("~/.netrc file owner (%s) does not match"
104n/a " current user (%s)") % (fowner, user),
105n/a file, lexer.lineno)
106n/a if (prop.st_mode & (stat.S_IRWXG | stat.S_IRWXO)):
107n/a raise NetrcParseError(
108n/a "~/.netrc access too permissive: access"
109n/a " permissions must restrict access to only"
110n/a " the owner", file, lexer.lineno)
111n/a password = lexer.get_token()
112n/a else:
113n/a raise NetrcParseError("bad follower token %r" % tt,
114n/a file, lexer.lineno)
115n/a
116n/a def authenticators(self, host):
117n/a """Return a (user, account, password) tuple for given host."""
118n/a if host in self.hosts:
119n/a return self.hosts[host]
120n/a elif 'default' in self.hosts:
121n/a return self.hosts['default']
122n/a else:
123n/a return None
124n/a
125n/a def __repr__(self):
126n/a """Dump the class data in the format of a .netrc file."""
127n/a rep = ""
128n/a for host in self.hosts.keys():
129n/a attrs = self.hosts[host]
130n/a rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n"
131n/a if attrs[1]:
132n/a rep = rep + "account " + repr(attrs[1])
133n/a rep = rep + "\tpassword " + repr(attrs[2]) + "\n"
134n/a for macro in self.macros.keys():
135n/a rep = rep + "macdef " + macro + "\n"
136n/a for line in self.macros[macro]:
137n/a rep = rep + line
138n/a rep = rep + "\n"
139n/a return rep
140n/a
141n/aif __name__ == '__main__':
142n/a print(netrc())