os.makedirs
os.makedirs(path, exist_ok=True) is 'mkdir -p': it creates every missing level and is happy if the folder already exists. os.mkdir creates exactly one level and fails if the parent is missing or the name is taken. To delete, rmdir removes one empty folder and removedirs also prunes the parents that become empty.
Demo
import os for d in ['logs']: os.makedirs(d) try: os.mkdir('logs/2026') result = 'created' except OSError as e: result = type(e).__name__ result
mkdir fails with FileExistsError when the name is taken and FileNotFoundError when a parent is missing — makedirs creates the parents. Without exist_ok, makedirs also raises FileExistsError for an existing folder; with exist_ok=True the second call is silent. removedirs deletes a/b/c, then tries b, then a, and stops quietly at the first folder that is not empty (a still holds keep.txt). The class names are the same on every OS; the error messages differ ("[Errno 17] File exists" on Linux, "[WinError 183] …" on Windows).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | str | PathLike | yes | The folder to create (makedirs: with all its parents). |
| mode | int | no (0o777) | Permission bits, reduced by the umask. Since 3.7 makedirs applies it only to the last folder; parents get the default. |
| exist_ok | bool | no (False) | makedirs only: True means "no error if the folder already exists" — but a file of that name still raises FileExistsError. |
Return value
None — All four change the file system and return None, or raise an OSError subclass.
Common patterns
import os os.makedirs(os.path.join('out', 'reports'), exist_ok=True)
import os folder = os.path.dirname(target) if folder: os.makedirs(folder, exist_ok=True)
import os try: os.mkdir('lockdir') except FileExistsError: print('someone else is running')
import shutil shutil.rmtree('build', ignore_errors=True)
Examples
Pitfalls
import os open('output', 'w').close() try: os.makedirs('output', exist_ok=True) except OSError as e: result = type(e).__name__ result
import os open('output', 'w').close() if os.path.isfile('output'): os.replace('output', 'output.old') os.makedirs('output', exist_ok=True) os.path.isdir('output')
import os try: os.mkdir('a/b/c') except OSError as e: result = type(e).__name__ result
import os os.makedirs('a/b/c') os.path.isdir('a/b/c')
import os try: os.makedirs(os.path.dirname('report.txt'), exist_ok=True) except OSError as e: result = type(e).__name__ result
import os os.makedirs(os.path.dirname('report.txt') or '.', exist_ok=True) os.path.isdir('.')
When to use
- Making sure a folder exists before writing into it (makedirs, exist_ok=True)
- Atomically claiming a name (mkdir raises if it exists)
- Removing empty folders (rmdir, removedirs)
- Deleting non-empty folders → shutil.rmtree
- Temporary folders → tempfile.TemporaryDirectory / mkdtemp
- Object paths → Path.mkdir(parents=True, exist_ok=True)
Notes
FAQ
os.makedirs(path, exist_ok=True). It creates any missing parents too, and it avoids the race of checking os.path.exists first.