From a53706ea3f5831d2b36b39889147baa838e28a57 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Fri, 18 May 2018 20:49:03 +0200 Subject: [PATCH] Added special handling for broken links with trailing separator - allow mkdir and makedirs under MacOS - see #396 --- pyfakefs/fake_filesystem.py | 14 +++++++++++++- pyfakefs/tests/fake_os_test.py | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 93cf284e..7aed347e 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -2594,6 +2594,7 @@ def makedir(self, dir_name, mode=PERM_DEF): read only or as per :py:meth:`add_object`. """ dir_name = make_string_path(dir_name) + ends_with_sep = self.ends_with_path_separator(dir_name) dir_name = self._path_without_trailing_separators(dir_name) if not dir_name: self.raise_os_error(errno.ENOENT, '') @@ -2616,7 +2617,11 @@ def makedir(self, dir_name, mode=PERM_DEF): error_nr = errno.EACCES else: error_nr = errno.EEXIST - self.raise_os_error(error_nr, dir_name) + if ends_with_sep and self.is_macos and not self.exists(dir_name): + # to avoid EEXIST exception, remove the link + self.remove_object(dir_name) + else: + self.raise_os_error(error_nr, dir_name) head, tail = self.splitpath(dir_name) self.add_object( @@ -2644,7 +2649,14 @@ def makedirs(self, dir_name, mode=PERM_DEF, exist_ok=False): OSError: if the directory already exists and exist_ok=False, or as per :py:meth:`create_dir`. """ + ends_with_sep = self.ends_with_path_separator(dir_name) dir_name = self.absnormpath(dir_name) + if (ends_with_sep and self.is_macos and + self.exists(dir_name, check_link=True) and + not self.exists(dir_name)): + # to avoid EEXIST exception, remove the link + self.remove_object(dir_name) + path_components = self._path_components(dir_name) # Raise a permission denied error if the first existing directory diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py index 544f6816..6caee9a7 100644 --- a/pyfakefs/tests/fake_os_test.py +++ b/pyfakefs/tests/fake_os_test.py @@ -2189,6 +2189,22 @@ def test_lstat_broken_link_with_trailing_sep_windows(self): link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EINVAL, self.os.lstat, link_path) + def test_mkdir_broken_link_with_trailing_sep_linux_windows(self): + self.check_linux_and_windows() + link_path = self.create_broken_link_path_with_trailing_sep() + self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, link_path) + self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, link_path) + + def test_mkdir_broken_link_with_trailing_sep_macos(self): + self.check_macos_only() + link_path = self.create_broken_link_path_with_trailing_sep() + self.os.mkdir(link_path) # no error + + def test_makedirs_broken_link_with_trailing_sep_macos(self): + self.check_macos_only() + link_path = self.create_broken_link_path_with_trailing_sep() + self.os.makedirs(link_path) # no error + def test_remove_broken_link_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.create_broken_link_path_with_trailing_sep()