Skip to content

Commit 4c3c39a

Browse files
Berthin TorresBerthin Torres
authored andcommitted
iadd support for the envvar and implement tests
1 parent b14986c commit 4c3c39a

2 files changed

Lines changed: 80 additions & 31 deletions

File tree

Lib/netrc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class netrc:
6767
def __init__(self, file=None):
6868
default_netrc = file is None
6969
if file is None:
70-
file = os.path.join(os.path.expanduser("~"), ".netrc")
70+
file = os.environ.get("NETRC", "") or os.path.join(os.path.expanduser("~"), ".netrc")
7171
self.hosts = {}
7272
self.macros = {}
7373
try:

Lib/test/test_netrc.py

Lines changed: 79 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,92 @@
1-
import netrc, os, unittest, sys, textwrap
2-
from test.support import os_helper
1+
import netrc, os, unittest, sys, textwrap, tempfile
2+
3+
from test import support
4+
from unittest import mock
35

46
try:
57
import pwd
68
except ImportError:
79
pwd = None
810

9-
temp_filename = os_helper.TESTFN
11+
12+
def generate_netrc(directory, filename, data):
13+
data = textwrap.dedent(data)
14+
mode = 'w'
15+
mode = 'w'
16+
if sys.platform != 'cygwin':
17+
mode += 't'
18+
with open(os.path.join(directory, filename), mode, encoding="utf-8") as fp:
19+
fp.write(data)
20+
1021

1122
class NetrcTestCase(unittest.TestCase):
1223

13-
def make_nrc(self, test_data):
14-
test_data = textwrap.dedent(test_data)
15-
mode = 'w'
16-
if sys.platform != 'cygwin':
17-
mode += 't'
18-
with open(temp_filename, mode, encoding="utf-8") as fp:
19-
fp.write(test_data)
20-
try:
21-
nrc = netrc.netrc(temp_filename)
22-
finally:
23-
os.unlink(temp_filename)
24+
@staticmethod
25+
def home_netrc(data):
26+
with support.os_helper.EnvironmentVarGuard() as environ, \
27+
tempfile.TemporaryDirectory() as tmpdir:
28+
environ.unset('NETRC')
29+
environ.unset('HOME')
30+
31+
generate_netrc(tmpdir, ".netrc", data)
32+
os.chmod(os.path.join(tmpdir, ".netrc"), 0o600)
33+
34+
with mock.patch("os.path.expanduser"):
35+
os.path.expanduser.return_value = tmpdir
36+
nrc = netrc.netrc()
37+
2438
return nrc
2539

26-
def test_toplevel_non_ordered_tokens(self):
27-
nrc = self.make_nrc("""\
40+
@staticmethod
41+
def envvar_netrc(data):
42+
with support.os_helper.EnvironmentVarGuard() as environ:
43+
with tempfile.TemporaryDirectory() as tmpdir:
44+
environ.set('NETRC', os.path.join(tmpdir, ".netrc"))
45+
environ.unset('HOME')
46+
47+
generate_netrc(tmpdir, ".netrc", data)
48+
os.chmod(os.path.join(tmpdir, ".netrc"), 0o600)
49+
50+
nrc = netrc.netrc()
51+
52+
return nrc
53+
54+
@staticmethod
55+
def file_argument(data):
56+
with support.os_helper.EnvironmentVarGuard() as environ:
57+
with tempfile.TemporaryDirectory() as tmpdir:
58+
environ.set('NETRC', 'not-a-file.random')
59+
60+
generate_netrc(tmpdir, ".netrc", data)
61+
os.chmod(os.path.join(tmpdir, ".netrc"), 0o600)
62+
63+
nrc = netrc.netrc(os.path.join(tmpdir, ".netrc"))
64+
65+
return nrc
66+
67+
def make_nrc(self, test_data):
68+
return self.file_argument(test_data)
69+
70+
@support.subTests('nrc_builder', (home_netrc, envvar_netrc, file_argument))
71+
def test_toplevel_non_ordered_tokens(self, nrc_builder):
72+
nrc = nrc_builder("""\
2873
machine host.domain.com password pass1 login log1 account acct1
2974
default login log2 password pass2 account acct2
3075
""")
3176
self.assertEqual(nrc.hosts['host.domain.com'], ('log1', 'acct1', 'pass1'))
3277
self.assertEqual(nrc.hosts['default'], ('log2', 'acct2', 'pass2'))
3378

34-
def test_toplevel_tokens(self):
35-
nrc = self.make_nrc("""\
79+
@support.subTests('nrc_builder', (home_netrc, envvar_netrc, file_argument))
80+
def test_toplevel_tokens(self, nrc_builder):
81+
nrc = nrc_builder("""\
3682
machine host.domain.com login log1 password pass1 account acct1
3783
default login log2 password pass2 account acct2
3884
""")
3985
self.assertEqual(nrc.hosts['host.domain.com'], ('log1', 'acct1', 'pass1'))
4086
self.assertEqual(nrc.hosts['default'], ('log2', 'acct2', 'pass2'))
4187

42-
def test_macros(self):
88+
@support.subTests('nrc_builder', (home_netrc, envvar_netrc, file_argument))
89+
def test_macros(self, nrc_builder):
4390
data = """\
4491
macdef macro1
4592
line1
@@ -50,14 +97,15 @@ def test_macros(self):
5097
line4
5198
5299
"""
53-
nrc = self.make_nrc(data)
100+
nrc = nrc_builder(data)
54101
self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'],
55102
'macro2': ['line3\n', 'line4\n']})
56103
# strip the last \n
57104
self.assertRaises(netrc.NetrcParseError, self.make_nrc,
58105
data.rstrip(' ')[:-1])
59106

