[Python-Dev] unifying os.rename semantics across platform

Guido van Rossum guido@digicool.com
Tue, 22 May 2001 19:46:53 -0400


> It was brought to my attention a week ago by a client that os.rename
> semantics differ between Unix and Windows.  On Unix, if the destination file
> already exists it is silently deleted.  On Windows, an exception is raised.
> I was able to verify this for Python 2.0 on Windows98.  I assume nothing
> changed for 2.1, but I can't verify that.

I've always known this, and assumed it was common knowledge.
Sorry. ;-)

> (Windows trashed my partition
> table and my Linux root partition while I was downloading 2.1.
> Consequently, I no longer run Windows.  Take that, Bill...)  I haven't
> checked the Mac yet (will do that when I get back to the US), but I think
> that os.rename should have the same semantics across all platforms.  To the
> extent reasonably possible, I think this should also be true of other common
> functions exposed through the os module.
> 
> On the (unsupportable) theory that to-date, more Python apps have been
> written and/or deployed on Unix-like systems and that where Windows apps are
> concerned, many developers will have added a thin wrapper to mimic the Unix
> semantics, I think less breakage would result if the Unix semantics were
> implemented in the Windows version.  It appears that is what POSIX
> compliance would demand as well.
> 
> Skip

I certainly wouldn't want to try to emulate the Windows semantics on
Unix.  However, I think that emulating the correct Posix semantics on
Windows is not possible either.  The Posix rename() call guarantees
that it is atomic: there is no point in time where the file doesn't
exist at all (and a system or program crash can't delete the file).  I
wouldn't know how to do that in Windows -- the straightforward version

    if os.path.exists(target):
        os.unlink(target)
    os.rename(source, target)

leaves a vulnerability open where the target doesn't exist and if at
that point the system crashes or the program is killed, you lose the
target.

I would prefer to document the difference so applications can decide
how to deal with this.

--Guido van Rossum (home page: http://www.python.org/~guido/)