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

Anders Hovmöller boxed at killingar.net
Mon May 13 14:23:34 EDT 2019



> On 13 May 2019, at 19:38, Steven D'Aprano <steve at pearwood.info> wrote:
> 
>> On Mon, May 13, 2019 at 12:31:08PM +0200, Anders Hovmöller wrote:
>> 
>> 
>>> On 13 May 2019, at 11:38, Tom Hale <tom at hale.ee> wrote:
>>> 
>>> * os.symlink() - the new link name is expected to NOT exist
>>> * shutil.symlink() - the new symlink replaces an existing file
>> 
>> This seems error prone to me. There is nothing about those names that 
>> hint at the difference in behavior. 
> 
> One of them is in the `os` module, and therefore we should expect that 
> it will be a thin wrapper around the OS functionality.
> 
> The other is in the `shutil` module, and therefore we should expect that 
> it will be a shell utility function of arbitrary complexity.
> 
> Being found in different modules should always be treated as a sign that 
> the functions may be different. (If they're the same, why do we need 
> both?)

Assuming all users know there is another. And if you "from x import y" the call site is identical for the two different functions. This is just asking for trouble. 

> 
>> An optional "overwrite_if_exists=False" flag seems much nicer.
> 
> Aside from the argument name being too verbose, that violates the rule 
> of thumb "avoid constant bool flags" design principle.

Verbose is better than cryptic. Having the exact same name as something that does something else is pretty cryptic. 


> (Note that this is a *rule of thumb*, not a hard law: there are times 
> that it can and should be violated; its also not a well-known principle 
> and so lots of APIs violate it even when they shouldn't.)
> 
> If you have a function which takes a boolean argument to swap between 
> two different modes, and the usual calling pattern is to pass a 
> constant:
> 
>    function(arg, x, y, flag=True)
> 
> rather than a flag which is not know until runtime, then it is (usually) 
> better to use two distinct functions rather than one function with a 
> parameter that swaps modes.

OK. Then a different name seems also to be in order. symlink/setsymlink seems a lot better to me for example. 

/ Anders 


More information about the Python-ideas mailing list