Path.chmod
chmod(0o755) sets the full mode; to add or remove one bit, read st_mode first and combine with the stat constants. Permissions are an OS feature: on Windows chmod can only toggle read-only (the write bits), everything else is ignored.
Common call
p.chmod(p.stat().st_mode | stat.S_IXUSR)
Returns
None
Replaces
os.chmod(p, mode)
Watch out
Write mode numbers in octal: 0o644, not 644
Path.chmod(modemode — Permission bits, usually an octal literal (0o644) or stat.S_* flags OR-ed together.type: int · required, *, follow_symlinksfollow_symlinks — chmod only (3.10+): False changes the link itself — the same as lchmod(), and not supported on every platform.type: bool · default: True=True) / .lchmod(mode)
→ None
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| mode | int | yes | Permission bits, usually an octal literal (0o644) or stat.S_* flags OR-ed together. |
| follow_symlinks | bool | no (True) | chmod only (3.10+): False changes the link itself — the same as lchmod(), and not supported on every platform. |
Return value
None — Changes the file in place.
Common patterns
Make a script executable (POSIX)
Add the execute bits to the current mode.
import stat from pathlib import Path p = Path('deploy.sh') p.chmod(p.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
Private file (owner read/write only)
Typical for keys and tokens on POSIX.
from pathlib import Path Path('secret.key').chmod(0o600)
Make a file read-only (works on Windows too)
Removing all write bits sets the read-only attribute on Windows.
import stat from pathlib import Path p = Path('frozen.txt') p.chmod(p.stat().st_mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
Examples
1. Remove the write permission
import stat
from pathlib import Path
p = Path('ro.txt')
p.touch()
p.chmod(0o444)
writable = bool(p.stat().st_mode & stat.S_IWUSR)
p.chmod(0o644)
writable
Returns
False2. Give it back
import stat
from pathlib import Path
p = Path('rw.txt')
p.touch()
p.chmod(0o444)
p.chmod(0o644)
bool(p.stat().st_mode & stat.S_IWUSR)
Returns
True3. Octal vs decimal
(0o644, 644 == 0o644)
Returns
(420, False)4. Readable as a permission string
import stat
from pathlib import Path
Path('d').mkdir()
stat.filemode(Path('d').stat().st_mode)[0]
Returns
'd'5. Missing file
from pathlib import Path
try:
Path('ghost').chmod(0o644)
except OSError as e:
result = type(e).__name__
result
Returns
'FileNotFoundError'Pitfalls
1. Writing the mode in decimal
644 is a decimal number (0o1204) and sets strange bits. Permission masks are octal.
644
oct(644)
'0o1204'
0o644
oct(0o644)
'0o644'
2. Replacing the mode when you meant to add a bit
chmod sets the complete mode. Read st_mode and OR in the new bit to keep the others.
set only S_IRUSR
import stat from pathlib import Path p = Path('f') p.touch() p.chmod(stat.S_IRUSR) writable = bool(p.stat().st_mode & stat.S_IWUSR) p.chmod(0o644) writable
False
combine with st_mode
import stat from pathlib import Path p = Path('f') p.touch() p.chmod(p.stat().st_mode | stat.S_IRUSR) bool(p.stat().st_mode & stat.S_IWUSR)
True
When to use
Use it
- Making scripts executable, keys private, files read-only
Reach for something else
- Windows ACLs → not reachable through chmod (use icacls or pywin32)
- Changing owner → os.chown / shutil.chown (POSIX)
Notes
CPython impl
Path.chmod is os.chmod(self, mode, follow_symlinks=…) (Lib/pathlib/_local.py); lchmod is PathBase.lchmod = chmod(mode, follow_symlinks=False)
Windows
Only the read-only attribute is affected (write bits on/off); execute and group/other bits are ignored
lchmod
Changing a symlink's own mode is not supported on every OS; where it is not, the call raises instead of silently changing the target
FAQ
p.chmod(p.stat().st_mode | stat.S_IXUSR) adds the owner execute bit on Linux and macOS. Windows has no execute bit; it decides by file extension.