This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: os.symlink arg names are bad
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, eric.smith, krey, steven.daprano
Priority: normal Keywords:

Created on 2021-08-05 09:08 by krey, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (11)
msg398977 - (view) Author: krey (krey) Date: 2021-08-05 09:08
From: https://docs.python.org/3/library/os.html

os.symlink(src, dst, target_is_directory=False, *, dir_fd=None)

    Create a symbolic link pointing to `src` named `dst`.

It's a bit like saying

find(needle, haystack)

    Finds `haystack` in `needle`

If you look at the manpage ln, it says
ln [OPTION]... [-T] TARGET LINK_NAME

So os.symlink isn't consistent with ln
msg398980 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-08-05 09:28
There is nothing wrong with saying

    Create a symbolic link pointing to `src` named `dst`.

That is grammatically correct English.

We could say "create a sym link called dst pointing to src" but they mean exactly the same thing. And given that the order of parameters is src first and dst second, it makes more sense to keep the same order in the description.

Your analogy with

    Finds `haystack` in `needle`

is not correct. The analogy would be 


    find(needle, haystack)
    -> Finds `needle` in `haystack`
    -> or search haystack for needle

    os.symlink(src, dst)
    -> create symlink pointing to source called dst
    -> or create symlink called dst pointing to src


The order of arguments is the same as for ln:

    ln [OPTION]... [-T] TARGET LINK_NAME

TARGET is src, LINK_NAME is dst.


I don't think that there is anything needed to be done here.
msg398981 - (view) Author: krey (krey) Date: 2021-08-05 10:02
OK, let's ignore the analogy.

Everywhere else I've seen, arrows (or directed edges in a graph) point as
SOURCE -> TARGET
SOURCE -> DESTINATION
(TARGET and DESTINATION are synonymous in this context)
An example from math: https://en.wikipedia.org/wiki/Category_(mathematics)#Definition

ln has two arguments, LINKNAME and TARGET, so it's implied that
LINKNAME -> TARGET
In fact that's exactly what you see visually when you run ls -l

In os.symlink, however, you have
SRC <- DST
which is weird. I agree that this weirdness is explained in grammatically correct English.

Just because it's the first argument, we shouldn't call it src. The arg ordering is already confusing enough https://unix.stackexchange.com/questions/541795/tips-for-remembering-the-order-of-parameters-for-ln
msg398984 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-08-05 10:26
Order of arguments for ln:

    ln -s SOURCE DESTINATION

Order of arguments for os.symlink:

    os.symlink(SOURCE, DESTINATION)

They are exactly the same order.

> Everywhere else I've seen, arrows (or directed edges in a graph) point as
> SOURCE -> TARGET
> SOURCE -> DESTINATION

The source doesn't point to the symlink. The symlink points to the 
source.
msg398985 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-08-05 10:30
@krey: What's your suggested change? We can change neither the parameter order nor parameter names without breaking code, so that won't happen.

You created this as a documentation issue. Do you have a suggested documentation change?
msg398990 - (view) Author: krey (krey) Date: 2021-08-05 10:45
@eric.smith Sorry for tagging this as docs, wasn't sure what to pick. I guess it should be under Library 

Does CPython have a process for changing arg names via deprecation warnings?
msg398994 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-08-05 11:15
Yes, we have a process:

- At least one full release with a pending deprecation warning (silent 
  by default); 3.11 is the earliest that could take place.
- At least one full release with an active deprecation warning; 3.12 
  would be the earliest for this.
- Make the change. 3.13 would be the earliest for this.

If the change is particularly urgent, we could skip the pending warning 
and bring it forward one release, but since this isn't a critical 
security bug that needs immediate action, 3.12 would be the absolute 
earliest we could make this change.

But it is vanishingly unlikely that we would change either the names of 
the parameters, or their order, without a really good reason.

You haven't given us any convincing justification for why we should 
make this change. The os.symlink function takes its arguments in exactly 
the same order as `ln -s` takes them: original source file first, 
symbolic link destination second. We're not likely to change the order 
to be the opposite to that used by `ln`.

Different Unixes and Linuxes already use different argument names for 
`ln`, we're not obliged to match any of them. "src, dest" is fine.
msg398995 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-08-05 11:16
There's really no way we'd consider breaking possibly millions of working programs to change the parameter names. I guess you could come up with some way of supporting both sets of parameter names, but I doubt we'd accept that, either.

