Python Forum
deleting an empty Dir, using pathlib.Path
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
deleting an empty Dir, using pathlib.Path
#1
Greetings!
I'm trying to use pathlib.Path to identify empty Subdirectories (and delete them).

For some reason, my code cannot identify if a Subdir is empty.
3 of 4 Subdirectories have a small text file inside but all 3 identified as Empty.
mydir = 'C:\\02'
for fel in pathlib.Path(mydir).iterdir():
    if fel.is_dir():
        print(f"{fel} is a Directory")
        p = pathlib.Path(fel)
        stat = p.stat().st_size
        print(f" Size = {stat}")
I tried adding IF but it did not do anygood...

mydir = 'C:\\02'
for fel in pathlib.Path(mydir).iterdir():
    if fel.is_dir():
        print(f"{fel} is a Directory")
        p = pathlib.Path(fel)
        stat = p.stat().st_size
        print(f" Size = {stat}")
        if stat == 0 :
            print(f" Empty Dir --> {stat}")  
Thank you.
Reply
#2
A directory in a filesystem may have no relationship between the number of entries inside and the "size" returned by stat. To find if a directory is empty, I would suggest one of:
  • get the contents and see if it is empty (os.listdir, os.scandir, Path.iterdir)
  • just call os.rmdir() on all of the directories, and ignore the errors. If its empty, it will be removed. If it's not empty, it won't.

Maybe:
if fel.is_dir():
    if not any(fel.iterdir()):
        fel.rmdir()
Or:
if fel.is_dir():
    try:
        fel.rmdir()
    except OSError:
        pass
tester_V likes this post
Reply
#3
Sure I can do this by using
 os.listdir
or
os.path 
.
I was thinking if it is possible to do this with
pathlib.Path 


Thank you.
Reply
#4
(Jul-01-2021, 12:03 AM)tester_V Wrote: I was thinking if it is possible to do this with
pathlib.Path 

Path doesn't have a specific "is the directory empty?" method. The simple way would be to call any(fel.iterdir()). True if it has any contents, False if it doesn't.
Reply
#5
Actually, I came up with a mix of
pathlib.Path
and
os.listdir
it works fine but I'm not sure if it is the right way, the Python way...
mydir = 'C:\\02'
for fel in pathlib.Path(mydir).iterdir():
    if fel.is_dir():
        print(f"{fel} is a Directory")
        sub_dir= os.listdir(fel) 
        if len(sub_dir) == 0: 
            print(f" Empty directory --{fel}")  
Thank you.
Reply
#6
Any reason you're using Path semantics for getting the items in C:\\02, but you're using the os module for later? Seems like you'd do one or the other throughout your function.

Sorry, I changed my little code that I had earlier. You might have seen it before I did so. If I were to modify yours to use Path semantics throughout, I would do:

mydir = 'C:\\02'
for fel in pathlib.Path(mydir).iterdir():
    if fel.is_dir():
        print(f"{fel} is a Directory")
        if not any(fel.iterdir()):
            print(f" Empty directory --{fel}")
            # fel.rmdir() # uncomment to actually remove the directory        
tester_V likes this post
Reply
#7
I like your code, it is cleaner!
I wanted to use 'pathlib.Path' only but I could not make it work.
I mixed it...
I thought it does not matter if I use both 'os.listdir' and 'pathlib.Path' as soon as it works.

This is the whole snippet I came up with, but your is shorter and better for sure...

mydir = 'C:\\02'
for fel in pathlib.Path(mydir).iterdir():
    if fel.is_dir():
        print(f"{fel} is a Directory")
        sub_dir= os.listdir(fel) 
        if len(sub_dir) == 0: 
            print(f" Empty directory --{fel}")  
            rm_dr = pathlib.Path(fel)
            print(f" Directory to Remove --> {rm_dr}")
            rm_dr.rmdir()  
Thank you!
Reply
#8
Please, note, canonical way to process files/directories - i.e. create, delete, rename, move, etc. is to try to perform the desired action and handle the error [if any] accordingly. This way you avoid race condition that different process/thread/user make your check obsolete, e.g. you may check that folder is empty, but before you try to delete it, some other process may create a file in it or delete or rename it, etc.
tester_V likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#9
(Jul-01-2021, 12:29 AM)tester_V Wrote: I thought it does not matter if I use both 'os.listdir' and 'pathlib.Path' as soon as it works.

This is the whole snippet I came up with, but your is shorter and better for sure...
This will not check all sub folder has do it recursively in pathlib can use Path.rglob()
If do this with OS module then the have to us os.walk(),as os.listdir is not recursive.
Example now will print all empty folders paths,if uncomment will delete them.
from pathlib import Path

def is_empty(folder: Path) -> bool:
    return not any(folder.iterdir())

def check_dir(path: str) -> Path:
    for p in Path(path).rglob('*'):
        if p.is_dir and not p.is_file():
            if is_empty(p):
                print(p)
                #p.rmdir()

if __name__ == '__main__':
    path = 'G:/div_code/2'
    check_dir(path)
Also if want delete a folder completely with sub-folders and files,then can use shutil.rmtree.

What buran talk about is to try p.rmdir() and catch error it gives(OSError).
bowlofred did also show this as alterative.
Now will only delete empty folders,can eg print none empty folders or pass out,give message of choice.
from pathlib import Path

def is_empty(folder: Path) -> bool:
    return not any(folder.iterdir())

def check_dir(path: str) -> Path:
    for p in Path(path).rglob('*'):
        try:
            p.rmdir()
        except OSError:
            # Not empty folders
            print(p)

if __name__ == '__main__':
    path = 'G:/div_code/2'
    check_dir(path)
Output:
G:\div_code\2\foo G:\div_code\2\Ny mappe G:\div_code\2\foo\Articles.csv G:\div_code\2\Ny mappe\Nytt tekstdokument.txt
tester_V likes this post
Reply
#10
I suggest this
import os

def bool_dir(path):
    """Convert directory to bool. A directory is False iff it is empty.

    Raise OSError if path is not a directory."""
    with os.scandir(path) as it:
        return bool(next(it, False))
tester_V likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  -i option changes sys.path (removes leading empty string '') markanth 6 1,973 Aug-26-2022, 09:27 PM
Last Post: markanth
  Pathlib import not working chriswrcg 9 3,661 May-29-2022, 07:37 PM
Last Post: snippsat
  WebDriverException: Message: 'PATH TO CHROME DRIVER' executable needs to be in PATH Led_Zeppelin 1 2,198 Sep-09-2021, 01:25 PM
Last Post: Yoriz
  Trying to pathlib instead of os.path tester_V 4 2,472 Jun-22-2021, 04:15 AM
Last Post: tester_V
  pathlib destpath.exists() true even file does not exist NaN 9 4,653 Dec-01-2020, 12:43 PM
Last Post: NaN
  Question about if with () or without () / pathlib Tecuma 3 2,201 Apr-02-2020, 10:02 AM
Last Post: Tecuma
  pathlib hanging bluefrog 2 3,113 Sep-25-2018, 12:59 PM
Last Post: volcano63
  pathlib: resolving a path that does not exist Skaperen 6 5,474 Sep-08-2018, 12:25 AM
Last Post: Skaperen
  makin hardlinks with pathlib.Path Skaperen 2 5,218 Sep-06-2018, 07:53 AM
Last Post: scidam
  Need help using pathlib to read text file into dictionary gwilli3 4 4,177 Aug-13-2018, 06:21 PM
Last Post: gwilli3

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020