Skip to content

Commit

Permalink
Added special handling for broken links with trailing separator
Browse files Browse the repository at this point in the history
- allow mkdir and makedirs under MacOS
- see #396
  • Loading branch information
mrbean-bremen committed May 18, 2018
1 parent d1efc1f commit a53706e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
14 changes: 13 additions & 1 deletion pyfakefs/fake_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, '')
Expand All @@ -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(
Expand Down Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions pyfakefs/tests/fake_os_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit a53706e

Please sign in to comment.