[Python-Dev] [Python-checkins] cpython: Issue #9993: When the source and destination are on different filesystems,

Hynek Schlawack hs at ox.cx
Sat Jan 7 17:11:19 CET 2012

Hi Nick,  

Am Samstag, 7. Januar 2012 um 14:22 schrieb Nick Coghlan:

> > http://hg.python.org/cpython/rev/1ea8b7233fd7
> > changeset: 74288:1ea8b7233fd7
> > user: Antoine Pitrou <solipsis at pitrou.net (mailto:solipsis at pitrou.net)>
> > date: Fri Jan 06 20:16:19 2012 +0100
> > summary:
> > Issue #9993: When the source and destination are on different filesystems,
> > and the source is a symlink, shutil.move() now recreates a symlink on the
> > destination instead of copying the file contents.
> > Patch by Jonathan Niehof and Hynek Schlawack.
> That seems like a fairly nasty backwards incompatibilty right there.
> While the old behaviour was different from mv, it was still perfectly
> well defined. Now, operations that used to work may fail - basically
> anything involving an absolute symlink will silently fail if being
> moved to removable media (it will create a symlink that is completely
> useless on the destination machine). Relative symlinks may or may not
> be broken depending on whether or not their target is *also* being
> copied to the destination media.

I had a look at it, the possible cases are as following:

1. we can just do a os.rename(): if src is a link it stays one
2. os.rename() fails, src is not a symlink but a directory: copytree() is used with symlinks=True, i.e. symlinks are preserved, no matter where they point to, i.e. this would clash with removable media as well.
3. os.rename() fails and src is a symlink. In both former cases, links were preserved. And the removable-media-argument is IMHO moot due to case 2.

If you want hardcore backwards compatibility, we could make the old behavior default and add some flag. But to be honest, the new approach seems more congruent to me.  
> The new help text also doesn't say what will happen if the destination
> doesn't even *support* symlinks (as is quite likely in the removable
> media case).

A clarification might be appropriate. Maybe even a direct warning, that in such cases the usage of copytree(…, symlinks=False) might be a better idea?

But the more I think about it, the more it's my impression, that symlink problems aren't really our problems as they go through all possible layers and it's next to impossible to catch all edge cases in library code. Therefore I'd say it's best just to behave like UNIX tools (please note I'm not defensive here, I've just fixed the tests+docs :)).


More information about the Python-Dev mailing list