Skip to main content

How to Recursively Delete Directories in Python

Recursively deleting a directory (removing the directory and all of its contents, including subdirectories and files) is a powerful, but potentially dangerous operation.

This guide explains how to safely and correctly delete directories recursively in Python using shutil.rmtree() and pathlib, covering error handling and best practices.

The shutil.rmtree() function from the shutil module is the standard and safest way to recursively delete a directory and its contents in Python.

import shutil
import os

path_to_directory = './my-directory'

# Check if the directory exists before attempting to delete.
if os.path.isdir(path_to_directory):
shutil.rmtree(path_to_directory)
print('Directory deleted successfully')
else:
print('The specified directory does NOT exist')

# The directory should no longer exist. Verify.
print(os.path.isdir(path_to_directory)) # Output: False
  • shutil.rmtree(path_to_directory): This line performs the recursive deletion.
  • Important: Always ensure that path_to_directory actually points to a directory (and not a symbolic link to a directory) before calling rmtree().
  • The os.path.isdir() checks if the directory exists.
  • Relative vs. Absolute Paths: You can use both relative paths (like ./my-directory) and absolute paths (like /home/user/my-directory or C:\\Users\\user\\my-directory).

Handling Errors with ignore_errors=True

Sometimes, files within the directory might be read-only, or you might not have sufficient permissions to delete everything. The ignore_errors=True argument tells rmtree() to skip over these errors and continue deleting as much as possible:

import shutil
import os

path_to_directory = './my-directory'

shutil.rmtree(path_to_directory, ignore_errors=True)
print(os.path.isdir(path_to_directory)) # Check if directory exists.
  • This example uses the ignore_errors=True which will skip the errors.

Handling Errors with onerror

You can also handle the errors by providing the onerror argument:

import shutil
import os

path_to_directory = './my-directory'

def handle_error(function, path, excinfo):
print('function', function)
print('path: ', path)
print('exception info: ', excinfo)


shutil.rmtree(path_to_directory, onerror=handle_error)
  • The onerror argument accepts a function that takes three arguments: the function that raised the exception, the path and the exception.

Handling Errors with try/except

You can use try/except blocks to handle exceptions during the deletion:

import shutil
import os

path_to_directory = './my-directory'
try:
shutil.rmtree(path_to_directory)
print('Recursively deleted directory')
except Exception as e:
print('Exception: ', e)
  • The shutil.rmtree function might raise an OSError, or FileNotFoundError so you can handle them using a try/except block.

Checking for Existence Before Deletion

It's a good practice to check if the directory exists before attempting to delete it, as attempting to delete a non-existent directory will raise an exception:

import shutil
import os

path_to_directory = './my-directory'

if os.path.isdir(path_to_directory):
shutil.rmtree(path_to_directory)
print('Directory deleted successfully')
else:
print('The specified directory does NOT exist')

print(os.path.isdir(path_to_directory)) # Check again to verify deletion.

Using pathlib (Recursive Deletion)

The pathlib module offers an object-oriented way to interact with the file system. While pathlib has rmdir(), it only works on empty directories. To recursively delete, you need to iterate and delete contents first. This approach is more complex than shutil.rmtree() and provides no real benefit for this specific task, so shutil.rmtree() is still recommended.

from pathlib import Path

def recursively_remove_dir(dir_path):
directory = Path(dir_path)
for item in directory.iterdir():
if item.is_dir():
recursively_remove_dir(item) # Recursive call for subdirectories
else:
item.unlink() # Delete files
directory.rmdir() # Delete the (now empty) directory
print(f'Recursively deleted directory {dir_path}')

path_to_directory = './my-directory'
recursively_remove_dir(path_to_directory)
  • The code creates a Path object and iterates over the directory's subdirectories and files.
  • If an item is a directory, it makes a recursive call.
  • If a file is found, it is removed using unlink().
  • After iterating over all files and subdirectories the root directory is removed using rmdir().