[Tutor] Delete directories recursively

Kent Johnson kent37 at tds.net
Fri Jun 16 20:04:26 CEST 2006


John Corry wrote:
> 
> Amresh,
>  
> I had this problem a few months back.  I approached it backwards.  Maybe 
> not the right way to do it.  I removed all the files and directories and 
> then had my exception handle the file if it was read only.  The 
> exception  handler changes the file from read-only to not read only and 
> then calls the function again. 
>  
> Is there a better way to do it?  Would appreciate feedback on the code 
> below.
>  
> import shutil
> import os
>  
> def zaps(self):
>      
>         try:
>             shutil.rmtree('f:/m2m')
>             
>                                
>         except OSError, inst:
>             print OSError
>             os.chmod(inst.filename, 0666)
>             self.zaps()

I imagine this could be expensive if you have a deep directory hierarchy 
with lots of read-only files - you have to start the traversal from 
scratch each time you get an error. If you have more than 1000 read-only 
files you will get a stack overflow from the recursion.

shutil.rmtree() actually takes an optional error handler argument. 
According to the docs, "If onerror is provided, it must be a callable 
that accepts three parameters: function, path, and excinfo. The first 
parameter, function, is the function which raised the exception; it will 
be os.listdir(), os.remove() or os.rmdir()."

So something like this should work and be faster because the directory 
traversal doesn't restart each time (UNTESTED!!):

def handle_error(fn, path, excinfo):
   if fn is os.rmdir:
     # handle readonly dir
     os.chmod(path, 0666) # ?? not sure if this is correct for a dir
     os.rmdir(path) # try again
   elif fn is os.remove:
     os.chmod(path, 0666)
     os.remove(path)

shutil.rmtree(top, onerror=handle_error)

Kent



More information about the Tutor mailing list