Add some support for st_blocks in stat result
- closes #722
diff --git a/CHANGES.md b/CHANGES.md
index 78da2e0..84e6bda 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,7 +3,11 @@
## Unreleased
-### Fixes
+### New Features
+* added some support for `st_blocks` in stat result
+ (see [#722](../../issues/722))
+
+### Fixes
* fixed handling of `O_TMPFILE` in `os.open` (caused handling of
`O_DIRECTORY` as `O_TMPFILE`) (see [#723](../../issues/723))
diff --git a/pyfakefs/helpers.py b/pyfakefs/helpers.py
index 3e1ae69..35bf67b 100644
--- a/pyfakefs/helpers.py
+++ b/pyfakefs/helpers.py
@@ -214,6 +214,23 @@
self._st_size = val
@property
+ def st_blocks(self) -> int:
+ """Return the number of 512-byte blocks allocated for the file.
+ Assumes a page size of 4096 (matches most systems).
+ Ignores that this may not be available under some systems,
+ and that the result may differ if the file has holes.
+ """
+ if self.is_windows:
+ raise AttributeError(
+ "'os.stat_result' object has no attribute 'st_blocks'")
+ page_size = 4096
+ blocks_in_page = page_size // 512
+ pages = self._st_size // page_size
+ if self._st_size % page_size:
+ pages += 1
+ return pages * blocks_in_page
+
+ @property
def st_file_attributes(self) -> int:
if not self.is_windows:
raise AttributeError("module 'os.stat_result' "
diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py
index 6a34038..ecd856b 100644
--- a/pyfakefs/tests/fake_os_test.py
+++ b/pyfakefs/tests/fake_os_test.py
@@ -247,6 +247,31 @@
self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode)
self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE])
+ def test_st_blocks(self):
+ self.check_posix_only()
+ file_path = self.make_path('foo1')
+ self.create_file(file_path, contents=b"")
+ self.assertEqual(0, self.os.stat(file_path).st_blocks)
+ file_path = self.make_path('foo2')
+ self.create_file(file_path, contents=b"t")
+ self.assertEqual(8, self.os.stat(file_path).st_blocks)
+ file_path = self.make_path('foo3')
+ self.create_file(file_path, contents=b"t" * 4095)
+ self.assertEqual(8, self.os.stat(file_path).st_blocks)
+ file_path = self.make_path('foo4')
+ self.create_file(file_path, contents=b"t" * 4096)
+ self.assertEqual(8, self.os.stat(file_path).st_blocks)
+ file_path = self.make_path('foo5')
+ self.create_file(file_path, contents=b"t" * 4097)
+ self.assertEqual(16, self.os.stat(file_path).st_blocks)
+
+ def test_no_st_blocks_in_windows(self):
+ self.check_windows_only()
+ file_path = self.make_path('foo')
+ self.create_file(file_path, contents=b"")
+ with self.assertRaises(AttributeError):
+ self.os.stat(file_path).st_blocks
+
def test_stat_with_unc_path(self):
self.skip_real_fs()
self.check_windows_only()