mirror of https://github.com/python/cpython
bpo-18108: Adding dir_fd and follow_symlinks keyword args to shutil.chown (GH-15811)
* Adding dir_fd and follow_symlinks keyword args to shutil.chown * Extending test_shutil.TestShutil.test_chown to include new kwargs * Updating shutil.chown documentation Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Berker Peksag <berker.peksag@gmail.com> Co-authored-by: Zachary Ware <zachary.ware@gmail.com>
This commit is contained in:
parent
78ba4cb758
commit
8974a63f5e
|
@ -421,7 +421,8 @@ Directory and files operations
|
||||||
|
|
||||||
.. availability:: Unix, Windows.
|
.. availability:: Unix, Windows.
|
||||||
|
|
||||||
.. function:: chown(path, user=None, group=None)
|
.. function:: chown(path, user=None, group=None, *, dir_fd=None, \
|
||||||
|
follow_symlinks=True)
|
||||||
|
|
||||||
Change owner *user* and/or *group* of the given *path*.
|
Change owner *user* and/or *group* of the given *path*.
|
||||||
|
|
||||||
|
@ -436,6 +437,9 @@ Directory and files operations
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
Added *dir_fd* and *follow_symlinks* parameters.
|
||||||
|
|
||||||
|
|
||||||
.. function:: which(cmd, mode=os.F_OK | os.X_OK, path=None)
|
.. function:: which(cmd, mode=os.F_OK | os.X_OK, path=None)
|
||||||
|
|
||||||
|
|
|
@ -594,6 +594,10 @@ os.path
|
||||||
exactly one (back)slash to be absolute.
|
exactly one (back)slash to be absolute.
|
||||||
(Contributed by Barney Gale and Jon Foster in :gh:`44626`.)
|
(Contributed by Barney Gale and Jon Foster in :gh:`44626`.)
|
||||||
|
|
||||||
|
* Add support of *dir_fd* and *follow_symlinks* keyword arguments in
|
||||||
|
:func:`shutil.chown`.
|
||||||
|
(Contributed by Berker Peksag and Tahia K in :gh:`62308`)
|
||||||
|
|
||||||
pathlib
|
pathlib
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -1442,11 +1442,18 @@ elif _WINDOWS:
|
||||||
return _ntuple_diskusage(total, used, free)
|
return _ntuple_diskusage(total, used, free)
|
||||||
|
|
||||||
|
|
||||||
def chown(path, user=None, group=None):
|
def chown(path, user=None, group=None, *, dir_fd=None, follow_symlinks=True):
|
||||||
"""Change owner user and group of the given path.
|
"""Change owner user and group of the given path.
|
||||||
|
|
||||||
user and group can be the uid/gid or the user/group names, and in that case,
|
user and group can be the uid/gid or the user/group names, and in that case,
|
||||||
they are converted to their respective uid/gid.
|
they are converted to their respective uid/gid.
|
||||||
|
|
||||||
|
If dir_fd is set, it should be an open file descriptor to the directory to
|
||||||
|
be used as the root of *path* if it is relative.
|
||||||
|
|
||||||
|
If follow_symlinks is set to False and the last element of the path is a
|
||||||
|
symbolic link, chown will modify the link itself and not the file being
|
||||||
|
referenced by the link.
|
||||||
"""
|
"""
|
||||||
sys.audit('shutil.chown', path, user, group)
|
sys.audit('shutil.chown', path, user, group)
|
||||||
|
|
||||||
|
@ -1472,7 +1479,8 @@ def chown(path, user=None, group=None):
|
||||||
if _group is None:
|
if _group is None:
|
||||||
raise LookupError("no such group: {!r}".format(group))
|
raise LookupError("no such group: {!r}".format(group))
|
||||||
|
|
||||||
os.chown(path, _user, _group)
|
os.chown(path, _user, _group, dir_fd=dir_fd,
|
||||||
|
follow_symlinks=follow_symlinks)
|
||||||
|
|
||||||
def get_terminal_size(fallback=(80, 24)):
|
def get_terminal_size(fallback=(80, 24)):
|
||||||
"""Get the size of the terminal window.
|
"""Get the size of the terminal window.
|
||||||
|
|
|
@ -2212,7 +2212,9 @@ class TestMisc(BaseTest, unittest.TestCase):
|
||||||
def test_chown(self):
|
def test_chown(self):
|
||||||
dirname = self.mkdtemp()
|
dirname = self.mkdtemp()
|
||||||
filename = tempfile.mktemp(dir=dirname)
|
filename = tempfile.mktemp(dir=dirname)
|
||||||
|
linkname = os.path.join(dirname, "chown_link")
|
||||||
write_file(filename, 'testing chown function')
|
write_file(filename, 'testing chown function')
|
||||||
|
os.symlink(filename, linkname)
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
shutil.chown(filename)
|
shutil.chown(filename)
|
||||||
|
@ -2233,7 +2235,7 @@ class TestMisc(BaseTest, unittest.TestCase):
|
||||||
gid = os.getgid()
|
gid = os.getgid()
|
||||||
|
|
||||||
def check_chown(path, uid=None, gid=None):
|
def check_chown(path, uid=None, gid=None):
|
||||||
s = os.stat(filename)
|
s = os.stat(path)
|
||||||
if uid is not None:
|
if uid is not None:
|
||||||
self.assertEqual(uid, s.st_uid)
|
self.assertEqual(uid, s.st_uid)
|
||||||
if gid is not None:
|
if gid is not None:
|
||||||
|
@ -2269,6 +2271,36 @@ class TestMisc(BaseTest, unittest.TestCase):
|
||||||
shutil.chown(dirname, user, group)
|
shutil.chown(dirname, user, group)
|
||||||
check_chown(dirname, uid, gid)
|
check_chown(dirname, uid, gid)
|
||||||
|
|
||||||
|
dirfd = os.open(dirname, os.O_RDONLY)
|
||||||
|
self.addCleanup(os.close, dirfd)
|
||||||
|
basename = os.path.basename(filename)
|
||||||
|
baselinkname = os.path.basename(linkname)
|
||||||
|
shutil.chown(basename, uid, gid, dir_fd=dirfd)
|
||||||
|
check_chown(filename, uid, gid)
|
||||||
|
shutil.chown(basename, uid, dir_fd=dirfd)
|
||||||
|
check_chown(filename, uid)
|
||||||
|
shutil.chown(basename, group=gid, dir_fd=dirfd)
|
||||||
|
check_chown(filename, gid=gid)
|
||||||
|
shutil.chown(basename, uid, gid, dir_fd=dirfd, follow_symlinks=True)
|
||||||
|
check_chown(filename, uid, gid)
|
||||||
|
shutil.chown(basename, uid, gid, dir_fd=dirfd, follow_symlinks=False)
|
||||||
|
check_chown(filename, uid, gid)
|
||||||
|
shutil.chown(linkname, uid, follow_symlinks=True)
|
||||||
|
check_chown(filename, uid)
|
||||||
|
shutil.chown(baselinkname, group=gid, dir_fd=dirfd, follow_symlinks=False)
|
||||||
|
check_chown(filename, gid=gid)
|
||||||
|
shutil.chown(baselinkname, uid, gid, dir_fd=dirfd, follow_symlinks=True)
|
||||||
|
check_chown(filename, uid, gid)
|
||||||
|
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
shutil.chown(filename, uid, dir_fd=dirname)
|
||||||
|
|
||||||
|
with self.assertRaises(FileNotFoundError):
|
||||||
|
shutil.chown('missingfile', uid, gid, dir_fd=dirfd)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
shutil.chown(filename, dir_fd=dirfd)
|
||||||
|
|
||||||
|
|
||||||
@support.requires_subprocess()
|
@support.requires_subprocess()
|
||||||
class TestWhich(BaseTest, unittest.TestCase):
|
class TestWhich(BaseTest, unittest.TestCase):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
:func:`shutil.chown` now supports *dir_fd* and *follow_symlinks* keyword arguments.
|
Loading…
Reference in New Issue