Occasional OSError: [Errno 13] Permission denied on Windows

Tim Peters tim.peters at gmail.com
Thu Jan 5 17:17:57 CET 2006

[Alec Wysoker]
> Using Python 2.3.5 on Windows XP, I occasionally get OSError: [Errno
> 13] Permission denied when calling os.remove().  This can occur with a
> file that is not used by any other process on the machine,

How do you know that?

> and is created by the python.exe invocation that is trying to delete it.  It
> can happen with various pieces of my system - almost anywhere I try to
> delete a file.
> I have assumed that the problem is that I was holding on to a handle to
> the file that I was trying to remove.  I have scoured my code and close
> any handle to the file that I can find.  The intermittent nature of
> this problem leads me to believe that I'm not explicitly holding onto a
> file object somewhere.
> My next theory was that there was some object holding onto a file
> handle for which there wasn't an extant reference, but which hadn't
> been garbage-collected.  So, I tried removing files like this:
>         try:
>             os.remove(strPath)
>         except OSError:
>             # Wild guess that garbage collection might clear errno 13
>             gc.collect()
>             os.remove(strPath)
> This does indeed reduce the frequency of the problem, but it doesn't
> make it go away completely.

Replace gc.collect() there with a short sleep (say, time.sleep(0.2)),
and see whether that does just as well at reducing the frequency of
the problem.  My bet is that it will.

Best guess is that some process you haven't thought about yet _is_
opening the file.  For example, what you're seeing is common if
Copernic Desktop Search is installed and its "Index new and modified
files on the fly" option is enabled.  Other searching/indexing apps,
"file deletion recovery" services, and even some virus scanners can
have similar effects.  That's why I asked at the start how you _know_
no other process is opening the file.  The symtoms you describe are
consistent with some background-level utility app/service briefly
opening files for its own purposes.

In that case, anything that burns some time and tries again will work
better.  Replacing gc.collect() with time.sleep() is an easy way to
test that hypothesis; because gc.collect() does an all-generations
collection, it can consume measurable time.

More information about the Python-list mailing list