PathLib recursively remove directory?

44,015

Solution 1

As you already know, the only two Path methods for removing files/directories are .unlink() and .rmdir() and neither does what you want.

Pathlib is a module that provides object oriented paths across different OS's, it isn't meant to have lots of diverse methods.

The aim of this library is to provide a simple hierarchy of classes to handle filesystem paths and the common operations users do over them.

The "uncommon" file system alterations, such as recursively removing a directory, is stored in different modules. If you want to recursively remove a directory, you should use the shutil module. (It works with Path instances too!)

import shutil
import pathlib
import os  # for checking results

print(os.listdir())
# ["a_directory", "foo.py", ...]

path = pathlib.Path("a_directory")

shutil.rmtree(path)
print(os.listdir())
# ["foo.py", ...]

Solution 2

Here's a pure pathlib implementation:

from pathlib import Path


def rm_tree(pth):
    pth = Path(pth)
    for child in pth.glob('*'):
        if child.is_file():
            child.unlink()
        else:
            rm_tree(child)
    pth.rmdir()

Solution 3

Otherwise, you can try this one if you want only pathlib:

from pathlib import Path


def rm_tree(pth: Path):
    for child in pth.iterdir():
        if child.is_file():
            child.unlink()
        else:
            rm_tree(child)
    pth.rmdir()

rm_tree(your_path)

Solution 4

def rm_rf(basedir):
    if isinstance(basedir,str): basedir = pathlib.Path(basedir)
    if not basedir.is_dir(): return
    for p in reversed(list(basedir.rglob("*"))):
        if p.is_file(): p.unlink()
        elif p.is_dir(): p.rmdir()
    basedir.rmdir()

Solution 5

If you don't mind using a third-party library give path a try. Its API is similar to pathlib.Path, but provides some additional methods, including Path.rmtree() to recursively delete a directory tree.

Share:
44,015
Jasonca1
Author by

Jasonca1

Python developer that enjoys programming and learning new things.

Updated on July 08, 2022

Comments

  • Jasonca1
    Jasonca1 almost 2 years

    Is there any way to remove a directory and it’s contents in the PathLib module? With path.unlink() it only removes a file, with path.rmdir() the directory has to be empty. Is there no way to do it in one function call?

  • El Ruso
    El Ruso over 5 years
    just for mention, can be done this way -stackoverflow.com/a/49782093/4249707
  • Sebastian Werk
    Sebastian Werk about 5 years
    I still don’t get, why a recursive version is not part of pathlib.Path, when everything, what is needed is already there. I was really hoping, this confusing usage of os.path, os.mkdir, shutil, etc. would end with pathlib.
  • SwimBikeRun
    SwimBikeRun almost 5 years
    @SebastianWerk PR! PR! PR! -- although being in the stdlibrary it won't be out for a while sadly and would take a lot of effort to get in. I share your sentiments
  • Rami
    Rami over 4 years
    os is no more used following the suggestion of Anton.
  • Roger Dahl
    Roger Dahl about 3 years
    Is it safe to mutate the dir you're iterating over? Might have to extract the full results of the iterdir() to a list before starting to iterate.
  • Rami
    Rami about 3 years
    The recursive function will continue removing files (child.unlink()) until the directory is empty. Once empty, the directory is removed (pth.rmdir()).
  • user2846495
    user2846495 almost 3 years
    This would delete the contents of symlinked directories, I'd have thought?
  • djvg
    djvg over 2 years
    The unsafe version of shutil.rmtree does something similar (source), but it raises an OSError("Cannot call rmtree on a symbolic link") in case of symlinked dir.
  • Charlie Parker
    Charlie Parker about 2 years
    what is wrong with doing pth.rmdir() if pth is a Path obj compared to your answer?
  • Charlie Parker
    Charlie Parker about 2 years
    what is wrong with doing shutil.rmtree(path) compared to your answer?