From e07381d1475f0bd855ff1d826df6691b32fec9e7 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Thu, 3 May 2018 20:58:55 +0200 Subject: [PATCH] Added handling for creating broken symlinks with trailing separator - fixes #371 --- pyfakefs/fake_filesystem.py | 16 ++++++++++++++-- pyfakefs/tests/fake_os_test.py | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 66d12b6b..0f6201fb 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -2459,8 +2459,20 @@ def create_symlink(self, file_path, link_target, create_missing_dirs=True): if self.ends_with_path_separator(file_path): if self.exists(file_path): self.raise_os_error(errno.EEXIST, file_path) - if not self.is_windows_fs: - self.raise_os_error(errno.ENOENT, file_path) + if self.exists(link_target): + if not self.is_windows_fs: + self.raise_os_error(errno.ENOENT, file_path) + else: + if self.is_windows_fs: + self.raise_os_error(errno.EINVAL, link_target) + elif self.is_macos: + # to avoid EEXIST exception, remove the link + # if it already exists + if self.exists(file_path, check_link=True): + self.remove_object(file_path) + else: + self.raise_os_error(errno.EEXIST, link_target) + # resolve the link path only if it is not a link itself if not self.islink(file_path): diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py index ec7fd2ac..13ef746c 100644 --- a/pyfakefs/tests/fake_os_test.py +++ b/pyfakefs/tests/fake_os_test.py @@ -612,6 +612,31 @@ def test_readlink_raises_if_path_is_none(self): self.skip_if_symlink_not_supported() self.assertRaises(TypeError, self.os.readlink, None) + def test_broken_symlink_with_trailing_separator_linux(self): + self.check_linux_only() + file_path = self.make_path('foo') + link_path = self.make_path('link') + self.os.symlink(file_path, link_path) + self.assert_raises_os_error(errno.EEXIST, self.os.symlink, + link_path + self.os.sep, link_path + self.os.sep) + + def test_broken_symlink_with_trailing_separator_macos(self): + # regression test for #371 + self.check_macos_only() + file_path = self.make_path('foo') + link_path = self.make_path('link') + self.os.symlink(file_path, link_path) + self.os.symlink(link_path + self.os.sep, link_path + self.os.sep) + + def test_broken_symlink_with_trailing_separator_windows(self): + self.check_windows_only() + self.skip_if_symlink_not_supported() + file_path = self.make_path('foo') + link_path = self.make_path('link') + self.os.symlink(file_path, link_path) + self.assert_raises_os_error(errno.EINVAL, self.os.symlink, + link_path + self.os.sep, link_path + self.os.sep) + def test_readlink_with_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink(self.make_path('meyer', 'lemon', 'pie'),