[Python-ideas] shutil.symlink to allow non-race replacement of existing link targets

Steven D'Aprano steve at pearwood.info
Mon May 13 23:16:49 EDT 2019


On Tue, May 14, 2019 at 11:43:32AM +0900, Stephen J. Turnbull wrote:

[...]
>  > Isn't the fact that they live in *different modules* obvious
>  > enough?
> 
> Please, Steve, you didn't need to go there.
> 
> Because it's not enough.  

Of course it is enough to presume that if they come from different 
modules, they are probably different unless proven otherwise.

As I have shown (perhaps you stopped reading and didn't bother reading 
through the rest of my post) it is not uncommon for different namespaces 
to define radically different functions with the same name.


> It's not unheard of for modules to include
> functionality from other modules with "thin wrappers", merely to
> change the calling convention, or even just to avoid an import.  Even
> within the stdlib.

Um, yes? And how is that relevant? If there's a "thin wrapper" 
changing the calling convention, then the APIs are different 
and they are not the same. That supports my position: functions with the 
same name coming from different namespaces are likely to be different. 
Even if a few happen to be the same that doesn't justify *assuming* that 
all such functions will be the same.

If they're just an import, then *unless documented otherwise* they are 
considered an implementation detail not a public part of the API.


> The point is that subtle issues like the presence
> or absence of race conditions require careful reading of the
> documentation, when some of said documentation may not even be in
> Python in the case of modules like os.

Lack of documentation means we should fix the documentation.


> If one of these has a race condition and the other doesn't, I think it
> would be reasonable for the documentation of the racy one to
> acknowledge the bug and point to the non-racy one.

I don't think you have understood the issue here. Perhaps you 
should re-read the original post in the thread.

There is no buggy existing version of symlink with a race condition. If 
the destination exists, os.symlink correctly does the right thing: it 
raises an error.

py> os.symlink('/tmp/spam', '/tmp/eggs')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileExistsError: [Errno 17] File exists: '/tmp/spam' -> '/tmp/eggs'

And there is currently no shutils version at all.

The problem is a lack of a symlink function that safely overwrites an 
existing file or symlink. We're just bike-shedding over its spelling 
and where it lives:

- modify os.symlink and give it a "force" parameter
- add a new function into shutils



-- 
Steven


More information about the Python-ideas mailing list