While maybe in hindsight we should have chosen the parameter names that "ln -s" uses, that ship has sailed, and we'll have to live with it like it is.
msg398998 - (view) Author: krey (krey) Date: 2021-08-05 12:00
@eric.smith Fair enough, though the impact would probably be quite low in reality. Nobody seems to pass these args by keyword: https://github.com/search?q=%22os.symlink(src%3D%22&type=Code

@steven.daprano My suggestion was changing the names of the args, not the order

Current
def os.symlink(src, dst):
    ln -s src dst

Changing the names
def os.symlink(dst, src):
    ln -s dst src

Changing the order
def os.symlink(dst, src):
    ln -s src dst

I concede that different unixes have different argnames for ln, it's a bit of a mess. From a CS theory perspective, I think the GNU convention makes more sense.
msg399000 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-08-05 12:14
There is no one single set of names used by `ln` that we could have 
chosen. Any choice we made would have annoyed some people.

I strongly argue that, of all the various naming conventions in common 
usage (see below), Python's choice of src, dest (source, destination) is 
the most clear and understandable. Source is the source file, the 
original file. When a symlink is made, it gets written to the 
destination path, dest. Clear and straightforward.

Using "target" is ambiguous, "target" can mean the target of the 
symbolic link (where the sym link points, i.e. the original file) *or* 
it can mean the target of the `ln` command, i.e. where the symlink is 
created.

Some of the common naming conventions:

POSIX, NetBSD, FreeBSD, MacOS use source_file, target_file.

OpenBSD uses source, target.

Solaris uses source_file, target.

AIX uses SourceFile, TargetFile.

GNU uses target, linkname.

https://unix.stackexchange.com/questions/541795/tips-for-remembering-the-order-of-parameters-for-ln

Windows mklink not only uses yet another set of names, but puts them in 
the opposite order: link, target.

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/mklink

MKS Toolkit calls them old, new.

https://www.mkssoftware.com/docs/man1/ln.1.asp

The Open Group Base Specifications document calls them path1, path2.

https://pubs.opengroup.org/onlinepubs/9699919799/functions/symlink.html#
msg399001 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-08-05 12:25
On Thu, Aug 05, 2021 at 12:00:31PM +0000, krey wrote:

> @steven.daprano My suggestion was changing the names of the args, not the order
> 
> Current
> def os.symlink(src, dst):
>     ln -s src dst

So far so good.

> Changing the names
> def os.symlink(dst, src):
>     ln -s dst src

That's not changing the names, that's changing the order.

You're putting the destination first, and the source second. That's the 
opposite order to that of `ln` in all the Unixes I can find, but it 
matches the order of Windows, which seems to be the only OS I can see 
that puts the destination (the path to the symlink) first and the source 
(the path to the target/original) second.

In any case, we have no power to change the order of arguments to `ln`.

> Changing the order
> def os.symlink(dst, src):
>     ln -s src dst

And that's just confused, because you have `ln` use the same order it 
has now, and symlink reverse the order.

> I concede that different unixes have different argnames for ln, it's a 
> bit of a mess. From a CS theory perspective, I think the GNU 
> convention makes more sense.

The GNU convention is the same convention as all the other Unixes, and 
os.symlink. Only the documented names are different.
History
Date User Action Args
2022-04-11 14:59:48adminsetgithub: 89000
2021-08-05 12:25:12steven.dapranosetmessages: + msg399001
2021-08-05 12:14:39steven.dapranosetmessages: + msg399000
2021-08-05 12:00:31kreysetstatus: open -> closed
resolution: not a bug
messages: + msg398998

stage: resolved
2021-08-05 11:16:52eric.smithsetmessages: + msg398995
2021-08-05 11:15:38steven.dapranosetmessages: + msg398994
2021-08-05 10:45:34kreysetmessages: + msg398990
2021-08-05 10:30:17eric.smithsetnosy: + eric.smith
messages: + msg398985
2021-08-05 10:26:25steven.dapranosetmessages: + msg398984
2021-08-05 10:02:00kreysetmessages: + msg398981
2021-08-05 09:28:05steven.dapranosetnosy: + steven.daprano
messages: + msg398980
2021-08-05 09:08:14kreycreate