Skip to content

Commit 3f760d7

Browse files
committed
Do not resolve links in base path for fake os.scandir
- used PEP8 conform methods in fake_scandir - fixes #350
1 parent f245afb commit 3f760d7

File tree

3 files changed

+28
-14
lines changed

3 files changed

+28
-14
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ must use pyfakefs 3.3 or earlier.
2626
* Removed Python 2.6 support [#293](../../issues/293)
2727

2828
#### Fixes
29+
* Links in base path in `os.scandir` shall not be resolved ([#350](../../issues/350))
2930
* Correctly handle newline parameter in `open()` for Python 3, added support for universal newline mode in Python 2 ([#339](../../issues/339))
3031
* Creating a file with a path ending with path separator did not raise ([#320](../../issues/320))
3132
* Fixed more problems related to `flush` ([#302](../../issues/302), [#300](../../issues/300))

pyfakefs/fake_scandir.py

+17-14
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ def stat(self, follow_symlinks=True):
8383
"""
8484
if follow_symlinks:
8585
if self._statresult_symlink is None:
86-
file_object = self._filesystem.ResolveObject(self.path)
86+
file_object = self._filesystem.resolve(self.path)
8787
if self._filesystem.is_windows_fs:
8888
file_object.st_nlink = 0
8989
self._statresult_symlink = file_object.stat_result.copy()
9090
return self._statresult_symlink
9191

9292
if self._statresult is None:
93-
file_object = self._filesystem.LResolveObject(self.path)
93+
file_object = self._filesystem.lresolve(self.path)
9494
self._inode = file_object.st_ino
9595
if self._filesystem.is_windows_fs:
9696
file_object.st_nlink = 0
@@ -106,14 +106,15 @@ def __init__(self, filesystem, path):
106106
self.filesystem = filesystem
107107
if isinstance(path, int):
108108
if sys.version_info < (3, 7) or self.filesystem.is_windows_fs:
109-
raise NotImplementedError('scandir does not support file descriptor'
110-
'path argument')
109+
raise NotImplementedError(
110+
'scandir does not support file descriptor '
111+
'path argument')
111112
path = self.filesystem.get_open_file(path).get_object().path
112113

113-
self.path = self.filesystem.ResolvePath(path)
114+
self.path = self.filesystem.absnormpath(path)
114115
contents = {}
115116
try:
116-
contents = self.filesystem.ConfirmDir(path).contents
117+
contents = self.filesystem.confirmdir(path).contents
117118
except OSError:
118119
pass
119120
self.contents_iter = iter(contents)
@@ -128,9 +129,10 @@ def __next__(self):
128129
entry = self.contents_iter.__next__()
129130
dir_entry = DirEntry(self.filesystem)
130131
dir_entry.name = entry
131-
dir_entry.path = self.filesystem.JoinPaths(self.path, dir_entry.name)
132-
dir_entry._isdir = self.filesystem.IsDir(dir_entry.path)
133-
dir_entry._islink = self.filesystem.IsLink(dir_entry.path)
132+
dir_entry.path = self.filesystem.joinpaths(self.path,
133+
dir_entry.name)
134+
dir_entry._isdir = self.filesystem.isdir(dir_entry.path)
135+
dir_entry._islink = self.filesystem.islink(dir_entry.path)
134136
return dir_entry
135137

136138
# satisfy both Python 2 and 3
@@ -184,8 +186,8 @@ def _classify_directory_contents(filesystem, root):
184186
"""
185187
dirs = []
186188
files = []
187-
for entry in filesystem.ListDir(root):
188-
if filesystem.IsDir(filesystem.JoinPaths(root, entry)):
189+
for entry in filesystem.listdir(root):
190+
if filesystem.isdir(filesystem.joinpaths(root, entry)):
189191
dirs.append(entry)
190192
else:
191193
files.append(entry)
@@ -213,7 +215,7 @@ def walk(filesystem, top, topdown=True, onerror=None, followlinks=False):
213215

214216
def do_walk(top_dir, top_most=False):
215217
top_dir = filesystem.CollapsePath(top_dir)
216-
if not top_most and not followlinks and filesystem.IsLink(top_dir):
218+
if not top_most and not followlinks and filesystem.islink(top_dir):
217219
return
218220
try:
219221
top_contents = _classify_directory_contents(filesystem, top_dir)
@@ -227,9 +229,10 @@ def do_walk(top_dir, top_most=False):
227229
yield top_contents
228230

229231
for directory in top_contents[1]:
230-
if not followlinks and filesystem.IsLink(directory):
232+
if not followlinks and filesystem.islink(directory):
231233
continue
232-
for contents in do_walk(filesystem.JoinPaths(top_dir, directory)):
234+
for contents in do_walk(filesystem.joinpaths(top_dir,
235+
directory)):
233236
yield contents
234237

235238
if not topdown:

tests/fake_os_test.py

+10
Original file line numberDiff line numberDiff line change
@@ -4087,6 +4087,16 @@ def test_is_link(self):
40874087
self.assertTrue(self.dir_entries[2].is_symlink())
40884088
self.assertTrue(self.dir_entries[3].is_symlink())
40894089

4090+
def test_path_links_not_resolved(self):
4091+
# regression test for #350
4092+
self.skip_if_symlink_not_supported()
4093+
dir_path = self.make_path('A', 'B', 'C')
4094+
self.os.makedirs(self.os.path.join(dir_path, 'D'))
4095+
link_path = self.make_path('A', 'C')
4096+
self.os.symlink(dir_path, link_path)
4097+
self.assertEqual([self.os.path.join(link_path, 'D')],
4098+
[f.path for f in self.os.scandir(link_path)])
4099+
40904100
def test_inode(self):
40914101
if has_scandir and self.is_windows and self.use_real_fs():
40924102
self.skipTest('inode seems not to work in scandir module under Windows')

0 commit comments

Comments
 (0)