From 34dbbf7c9f75389b1ccde96948ad88e72fd6dc53 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Fri, 14 Feb 2020 19:25:17 +0100 Subject: [PATCH] Fixed handling of current path in lresolve() / os.lstat() - fixes #516 --- CHANGES.md | 2 ++ pyfakefs/fake_filesystem.py | 9 ++++++++- pyfakefs/tests/fake_filesystem_vs_real_test.py | 6 +++++- pyfakefs/tests/fake_os_test.py | 11 +++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 58298559..8b49fc72 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,8 @@ the proposed changes so you can be ready. functions #### Fixes + * Fixed handling of relative paths in `lresolve` / `os.lstat` + (see [#516](../../issues/516)) * Fixed handling of byte string paths (see [#517](../../issues/517)) * Fixed `os.walk` if path ends with path separator diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 220daea9..637b9bf5 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -1442,6 +1442,8 @@ def absnormpath(self, path): cwd = self._matching_string(path, self.cwd) if not path: path = self.path_separator + if path == self._matching_string(path, '.'): + path = cwd elif not self._starts_with_root_path(path): # Prefix relative paths with cwd, if cwd is not root. root_name = self._matching_string(path, self.root.name) @@ -2002,12 +2004,16 @@ def lresolve(self, path): OSError: if the object is not found. """ path = make_string_path(path) + if not path: + raise OSError(errno.ENOENT, path) if path == self.root.name: # The root directory will never be a link return self.root # remove trailing separator path = self._path_without_trailing_separators(path) + if path == self._matching_string(path, '.'): + path = self.cwd path = self._original_path(path) parent_directory, child_name = self.splitpath(path) @@ -2022,7 +2028,8 @@ def lresolve(self, path): self.raise_os_error(errno.ENOENT, path) if not parent_obj.st_mode & PERM_READ: self.raise_os_error(errno.EACCES, parent_directory) - return parent_obj.get_entry(child_name) + return (parent_obj.get_entry(child_name) if child_name + else parent_obj) except KeyError: self.raise_os_error(errno.ENOENT, path) diff --git a/pyfakefs/tests/fake_filesystem_vs_real_test.py b/pyfakefs/tests/fake_filesystem_vs_real_test.py index f0294778..756d7cdc 100644 --- a/pyfakefs/tests/fake_filesystem_vs_real_test.py +++ b/pyfakefs/tests/fake_filesystem_vs_real_test.py @@ -172,7 +172,11 @@ def _compare_behaviors(self, method_name, path, real, fake, # pylint: disable=C6403 def _error_class(exc): - return (exc and exc.__class__.__name__) or 'None' + if exc: + if hasattr(exc, 'errno'): + return '{}({})'.format(exc.__class__.__name__, exc.errno) + return exc.__class__.__name__ + return 'None' real_err, real_value = self._get_real_value(method_name, path, real) fake_err, fake_value = self._get_fake_value(method_name, path, fake) diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py index 9c8c4869..4b24dee0 100644 --- a/pyfakefs/tests/fake_os_test.py +++ b/pyfakefs/tests/fake_os_test.py @@ -347,6 +347,12 @@ def test_lstat_with_byte_string(self): stat_bytes = self.os.lstat(base_path_bytes) self.assertEqual(stat_bytes, stat_str) + def test_stat_with_current_dir(self): + # regression test for #516 + stat_result = self.os.stat('.') + lstat_result = self.os.lstat('.') + self.assertEqual(stat_result, lstat_result) + def test_exists_with_trailing_sep(self): # regression test for #364 file_path = self.make_path('alpha') @@ -359,6 +365,11 @@ def test_mkdir_with_trailing_sep(self): self.os.mkdir(dir_path + self.os.sep + self.os.sep) self.assertTrue(self.os.path.exists(dir_path)) + def test_readlink_empty_path(self): + self.check_posix_only() + self.assert_raises_os_error(errno.ENOENT, + self.os.readlink, '') + def test_readlink_ending_with_sep_posix(self): # regression test for #359 self.check_posix_only()