Problems with os.scandir()

Hi,
I have a general problem with os.scandir() at least on a Windows system. I want to get the size of all directories in a given tree. I found the following proposal:

import os

def get_dir_size(path='.'):
    total = 0
    with os.scandir(path) as it:
        for entry in it:
            if entry.is_file():
                total += entry.stat().st_size
            elif entry.is_dir():
                total += get_dir_size(entry.path)
    return total

print(get_dir_size('J:\\'))

If my external disk - here J: - has a first-level-directory named “System Volume Information” or
“$RECYCLE.BIN” then I get an immediate windows error message:

PermissionError: [WinError 5] Permission denied

As almost all (or really all) external drives have such a directory, the os.scandir() function stops and throws the error. How can I fix it?
I would be happy excluding such system directories from the scan, but how can I do that?

Use a try/except block:

        try:
            for entry in it:
                if entry.is_file():
                    total += entry.stat().st_size
                elif entry.is_dir():
                    total += get_dir_size(entry.path)
        except PermissionError:
            continue

That will just ignore the error and continue on in the loop.

My program:

import os

def get_dir_size(path='.'):
    total = 0
    with os.scandir(path) as it:
        try:
            for entry in it:
                if entry.is_file():
                    total += entry.stat().st_size
                elif entry.is_dir():
                    total += get_dir_size(entry.path)
        except PermissionError:
            continue
        return total

print(get_dir_size('J:\\'))

has a simple syntax error now:

SyntaxError: 'continue' not properly in loop

As far as I remember “continue” works in while- or for-loops only.

Right. Which line is causing the error? If it’s the if entry.is_file() line move the try inside the for loop. If not you might need a while True and iterate manually with next.

It seems likely to be the scandir() call itself. A traceback would tell us.

I’d personally put the try/except around the internal get_dir_size()
call only and fake up a size of 0 for directories I couldn’t scan. With
a warning log message about that particular directory.