Skip to content

Commit

Permalink
Add some support for st_blocks in stat result
Browse files Browse the repository at this point in the history
- closes #722
  • Loading branch information
mrbean-bremen committed Oct 2, 2022
1 parent 26e8b72 commit 0fb50dd
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
6 changes: 5 additions & 1 deletion CHANGES.md
Expand Up @@ -3,7 +3,11 @@ The released versions correspond to PyPi releases.

## 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))

Expand Down
17 changes: 17 additions & 0 deletions pyfakefs/helpers.py
Expand Up @@ -213,6 +213,23 @@ def st_size(self) -> int:
def st_size(self, val: int) -> None:
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:
Expand Down
25 changes: 25 additions & 0 deletions pyfakefs/tests/fake_os_test.py
Expand Up @@ -247,6 +247,31 @@ def test_stat(self):
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()
Expand Down

0 comments on commit 0fb50dd

Please sign in to comment.