[MERGE] Support FTP servers with non-atomic rename (bug #89436)
John Arbash Meinel
john at arbash-meinel.com
Mon Apr 16 21:04:30 BST 2007
Aaron Bentley wrote:
> John Arbash Meinel wrote:
...
>> So I'm +1 on the update to FTP. I'm at least -0 on the change to
>> fancy_rename. Because I think you are failing when you don't have to.
>
> I changed fancy_rename so that the FTP tests would pass. I cannot make
> the FTP change without either fixing fancy_rename or disabling
> test_rename_dir_nonempty, and the latter seems unwise.
>
> Aaron
FTPTransport.rename() should not be using 'fancy_rename'.
FTPTransport.move() should.
I guess I was mistaken in which functions you were changing. I would not
use "fancy_rename" for directories, and I certainly would avoid it in
'def rename()'.
The specific docstrings are:
def rename(self, rel_from, rel_to):
"""Rename a file or directory.
This *must* fail if the destination is a nonempty directory - it must
not automatically remove it. It should raise DirectoryNotEmpty, or
some other PathError if the case can't be specifically detected.
If the destination is an empty directory or a file this function may
either fail or succeed, depending on the underlying transport. It
should not attempt to remove the destination if overwriting is not the
native transport behaviour. If at all possible the transport should
ensure that the rename either completes or not, without leaving the
destination deleted and the new file not moved in place.
This is intended mainly for use in implementing LockDir.
"""
def move(self, rel_from, rel_to):
"""Move the item at rel_from to the location at rel_to.
The destination is deleted if possible, even if it's a non-empty
directory tree.
If a transport can directly implement this it is suggested that
it do so for efficiency.
"""
So "Transport.rename()" translates to os.rename() on all platforms.
(Since it is defined to fail for non-empty directories, and is likely to
fail for existing target files on some platforms.)
Transport.move() is defined to have POSIX file rename semantics. So it
will overwrite an existing file.
So your change should have been to FtpTransport.move()
which is what:
https://bugs.launchpad.net/bzr/+bug/89436
was actually talking about.
It is unfortunate that we have 2 similar functions (move() and rename())
that have slightly different behavior. But it is specifically because we
need "rename-over-the-top" for files (we call that move()) and we don't
want it for directories (we call that rename()).
Arguably they could be called:
rename_with_overwrite()
and
rename_no_replace()
Or something like that to make it more clear.
John
=:->
More information about the bazaar
mailing list