Python pathlib Path().mkdir() applies desired mode to final directory, but mode-umask mode to parents - bug?
Asked Answered
S

1

5

I am using pathlib to set up a folder structure, for which I'd like permissions set to drwxrwx--- (770) for all folders in the tree.

My current code is:

p=Path('name/{}/{}/{}/category'.format(year,month,day))
pp=Path('name/{}/{}/{}'.format(year,month,day))
p.mkdir(mode=0o770,parents=True,exist_ok=True)

I need exist_ok=True as I want the same line to work as I loop through category values. However, while testing this I'm deleting the folders.

After running,

oct(p.stat().st_mode)
0o40770
oct(pp.stat().st_mode)
0o40775

i.e., the parent directories have default permissions of 777 (with umask=002).

The only way around this I can think of, which seems inefficient, is:

p.mkdir(mode=0o770,parents=True,exist_ok=True)
os.system("chmod -R 770 {}".format(name))

Is there a way to apply the desired permissions with the Path().mkdir() call, or is the os.system() call unavoidable?

Spinose answered 28/4, 2021 at 11:8 Comment(0)
K
6

The documentation for Path.mkdir mentions this behavior:

If parents is true, any missing parents of this path are created as needed; they are created with the default permissions without taking mode into account (mimicking the POSIX mkdir -p command).

One way to avoid this would be to iterate over each path's parts or parents yourself, calling mkdir with exists_ok but without parents on each. That way, the missing directories are still created, but the mode is taken into account. That would look something like:

for parent in reversed(p.parents):
    parent.mkdir(mode=0o770, exist_ok=True)
Keary answered 28/4, 2021 at 11:14 Comment(1)
Excellent! Requires an additional p.mkdir(mode=0o770,exist_ok=True), but I'm happy with that.Spinose

© 2022 - 2024 — McMap. All rights reserved.