60-
def test_optional_tokens(self):
107+
@support.subTests('nrc_builder', (home_netrc, envvar_netrc, file_argument))
108+
def test_optional_tokens(self, nrc_builder):
61109
data = (
62110
"machine host.domain.com",
63111
"machine host.domain.com login",
@@ -68,7 +116,7 @@ def test_optional_tokens(self):
68116
"machine host.domain.com account \"\" password"
69117
)
70118
for item in data:
71-
nrc = self.make_nrc(item)
119+
nrc = nrc_builder(item)
72120
self.assertEqual(nrc.hosts['host.domain.com'], ('', '', ''))
73121
data = (
74122
"default",
@@ -83,7 +131,8 @@ def test_optional_tokens(self):
83131
nrc = self.make_nrc(item)
84132
self.assertEqual(nrc.hosts['default'], ('', '', ''))
85133

86-
def test_invalid_tokens(self):
134+
@support.subTests('nrc_builder', (home_netrc, envvar_netrc, file_argument))
135+
def test_invalid_tokens(self, nrc_builder):
87136
data = (
88137
"invalid host.domain.com",
89138
"machine host.domain.com invalid",
@@ -92,7 +141,7 @@ def test_invalid_tokens(self):
92141
"default host.domain.com login log password pass account acct invalid"
93142
)
94143
for item in data:
95-
self.assertRaises(netrc.NetrcParseError, self.make_nrc, item)
144+
self.assertRaises(netrc.NetrcParseError, nrc_builder, item)
96145

97146
def _test_token_x(self, nrc, token, value):
98147
nrc = self.make_nrc(nrc)
@@ -102,7 +151,7 @@ def _test_token_x(self, nrc, token, value):
102151
self.assertEqual(nrc.hosts['host.domain.com'], ('log', value, 'pass'))
103152
elif token == 'password':
104153
self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', value))
105-
154+
106155
def test_token_value_quotes(self):
107156
self._test_token_x("""\
108157
machine host.domain.com login "log" password pass account acct
@@ -272,20 +321,20 @@ def test_comment_at_end_of_machine_line_pass_has_hash(self):
272321

273322
@unittest.skipUnless(os.name == 'posix', 'POSIX only test')
274323
@unittest.skipIf(pwd is None, 'security check requires pwd module')
275-
@os_helper.skip_unless_working_chmod
324+
@support.os_helper.skip_unless_working_chmod
276325
def test_security(self):
277326
# This test is incomplete since we are normally not run as root and
278327
# therefore can't test the file ownership being wrong.
279-
d = os_helper.TESTFN
328+
d = support.os_helper.TESTFN
280329
os.mkdir(d)
281-
self.addCleanup(os_helper.rmtree, d)
330+
self.addCleanup(support.os_helper.rmtree, d)
282331
fn = os.path.join(d, '.netrc')
283332
with open(fn, 'wt') as f:
284333
f.write("""\
285334
machine foo.domain.com login bar password pass
286335
default login foo password pass
287336
""")
288-
with os_helper.EnvironmentVarGuard() as environ:
337+
with support.os_helper.EnvironmentVarGuard() as environ:
289338
environ.set('HOME', d)
290339
os.chmod(fn, 0o600)
291340
nrc = netrc.netrc()
@@ -298,7 +347,7 @@ def test_security(self):
298347
machine foo.domain.com login anonymous password pass
299348
default login foo password pass
300349
""")
301-
with os_helper.EnvironmentVarGuard() as environ:
350+
with support.os_helper.EnvironmentVarGuard() as environ:
302351
environ.set('HOME', d)
303352
os.chmod(fn, 0o600)
304353
nrc = netrc.netrc()

0 commit comments

Comments
 (0)