Thanks to visit codestin.com
Credit goes to github.com

Skip to content

bpo-28334: netrc() now uses expanduser() to find .netrc file #4537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions Doc/library/netrc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ the Unix :program:`ftp` program and other FTP clients.

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

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

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


.. exception:: NetrcParseError

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

5 changes: 1 addition & 4 deletions Lib/netrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ class netrc:
def __init__(self, file=None):
default_netrc = file is None
if file is None:
try:
file = os.path.join(os.environ['HOME'], ".netrc")
except KeyError:
raise OSError("Could not find .netrc: $HOME is not set") from None
file = os.path.join(os.path.expanduser("~"), ".netrc")
self.hosts = {}
self.macros = {}
with open(file) as fp:
Expand Down
43 changes: 40 additions & 3 deletions Lib/test/test_netrc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import netrc, os, unittest, sys, tempfile, textwrap
from unittest import mock
from test import support


Expand Down Expand Up @@ -126,8 +127,44 @@ def test_security(self):
os.chmod(fn, 0o622)
self.assertRaises(netrc.NetrcParseError, netrc.netrc)

def test_main():
support.run_unittest(NetrcTestCase)
def test_file_not_found_in_home(self):
d = support.TESTFN
os.mkdir(d)
self.addCleanup(support.rmtree, d)
with support.EnvironmentVarGuard() as environ:
environ.set('HOME', d)
self.assertRaises(FileNotFoundError, netrc.netrc)

def test_file_not_found_explicit(self):
self.assertRaises(FileNotFoundError, netrc.netrc,
file='unlikely_netrc')

def test_home_not_set(self):
fake_home = support.TESTFN
os.mkdir(fake_home)
self.addCleanup(support.rmtree, fake_home)
fake_netrc_path = os.path.join(fake_home, '.netrc')
with open(fake_netrc_path, 'w') as f:
f.write('machine foo.domain.com login bar password pass')
os.chmod(fake_netrc_path, 0o600)

orig_expanduser = os.path.expanduser
called = []

def fake_expanduser(s):
called.append(s)
with support.EnvironmentVarGuard() as environ:
environ.set('HOME', fake_home)
result = orig_expanduser(s)
return result

with support.swap_attr(os.path, 'expanduser', fake_expanduser):
nrc = netrc.netrc()
login, account, password = nrc.authenticators('foo.domain.com')
self.assertEqual(login, 'bar')

self.assertTrue(called)


if __name__ == "__main__":
test_main()
unittest.main()
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,7 @@ Bill van Melle
Lucas Prado Melo
Ezio Melotti
Doug Mennella
Dimitri Merejkowsky
Brian Merrell
Alexis Métaireau
Luke Mewburn
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Use :func:`os.path.expanduser` to find the ``~/.netrc`` file in
:class:`netrc.netrc`. If it does not exist, :exc:`FileNotFoundError`
is raised. Patch by Dimitri Merejkowsky.