10000 bpo-18108: Adding dir_fd and follow_symlinks keyword args to shutil.c… · python/cpython@8974a63 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8974a63

Browse files
ta1hiaserhiy-storchakaberkerpeksagzware
authored
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>
1 parent 78ba4cb commit 8974a63

File tree

5 files changed

+53
-4
lines changed

5 files changed

+53
-4
lines changed

Doc/library/shutil.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,8 @@ Directory and files operations
421421

422422
.. availability:: Unix, Windows.
423423

424-
.. function:: chown(path, user=None, group=None)
424+
.. function:: chown(path, user=None, group=None, *, dir_fd=None, \
425+
follow_symlinks=True)
425426

426427
Change owner *user* and/or *group* of the given *path*.
427428

@@ -436,6 +437,9 @@ Directory and files operations
436437

437438
.. versionadded:: 3.3
438439

440+
.. versionchanged:: 3.13
441+
Added *dir_fd* and *follow_symlinks* parameters.
442+
439443

440444
.. function:: which(cmd, mode=os.F_OK | os.X_OK, path=None)
441445

Doc/whatsnew/3.13.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,10 @@ os.path
594594
exactly one (back)slash to be absolute.
595595
(Contributed by Barney Gale and Jon Foster in :gh:`44626`.)
596596

597+
* Add support of *dir_fd* and *follow_symlinks* keyword arguments in
598+
:func:`shutil.chown`.
599+
(Contributed by Berker Peksag and Tahia K in :gh:`62308`)
600+
597601
pathlib
598602
-------
599603

Lib/shutil.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,11 +1442,18 @@ def disk_usage(path):
14421442
return _ntuple_diskusage(total, used, free)
14431443

14441444

1445-
def chown(path, user=None, group=None):
1445+
def chown(path, user=None, group=None, *, dir_fd=None, follow_symlinks=True):
14461446
"""Change owner user and group of the given path.
14471447
14481448
user and group can be the uid/gid or the user/group names, and in that case,
14491449
they are converted to their respective uid/gid.
1450+
1451+
If dir_fd is set, it should be an open file descriptor to the directory to
1452+
be used as the root of *path* if it is relative.
1453+
1454+
If follow_symlinks is set to False and the last element of the path is a
1455+
symbolic link, chown will modify the link itself and not the file being
1456+
referenced by the link.
14501457
"""
14511458
sys.audit('shutil.chown', path, user, group)
14521459

@@ -1472,7 +1479,8 @@ def chown(path, user=None, group=None):
14721479
if _group is None:
14731480
raise LookupError("no such group: {!r}".format(group))
14741481

1475-
os.chown(path, _user, _group)
1482+
os.chown(path, _user, _group, dir_fd=dir_fd,
1483+
follow_symlinks=follow_symlinks)
14761484

14771485
def get_terminal_size(fallback=(80, 24)):
14781486
"""Get the size of the terminal window.

Lib/test/test_shutil.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2212,7 +2212,9 @@ def test_disk_usage(self):
22122212
def test_chown(self):
22132213
dirname = self.mkdtemp()
22142214
filename = tempfile.mktemp(dir=dirname)
2215+
linkname = os.path.join(dirname, "chown_link")
22152216
write_file(filename, 'testing chown function')
2217+
os.symlink(filename, linkname)
22162218

22172219
with self.assertRaises(ValueError):
22182220
shutil.chown(filename)
@@ -2233,7 +2235,7 @@ def test_chown(self):
22332235
gid = os.getgid()
22342236

22352237
def check_chown(path, uid=None, gid=None):
2236-
s = os.stat(filename)
2238+
s = os.stat(path)
22372239
if uid is not None:
22382240
self.assertEqual(uid, s.st_uid)
22392241
if gid is not None:
@@ -2269,6 +2271,36 @@ def check_chown(path, uid=None, gid=None):
22692271
shutil.chown(dirname, user, group)
22702272
check_chown(dirname, uid, gid)
22712273

2274+
dirfd = os.open(dirname, os.O_RDONLY)
2275+
self.addCleanup(os.close, dirfd)
2276+
basename = os.path.basename(filename)
2277+
baselinkname = os.path.basename(linkname)
2278+
shutil.chown(basename, uid, gid, dir_fd=dirfd)
2279+
check_chown(filename, uid, gid)
2280+
shutil.chown(basename, uid, dir_fd=dirfd)
2281+
check_chown(filename, uid)
2282+
shutil.chown(basename, group=gid, dir_fd=dirfd)
2283+
check_chown(filename, gid=gid)
2284+
shutil.chown(basename, uid, gid, dir_fd=dirfd, follow_symlinks=True)
2285+
check_chown(filename, uid, gid)
2286+
shutil.chown(basename, uid, gid, dir_fd=dirfd, follow_symlinks=False)
2287+
check_chown(filename, uid, gid)
2288+
shutil.chown(linkname, uid, follow_symlinks=True)
2289+
check_chown(filename, uid)
2290+
shutil.chown(baselinkname, group=gid, dir_fd=dirfd, follow_symlinks=False)
2291+
check_chown(filename, gid=gid)
2292+
shutil.chown(baselinkname, uid, gid, dir_fd=dirfd, follow_symlinks=True)
2293+
check_chown(filename, uid, gid)
2294+
2295+
with self.assertRaises(TypeError):
2296+
shutil.chown(filename, uid, dir_fd=dirname)
2297+
2298+
with self.assertRaises(FileNotFoundError):
2299+
shutil.chown('missingfile', uid, gid, dir_fd=dirfd)
2300+
2301+
with self.assertRaises(ValueError):
2302+
shutil.chown(filename, dir_fd=dirfd)
2303+
22722304

22732305
@support.requires_subprocess()
22742306
class TestWhich(BaseTest, unittest.TestCase):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:func:`shutil.chown` now supports *dir_fd* and *follow_symlinks* keyword arguments.

0 commit comments

Comments
 (0)
0