Unverified Kaydet (Commit) 8d9bb11d authored tarafından Berker Peksag's avatar Berker Peksag Kaydeden (comit) GitHub

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: 's avatarDimitri Merejkowsky <dimitri.merejkowsky@tanker.io>
üst 9d5ec808
...@@ -20,8 +20,10 @@ the Unix :program:`ftp` program and other FTP clients. ...@@ -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 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 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 no argument is given, the file :file:`.netrc` in the user's home directory --
be read. Parse errors will raise :exc:`NetrcParseError` with diagnostic 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. information including the file name, line number, and terminating token.
If no argument is specified on a POSIX system, the presence of passwords in 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 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. ...@@ -32,6 +34,10 @@ the Unix :program:`ftp` program and other FTP clients.
.. versionchanged:: 3.4 Added the POSIX permission check. .. 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 .. exception:: NetrcParseError
...@@ -82,4 +88,3 @@ Instances of :class:`~netrc.netrc` have public instance variables: ...@@ -82,4 +88,3 @@ Instances of :class:`~netrc.netrc` have public instance variables:
punctuation is allowed in passwords, however, note that whitespace and punctuation is allowed in passwords, however, note that whitespace and
non-printable characters are not allowed in passwords. This is a limitation 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. of the way the .netrc file is parsed and may be removed in the future.
...@@ -23,10 +23,7 @@ class netrc: ...@@ -23,10 +23,7 @@ class netrc:
def __init__(self, file=None): def __init__(self, file=None):
default_netrc = file is None default_netrc = file is None
if file is None: if file is None:
try: file = os.path.join(os.path.expanduser("~"), ".netrc")
file = os.path.join(os.environ['HOME'], ".netrc")
except KeyError:
raise OSError("Could not find .netrc: $HOME is not set") from None
self.hosts = {} self.hosts = {}
self.macros = {} self.macros = {}
with open(file) as fp: with open(file) as fp:
......
import netrc, os, unittest, sys, tempfile, textwrap import netrc, os, unittest, sys, tempfile, textwrap
from unittest import mock
from test import support from test import support
...@@ -126,8 +127,44 @@ class NetrcTestCase(unittest.TestCase): ...@@ -126,8 +127,44 @@ class NetrcTestCase(unittest.TestCase):
os.chmod(fn, 0o622) os.chmod(fn, 0o622)
self.assertRaises(netrc.NetrcParseError, netrc.netrc) self.assertRaises(netrc.NetrcParseError, netrc.netrc)
def test_main(): def test_file_not_found_in_home(self):
support.run_unittest(NetrcTestCase) 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__": if __name__ == "__main__":
test_main() unittest.main()
...@@ -1031,6 +1031,7 @@ Bill van Melle ...@@ -1031,6 +1031,7 @@ Bill van Melle
Lucas Prado Melo Lucas Prado Melo
Ezio Melotti Ezio Melotti
Doug Mennella Doug Mennella
Dimitri Merejkowsky
Brian Merrell Brian Merrell
Alexis Métaireau Alexis Métaireau
Luke Mewburn Luke Mewburn
......
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.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment