Question: I tried to use shutil to delete a directory and all contained files, as follows: import shutil from os.path import exists if exists(path_dir): shutil.rmtree(path_dir)  Unfortunately, my solution does not work, throwing the following error: FileNotFoundError: [Errno 2] No such file or directory: '._image1.jpg'  A quick search showed that I'm not alone in having this problem. In my understanding, the rmtree function is equivalent to the rm -Rf $DIR shell command - but this doesn't seem to be the case. p.s. for reconstruction purposes. Please create a symbolic link for example using ln -s /path/to/original /path/to/link

Answer: That is strange, I have no issues with shutil.rmtree() with or without symlink under the folder to be deleted, both in windows 10 and Ubuntu 20.04.2 LTS. Anyhow try the following code. I tried it in windows 10 and Ubuntu. from pathlib import Path import shutil def delete_dir_recursion(p): """ Delete folder, sub-folders and files. """ for f in p.glob('**/*'): if f.is_symlink(): f.unlink(missing_ok=True) # missing_ok is added in python 3.8 print(f'symlink {f.name} from path {f} was deleted') elif f.is_file(): f.unlink() print(f'file: {f.name} from path {f} was deleted') elif f.is_dir(): try: f.rmdir() # delete empty sub-folder print(f'folder: {f.name} from path {f} was deleted') except OSError: # sub-folder is not empty delete_dir_recursion(f) # recurse the current sub-folder except Exception as exception: # capture other exception print(f'exception name: {exception.__class__.__name__}') print(f'exception msg: {exception}') try: p.rmdir() # time to delete an empty folder print(f'folder: {p.name} from path {p} was deleted') except NotADirectoryError: p.unlink() # delete folder even if it is a symlink, linux print(f'symlink folder: {p.name} from path {p} was deleted') except Exception as exception: print(f'exception name: {exception.__class__.__name__}') print(f'exception msg: {exception}') def delete_dir(folder): p = Path(folder) if not p.exists(): print(f'The path {p} does not exists!') return # Attempt to delete the whole folder at once. try: shutil.rmtree(p) except Exception as exception: print(f'exception name: {exception.__class__.__name__}') print(f'exception msg: {exception}') # continue parsing the folder else: # else if no issues on rmtree() if not p.exists(): # verify print(f'folder {p} was successfully deleted by shutil.rmtree!') return print(f'Parse the folder {folder} ...') delete_dir_recursion(p) if not p.exists(): # verify print(f'folder {p} was successfully deleted!') # start folder_to_delete = '/home/zz/tmp/sample/b' # delete folder b delete_dir(folder_to_delete)  Sample output: We are going to delete the folder b. . ├── 1.txt ├── a ├── b │ ├── 1 │ ├── 1.txt -> ../1.txt │ ├── 2 │ │ └── 21 │ │ └── 21.txt │ ├── 3 │ │ └── 31 │ ├── 4 │ │ └── c -> ../../c │ ├── a -> ../a │ └── b.txt ├── c  Parse the folder /home/zz/tmp/sample/b ... symlink a from path /home/zz/tmp/sample/b/a was deleted symlink c from path /home/zz/tmp/sample/b/4/c was deleted folder: 4 from path /home/zz/tmp/sample/b/4 was deleted symlink 1.txt from path /home/zz/tmp/sample/b/1.txt was deleted file: b.txt from path /home/zz/tmp/sample/b/b.txt was deleted file: 21.txt from path /home/zz/tmp/sample/b/2/21/21.txt was deleted folder: 21 from path /home/zz/tmp/sample/b/2/21 was deleted folder: 2 from path /home/zz/tmp/sample/b/2 was deleted folder: 1 from path /home/zz/tmp/sample/b/1 was deleted folder: 31 from path /home/zz/tmp/sample/b/3/31 was deleted folder: 3 from path /home/zz/tmp/sample/b/3 was deleted folder: b from path /home/zz/tmp/sample/b was deleted folder /home/zz/tmp/sample/b was successfully deleted!