Complete guide to Python's os.removedirs function covering recursive directory removal, error handling, and practical examples.
Last modified April 11, 2025
This comprehensive guide explores Python’s os.removedirs function, which recursively removes empty directories. We’ll cover usage patterns, error handling, and practical directory cleanup examples.
The os.removedirs function removes directories recursively. It works from the leaf directory up to the root, removing empty parents.
Key behavior: removes leaf directory first, then empty parents up the path. Raises OSError if any directory in path is not empty or removal fails.
The simplest use of os.removedirs removes one empty directory. This behaves like os.rmdir but with the same error conditions.
remove_single_dir.py
import os
test_dir = “temp_dir” os.makedirs(test_dir, exist_ok=True)
try: os.removedirs(test_dir) print(f"Successfully removed {test_dir}") except OSError as e: print(f"Error removing {test_dir}: {e}")
if not os.path.exists(test_dir): print(f"{test_dir} no longer exists")
This example creates a temporary directory, removes it, and verifies success. The exist_ok=True prevents errors if the directory already exists.
Note that os.removedirs will fail if the directory contains files or subdirectories, unlike shutil.rmtree which forces deletion.
os.removedirs shines when removing nested empty directory trees. It automatically removes parent directories if they become empty.
remove_nested_dirs.py
import os
base_dir = “parent/child/grandchild” os.makedirs(base_dir)
try: os.removedirs(base_dir) print(f"Removed directory tree up from {base_dir}") except OSError as e: print(f"Error removing directories: {e}")
for dirpath in [“parent”, “parent/child”, base_dir]: exists = os.path.exists(dirpath) print(f"{dirpath} exists: {exists}")
This creates a three-level directory structure, then removes it completely. The function works from the grandchild up, removing each empty parent.
If any directory in the path contains other files, removal stops at that level. Only empty directories above the specified path will be removed.
When encountering non-empty directories, os.removedirs raises OSError. This example demonstrates proper error handling for such cases.
handle_non_empty.py
import os
dir_path = “test_dir” os.makedirs(dir_path, exist_ok=True) with open(os.path.join(dir_path, “file.txt”), “w”) as f: f.write(“test”)
try: os.removedirs(dir_path) except OSError as e: print(f"Failed to remove {dir_path}: {e}") print(“Directory is not empty”)
import shutil shutil.rmtree(dir_path) print(f"Forcefully removed {dir_path} with shutil.rmtree")
The first attempt fails because the directory contains a file. The example then shows using shutil.rmtree for forceful directory removal.
Always handle OSError when using os.removedirs as directory contents may change between checking and removal attempts.
os.removedirs works with relative paths, removing directories relative to the current working directory. This example demonstrates this.
relative_paths.py
import os
os.makedirs("./relative/path/to/dir", exist_ok=True)
original_dir = os.getcwd()
os.chdir("./relative/path")
try: os.removedirs(“to/dir”) print(“Removed relative path directories”) except OSError as e: print(f"Error: {e}")
os.chdir(original_dir)
print(f"Path exists: {os.path.exists(‘relative/path/to/dir’)}")
This shows how relative paths are interpreted based on current working directory. The function removes directories relative to the current path when called.
Be cautious with relative paths - the removal scope depends on current directory. Absolute paths are generally safer for predictable behavior.
os.removedirs stops removal when encountering a non-empty directory. This example shows how it preserves directories containing other files.
preserve_parents.py
import os
base_path = “preserve_test/a/b/c” os.makedirs(base_path)
with open(“preserve_test/a/important.txt”, “w”) as f: f.write(“don’t delete me”)
try: os.removedirs(base_path) print(“Full path removed”) except OSError as e: print(f"Partial removal: {e}")
for dirpath in [“preserve_test”, “preserve_test/a”, base_path]: exists = os.path.exists(dirpath) print(f"{dirpath} exists: {exists}")
The file in the ‘a’ directory prevents removal of that directory and its parents. Only the ‘b’ and ‘c’ directories (which become empty) are successfully removed.
This behavior makes os.removedirs safe for cleaning up empty directory trees without risking deletion of directories containing other files.
This example contrasts os.removedirs with similar directory removal functions, showing their different behaviors and use cases.
compare_removal.py
import os import shutil
os.makedirs(“compare_test/a/b/c”, exist_ok=True)
print(“Using os.rmdir (single directory):”) try: os.rmdir(“compare_test/a/b/c”) print(“Successfully removed leaf directory”) except OSError as e: print(f"Error: {e}")
print("\nUsing os.removedirs (recursive empty directories):") try: os.removedirs(“compare_test/a/b”) print(“Successfully removed empty tree”) except OSError as e: print(f"Error: {e}")
os.makedirs(“compare_test2/a/b/c”) with open(“compare_test2/a/file.txt”, “w”) as f: f.write(“test”)
print("\nUsing shutil.rmtree (forceful removal):") try: shutil.rmtree(“compare_test2”) print(“Forcefully removed entire tree”) except OSError as e: print(f"Error: {e}")
os.rmdir removes only the specified directory. os.removedirs removes empty parents. shutil.rmtree removes everything forcefully.
Choose the appropriate function based on whether you need safety, recursion, or unconditional removal in your specific use case.
Race conditions: Directory state may change between checks
Partial removal: Some directories may remain if not empty
Symbolic links: Behavior with symlinks varies by platform
Permissions: Requires write/execute permissions on parent dirs
Data loss: Only use for intended empty directory cleanup
Error handling: Always catch and handle OSError exceptions
Verification: Check directory emptiness before removal
Alternatives: Consider shutil.rmtree for non-empty dirs
Absolute paths: Prefer absolute paths for predictable behavior
Cleanup scripts: Ideal for temporary directory cleanup
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.