Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8d9bb11

Browse filesBrowse files
authored
bpo-28334: netrc() now uses expanduser() to find .netrc file (GH-4537)
Previously, netrc.netrc() was raised an exception if $HOME is not set. Authored-By: Dimitri Merejkowsky <dimitri.merejkowsky@tanker.io>
1 parent 9d5ec80 commit 8d9bb11
Copy full SHA for 8d9bb11

File tree

5 files changed

+53
-10
lines changed
Filter options

5 files changed

+53
-10
lines changed

‎Doc/library/netrc.rst

Copy file name to clipboardExpand all lines: Doc/library/netrc.rst
+8-3Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ the Unix :program:`ftp` program and other FTP clients.
2020

2121
A :class:`~netrc.netrc` instance or subclass instance encapsulates data from a netrc
2222
file. The initialization argument, if present, specifies the file to parse. If
23-
no argument is given, the file :file:`.netrc` in the user's home directory will
24-
be read. Parse errors will raise :exc:`NetrcParseError` with diagnostic
23+
no argument is given, the file :file:`.netrc` in the user's home directory --
24+
as determined by :func:`os.path.expanduser` -- will be read. Otherwise,
25+
a :exc:`FileNotFoundError` exception will be raised.
26+
Parse errors will raise :exc:`NetrcParseError` with diagnostic
2527
information including the file name, line number, and terminating token.
2628
If no argument is specified on a POSIX system, the presence of passwords in
2729
the :file:`.netrc` file will raise a :exc:`NetrcParseError` if the file
@@ -32,6 +34,10 @@ the Unix :program:`ftp` program and other FTP clients.
3234

3335
.. versionchanged:: 3.4 Added the POSIX permission check.
3436

37+
.. versionchanged:: 3.7
38+
:func:`os.path.expanduser` is used to find the location of the
39+
:file:`.netrc` file when *file* is not passed as argument.
40+
3541

3642
.. exception:: NetrcParseError
3743

@@ -82,4 +88,3 @@ Instances of :class:`~netrc.netrc` have public instance variables:
8288
punctuation is allowed in passwords, however, note that whitespace and
8389
non-printable characters are not allowed in passwords. This is a limitation
8490
of the way the .netrc file is parsed and may be removed in the future.
85-

‎Lib/netrc.py

Copy file name to clipboardExpand all lines: Lib/netrc.py
+1-4Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ class netrc:
2323
def __init__(self, file=None):
2424
default_netrc = file is None
2525
if file is None:
26-
try:
27-
file = os.path.join(os.environ['HOME'], ".netrc")
28-
except KeyError:
29-
raise OSError("Could not find .netrc: $HOME is not set") from None
26+
file = os.path.join(os.path.expanduser("~"), ".netrc")
3027
self.hosts = {}
3128
self.macros = {}
3229
with open(file) as fp:

‎Lib/test/test_netrc.py

Copy file name to clipboardExpand all lines: Lib/test/test_netrc.py
+40-3Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import netrc, os, unittest, sys, tempfile, textwrap
2+
from unittest import mock
23
from test import support
34

45

@@ -126,8 +127,44 @@ def test_security(self):
126127
os.chmod(fn, 0o622)
127128
self.assertRaises(netrc.NetrcParseError, netrc.netrc)
128129

129-
def test_main():
130-
support.run_unittest(NetrcTestCase)
130+
def test_file_not_found_in_home(self):
131+
d = support.TESTFN
132+
os.mkdir(d)
133+
self.addCleanup(support.rmtree, d)
134+
with support.EnvironmentVarGuard() as environ:
135+
environ.set('HOME', d)
136+
self.assertRaises(FileNotFoundError, netrc.netrc)
137+
138+
def test_file_not_found_explicit(self):
139+
self.assertRaises(FileNotFoundError, netrc.netrc,
140+
file='unlikely_netrc')
141+
142+
def test_home_not_set(self):
143+
fake_home = support.TESTFN
144+
os.mkdir(fake_home)
145+
self.addCleanup(support.rmtree, fake_home)
146+
fake_netrc_path = os.path.join(fake_home, '.netrc')
147+
with open(fake_netrc_path, 'w') as f:
148+
f.write('machine foo.domain.com login bar password pass')
149+
os.chmod(fake_netrc_path, 0o600)
150+
151+
orig_expanduser = os.path.expanduser
152+
called = []
153+
154+
def fake_expanduser(s):
155+
called.append(s)
156+
with support.EnvironmentVarGuard() as environ:
157+
environ.set('HOME', fake_home)
158+
result = orig_expanduser(s)
159+
return result
160+
161+
with support.swap_attr(os.path, 'expanduser', fake_expanduser):
162+
nrc = netrc.netrc()
163+
login, account, password = nrc.authenticators('foo.domain.com')
164+
self.assertEqual(login, 'bar')
165+
166+
self.assertTrue(called)
167+
131168

132169
if __name__ == "__main__":
133-
test_main()
170+
unittest.main()

‎Misc/ACKS

Copy file name to clipboardExpand all lines: Misc/ACKS
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@ Bill van Melle
10311031
Lucas Prado Melo
10321032
Ezio Melotti
10331033
Doug Mennella
1034+
Dimitri Merejkowsky
10341035
Brian Merrell
10351036
Alexis Métaireau
10361037
Luke Mewburn
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Use :func:`os.path.expanduser` to find the ``~/.netrc`` file in
2+
:class:`netrc.netrc`. If it does not exist, :exc:`FileNotFoundError`
3+
is raised. Patch by Dimitri Merejkowsky.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.