[Python-ideas] shutil.symlink to allow non-race replacement of existing link targets
Steven D'Aprano
steve at pearwood.info
Mon May 13 21:33:09 EDT 2019
On Tue, May 14, 2019 at 12:22:05AM +0300, Serge Matveenko wrote:
> As a regular library user, I see and expect no obvious difference
> between `os.symlink` and `shutil.symlink`.
You "see ... no obvious difference" between two functions that live in
completely different modules?
Isn't the fact that they live in *different modules* obvious enough? If
os.symlink was exactly the same as shutil.symlink, we would not need
them both.
Do you also see and expect no obvious difference between list.remove and
os.remove? If so, today is your opportunity to learn something and
become a better programmer! *wink*
Modules and classes are both namespaces, and we have namespaces with
different names precisely so that they can do something different. This
is why math.sqrt and cmath.sqrt are different:
py> math.sqrt(-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
py> cmath.sqrt(-2)
1.4142135623730951j
This is why *all of these* are different:
- os.open
- gzip.open
- bz2.open
- aifc.open
- shelve.open
- tokenize.open
- wave.open
- webbrowser.open
and none of those are the same as the builtin open.
A few more examples to prove this isn't an isolated thing:
* re.split, shlex.split and str.split
* dis.dis, pickletools.dis
* copy.copy, shutil.copy
The bottom line is that it is completely normal and not uncommon for
functions to be distinguished by the namespace they are found in. It is
both unreasonable and unnecessary to force objects in different
namespaces to have unique names.
> Probably they should have
> different names if the behavior is not the same.
The behaviour is broadly the same. They both create a symlink. Only the
fine details are different.
> As a constant Linux user, I'd expect a `symlink` function to do
> something similar to `ln -s` which also could be used as `ln -sf`. So,
> something like `symlink(force:bool=False)` looks like an expected and
> "guessable".
That's not an unreasonable suggestion. But the Windows mklink command
does not seem to take a "force" parameter:
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/mklink
so not so guessable to Windows users.
The ln command on my Linux system takes sixteen options, and we surely
don't expect to match all of them.
In my previous response, I already explained why constant bool
parameters were (often) an interface anti-pattern. I'm on the fence with
this one: I don't think that os.symlink(... force=False) is awful, but I
still prefer the more complex functionality to go into shutils and
leave the os version to be a thin wrapper around the basic OS
functionality.
If there's no consensus here, I guess the final decision will be that of
the person doing the work.
--
Steven
More information about the Python-ideas
mailing list