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

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 11 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 5 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 43 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 1 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.
Morty Proxy This is a proxified and sanitized view of the page, visit original site.