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.
|
||||
|
||||
.. 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*.
|
||||
|
||||
|
@ -436,6 +437,9 @@ Directory and files operations
|
|||
|
||||
.. 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)
|
||||
|
||||
|
|
|
@ -594,6 +594,10 @@ os.path
|
|||
exactly one (back)slash to be absolute.
|
||||
(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
|
||||
-------
|
||||
|
||||
|
|
|
@ -1442,11 +1442,18 @@ elif _WINDOWS:
|
|||
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.
|
||||
|
||||
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.
|
||||
|
||||
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)
|
||||
|
||||
|
@ -1472,7 +1479,8 @@ def chown(path, user=None, group=None):
|
|||
if _group is None:
|
||||
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)):
|
||||
"""Get the size of the terminal window.
|
||||
|
|
|
@ -2212,7 +2212,9 @@ class TestMisc(BaseTest, unittest.TestCase):
|
|||
def test_chown(self):
|
||||
dirname = self.mkdtemp()
|
||||
filename = tempfile.mktemp(dir=dirname)
|
||||
linkname = os.path.join(dirname, "chown_link")
|
||||
write_file(filename, 'testing chown function')
|
||||
os.symlink(filename, linkname)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
shutil.chown(filename)
|
||||
|
@ -2233,7 +2235,7 @@ class TestMisc(BaseTest, unittest.TestCase):
|
|||
gid = os.getgid()
|
||||
|
||||
def check_chown(path, uid=None, gid=None):
|
||||
s = os.stat(filename)
|
||||
s = os.stat(path)
|
||||
if uid is not None:
|
||||
self.assertEqual(uid, s.st_uid)
|
||||
if gid is not None:
|
||||
|
@ -2269,6 +2271,36 @@ class TestMisc(BaseTest, unittest.TestCase):
|
|||
shutil.chown(dirname, user, group)
|
||||
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()
|
||||
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