Skip to content

Commit cdb8431

Browse files
committed
Consolidated setting of st_ino
- now is always set in add_entry - st_ino was not set in fake_filesystem.makedir, what caused incorrect behavior for os.samefile for directories - fixes #515
1 parent 34dbbf7 commit cdb8431

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ the proposed changes so you can be ready.
2020
functions
2121

2222
#### Fixes
23+
* Added missing `st_ino` in `makedir` (see [#515](../../issues/515))
2324
* Fixed handling of relative paths in `lresolve` / `os.lstat`
2425
(see [#516](../../issues/516))
2526
* Fixed handling of byte string paths

pyfakefs/fake_filesystem.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,9 @@ def add_entry(self, path_object):
646646

647647
self.contents[path_object_name] = path_object
648648
path_object.parent_dir = self
649+
if path_object.st_ino is None:
650+
self.filesystem.last_ino += 1
651+
path_object.st_ino = self.filesystem.last_ino
649652
self.st_nlink += 1
650653
path_object.st_nlink += 1
651654
path_object.st_dev = self.st_dev
@@ -878,8 +881,8 @@ def __init__(self, path_separator=os.path.sep, total_size=None,
878881
# A heap containing all free positions in self.open_files list
879882
self._free_fd_heap = []
880883
# last used numbers for inodes (st_ino) and devices (st_dev)
881-
self._last_ino = 0
882-
self._last_dev = 0
884+
self.last_ino = 0
885+
self.last_dev = 0
883886
self.mount_points = {}
884887
self.add_mount_point(self.root.name, total_size)
885888
self._add_standard_streams()
@@ -896,8 +899,8 @@ def reset(self, total_size=None):
896899

897900
self.open_files = []
898901
self._free_fd_heap = []
899-
self._last_ino = 0
900-
self._last_dev = 0
902+
self.last_ino = 0
903+
self.last_dev = 0
901904
self.mount_points = {}
902905
self.add_mount_point(self.root.name, total_size)
903906
self._add_standard_streams()
@@ -994,14 +997,18 @@ def add_mount_point(self, path, total_size=None):
994997
path = self.absnormpath(path)
995998
if path in self.mount_points:
996999
self.raise_os_error(errno.EEXIST, path)
997-
self._last_dev += 1
1000+
self.last_dev += 1
9981001
self.mount_points[path] = {
999-
'idev': self._last_dev, 'total_size': total_size, 'used_size': 0
1002+
'idev': self.last_dev, 'total_size': total_size, 'used_size': 0
10001003
}
10011004
# special handling for root path: has been created before
1002-
root_dir = (self.root if path == self.root.name
1003-
else self.create_dir(path))
1004-
root_dir.st_dev = self._last_dev
1005+
if path == self.root.name:
1006+
root_dir = self.root
1007+
self.last_ino += 1
1008+
root_dir.st_ino = self.last_ino
1009+
else:
1010+
root_dir = self.create_dir(path)
1011+
root_dir.st_dev = self.last_dev
10051012
return self.mount_points[path]
10061013

10071014
def _auto_mount_drive_if_needed(self, path, force=False):
@@ -2293,8 +2300,6 @@ def create_dir(self, directory_path, perm_bits=PERM_DEF):
22932300
for new_dir in new_dirs:
22942301
new_dir.st_mode = S_IFDIR | perm_bits
22952302

2296-
self._last_ino += 1
2297-
current_dir.st_ino = self._last_ino
22982303
return current_dir
22992304

23002305
def create_file(self, file_path, st_mode=S_IFREG | PERM_DEF_FILE,
@@ -2448,8 +2453,6 @@ def add_real_directory(self, source_path, read_only=True, lazy_read=True,
24482453
new_dir = FakeDirectoryFromRealDirectory(
24492454
source_path, self, read_only, target_path)
24502455
parent_dir.add_entry(new_dir)
2451-
self._last_ino += 1
2452-
new_dir.st_ino = self._last_ino
24532456
else:
24542457
new_dir = self.create_dir(target_path)
24552458
for base, _, files in os.walk(source_path):
@@ -2557,8 +2560,6 @@ def create_file_internally(self, file_path,
25572560
encoding=encoding, errors=errors,
25582561
side_effect=side_effect)
25592562

2560-
self._last_ino += 1
2561-
file_object.st_ino = self._last_ino
25622563
self.add_object(parent_directory, file_object)
25632564

25642565
if st_size is None and contents is None:

pyfakefs/tests/fake_filesystem_shutil_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import os
2121
import shutil
2222
import sys
23+
import tempfile
2324
import unittest
2425

2526
from pyfakefs import fake_filesystem_unittest
@@ -489,6 +490,17 @@ def test_raises_if_dest_is_a_directory(self):
489490
else:
490491
self.assertRaises(OSError, shutil.copyfile, src_file, dst_dir)
491492

493+
def test_moving_dir_into_dir(self):
494+
# regression test for #515
495+
source_dir = tempfile.mkdtemp()
496+
target_dir = tempfile.mkdtemp()
497+
filename = 'foo.pdf'
498+
with open(os.path.join(source_dir, filename), 'wb') as fp:
499+
fp.write(b'stub')
500+
501+
shutil.move(source_dir, target_dir)
502+
shutil.rmtree(target_dir)
503+
492504

493505
class RealCopyFileTest(FakeCopyFileTest):
494506
def use_real_fs(self):

0 commit comments

Comments
 (0)