many functions call with a file system path can also choose whether to follow symlinks (usually the default) or not. is there a way to make this choice with os.listdir()? what about a file descriptor open to a directory (i am thinking to open the directory of interest ahead with os.open() then using that file descriptor on listdir)? same questions for os.scandir().
What would be the purpose of the follow_symlink option when you list the content of a directory? How would the result differ depending on the option's value?
case A: the given path is a directory
case B: the given path is a symlink to a directory
other functions differentiate these cases in exceptions. i was just thinking
listdir and/or
scandir ought to, as well. by default,
os.listdir() follows symlinks. many other functions have
followsymlinks= to allow disabling this so that symlinks are not followed in which case
NotADirectoryError should be raised. coders using
os.listdir() should handle this kind of exception around
os.listdir() unless they are 100% sure it cannot ever happen. presumably os.scandir() has the same issue.
(May-18-2024, 07:45 PM)Gribouillis Wrote: [ -> ]What would be the purpose of the follow_symlink option when you list the content of a directory?
to ensure that a symlink named like the believed directory is not followed. i use os.lstat() for a like purpose.
of course there is
if not os.path.islink(this_path):
.
(May-18-2024, 05:44 PM)Skaperen Wrote: [ -> ]many functions call with a file system path can also choose whether to follow symlinks (usually the default) or not. is there a way to make this choice with os.listdir()?
os.listdir
does not distinguish between regular files and symbolic links.
With
os.scandir
can check if an entry is a symbolic link
This allows you to manually choose whether to follow symbolic links or not.
import os
with os.scandir('path/to/directory') as it:
for entry in it:
if entry.is_symlink():
print(f"{entry.name} is a symbolic link")
else:
print(entry.name)
Pathlib also has a
resolve
(returns the absolute path of the target file or directory).
Follows all levels of symlinks until it reaches the final target.
from pathlib import Path
path = Path('path/to/symlink')
if path.is_symlink():
target_path = path.resolve()
print(f"{path} points to {target_path}")
else:
print(f"{symlink_path} is not a symbolic link")
You'll have to write your own
def mylistdir(path, follow_symlinks=True):
if follow_symlinks or not os.path.islink(path):
return os.listdir(path)
raise NotADirectoryError(path)
(May-18-2024, 05:44 PM)Skaperen Wrote: [ -> ]is there a way to make this choice with os.listdir()?
Probably not because os.listdir() is mainly just C's readdir() wrapped up.
If you pass a symlink to readdir(), it follows it, and there are no options not to. Since this is how POSIX has worked for a long time, most folks will assume the same here.
(May-23-2024, 07:05 AM)bowlofred Wrote: [ -> ]If you pass a symlink to readdir(), it follows it, and there are no options not to. Since this is how POSIX has worked for a long time, most folks will assume the same here.
i had hoped Python's library layer would clean up most of these inconsistencies. it seems to favor being too much like C.