On 11/7/22, Charles Machalow <csm10...@gmail.com> wrote: > > Junctions are contextually similar to symlinks on Windows.
Junctions (i.e. IO_REPARSE_TAG_MOUNT_POINT) are implemented to behave as mount points for local volumes, so there are a couple of important differences. In a remote path, a junction gets resolved on the server side, which is always possible because the target of a junction must be a local volume (i.e. local to the server). Thus a junction that targets "C:\spam" resolves to the "C:" drive on the remote system. If you're resolving a junction manually via `os.readlink()`, take care to never resolve a remote junction target as a local path such as "C:\spam". That would not only be wrong but also potentially harmful if client files get mistakenly modified, replaced, or deleted. On the other hand, a remote symlink that targets "C:\spam" gets resolved by the client and thus always resolves to the local "C:" drive of the client. This depends on the client system allowing remote-to-local (R2L) symlinks, which is disabled by default for good reason. When resolving a symlink manually, at worst you'll be in violation of the system's L2L, L2R, R2L, or R2R symlink policy. Secondly, the target of a junction does not replace the previously traversed path when the system parses a path. This affects how a relative symlink gets resolved, in which case traversed junctions behave like Unix bind mount points. Say that "E:\eggs\spamlink" is a relative symlink that targets "..\spam". When accessed directly, this symbolic link resolves to "E:\spam". Say that "C:\mount\junction" targets "E:\eggs". Then "C:\mount\junction\spamlink" resolves to "C:\mount\spam", a different file in this case. In contrast, the target of a symlink always replaces the traversed path when the system parse a path. Say that "C:\mount\symlink" targets "E:\eggs". Then "C:\mount\symlink\spamlink" resolves to "E:\spam", the same as if "E:\eggs\spamlink" had been opened directly. > Currently is_symlink/islink return False for junctions. Some API contexts, libraries, and applications only support IO_REPARSE_POINT_SYMLINK reparse points as symlinks. For general compatibility that's the only type of reparse point that reliably counts as a "symlink". Also, part of the rationale for this division is that currently we cannot copy a junction via os.readlink() and os.symlink(). If we were to copy a junction as a symlink, in general this could change how the target path is resolved or how the link behaves in the context of relative symlinks. It would be less of an issue if os.readlink() returned an object type that allowed duplicating any name-surrogate reparse point via os.symlink(). Instead of calling WinAPI CreateSymbolicLinkW() in such cases, os.symlink() would create the target file/directory and directly set the reparse point via FSCTL_SET_REPARSE_POINT. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/YM6EUE6HSH7QJISUXH3J24C4OSAN7JLR/ Code of Conduct: http://python.org/psf/codeofconduct/