Skip to content

Commit

Permalink
Add missing follow_symlink argument to os.link
Browse files Browse the repository at this point in the history
  • Loading branch information
mrbean-bremen committed Mar 12, 2024
1 parent 190390f commit c4edbcb
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The released versions correspond to PyPI releases.
* fixed creation of the temp directory in the fake file system after a filesystem reset
(see [#965](../../issues/965))
* fixed handling of `dirfd` in `os.symlink` (see [#968](../../issues/968))
* add missing `follow_symlink` argument to `os.link` (see [#973](../../issues/973))

## [Version 5.3.5](https://pypi.python.org/pypi/pyfakefs/5.3.5) (2024-01-30)
Fixes a regression.
Expand Down
10 changes: 9 additions & 1 deletion pyfakefs/fake_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,7 @@ def link(
*,
src_dir_fd: Optional[int] = None,
dst_dir_fd: Optional[int] = None,
follow_symlinks: Optional[bool] = None,
) -> None:
"""Create a hard link at dst, pointing at src.
Expand All @@ -1195,14 +1196,21 @@ def link(
with `src` being relative to this directory.
dst_dir_fd: If not `None`, the file descriptor of a directory,
with `dst` being relative to this directory.
follow_symlinks: (bool) If True (the default), symlinks in the
path are traversed.
Raises:
OSError: if something already exists at new_path.
OSError: if the parent directory doesn't exist.
"""
if IS_PYPY and follow_symlinks is not None:
raise OSError(errno.EINVAL, "Invalid argument: follow_symlinks")
if follow_symlinks is None:
follow_symlinks = True

src = self._path_with_dir_fd(src, self.link, src_dir_fd)
dst = self._path_with_dir_fd(dst, self.link, dst_dir_fd)
self.filesystem.link(src, dst)
self.filesystem.link(src, dst, follow_symlinks=follow_symlinks)

def fsync(self, fd: int) -> None:
"""Perform fsync for a fake file (in other words, do nothing).
Expand Down
23 changes: 23 additions & 0 deletions pyfakefs/tests/fake_os_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2705,6 +2705,29 @@ def test_link_count1(self):
self.os.unlink(file1_path)
self.assertEqual(self.os.stat(file2_path).st_nlink, 1)

@unittest.skipIf(IS_PYPY, "follow_symlinks not supported in PyPi")
def test_link_no_follow_symlink(self):
self.skip_if_symlink_not_supported()
target_path = self.make_path("target_path")
self.create_file(target_path, contents="foo")
symlink_path = self.make_path("symlink_to_file")
self.create_symlink(symlink_path, target_path)
link_path = self.make_path("link_to_symlink")
self.os.link(symlink_path, link_path, follow_symlinks=False)
self.assertTrue(self.os.path.islink(link_path))

@unittest.skipIf(not IS_PYPY, "follow_symlinks only not supported in PyPi")
def test_link_follow_symlink_not_supported_inPypy(self):
self.skip_if_symlink_not_supported()
target_path = self.make_path("target_path")
self.create_file(target_path, contents="foo")
symlink_path = self.make_path("symlink_to_file")
self.create_symlink(symlink_path, target_path)
link_path = self.make_path("link_to_symlink")
with self.assertRaises(OSError) as cm:
self.os.link(symlink_path, link_path, follow_symlinks=False)
self.assertEqual(errno.EINVAL, cm.exception.errno)

def test_nlink_for_directories(self):
self.skip_real_fs()
self.create_dir(self.make_path("foo", "bar"))
Expand Down

0 comments on commit c4edbcb

Please sign in to comment.