From 4dc8615957dadfc64d6a8f864ee93c7c65da38b5 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Sun, 30 Jan 2022 13:35:40 +0100 Subject: [PATCH] Correctly handle full disk after append - do not update flush position before disk size is checked - see #660 --- CHANGES.md | 20 +++++++++++++++----- pyfakefs/fake_filesystem.py | 6 +++++- pyfakefs/tests/fake_filesystem_test.py | 22 +++++++++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 9cbfb8de..ed1d9c88 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -57,6 +57,8 @@ This is a bugfix release. * handle `pathlib.Path.owner()` and `pathlib.Path.group` by returning the current user/group name (see [#629](../../issues/629)) * fixed handling of `use_known_patches=False` (could cause an exception) +* removed Python 3.5 from metadata to disable installation for that version + (see [#615](../../issues/615)) ### Infrastructure * added test dependency check (see [#608](../../issues/608)) @@ -66,6 +68,9 @@ This is a bugfix release. ## [Version 4.5.0](https://pypi.python.org/pypi/pyfakefs/4.5.0) (2021-06-04) Adds some support for Python 3.10 and basic type checking. +_Note_: This version has been yanked from PyPi as it erroneously allowed +installation under Python 3.5. + ### New Features * added support for some Python 3.10 features: * new method `pathlib.Path.hardlink_to` @@ -232,8 +237,8 @@ This is a bugfix release that fixes a regression issue. ## [Version 4.0.2](https://pypi.python.org/pypi/pyfakefs/4.0.2) (2020-03-04) This as a patch release that only builds for Python 3. Note that -versions 4.0.0 and 4.0.1 will be removed from PyPi to not to be able to -install them under Python 2. +versions 4.0.0 and 4.0.1 will be removed from PyPi to disable +installing them under Python 2. #### Fixes * Do not build for Python 2 (see [#524](../../issues/524)) @@ -242,14 +247,19 @@ install them under Python 2. This as a bug fix release for a regression bug. +_Note_: This version has been yanked from PyPi as it erroneously allowed +installation under Python 2. This has been fixed in version 4.0.2. + #### Fixes * Avoid exception if using `flask-restx` (see [#523](../../issues/523)) ## [Version 4.0.0](https://pypi.python.org/pypi/pyfakefs/4.0.0) (2020-03-03) +pyfakefs 4.0.0 drops support for Python 2.7. If you still need +Python 2.7, you can continue to use pyfakefs 3.7.x. + +_Note_: This version has been yanked from PyPi as it erroneously allowed +installation under Python 2. This has been fixed in version 4.0.2. - * pyfakefs 4.0.0 drops support for Python 2.7. If you still need - Python 2.7, you can continue to use pyfakefs 3.7.x. - #### Changes * Removed Python 2.7 and 3.4 support (see [#492](../../issues/492)) diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 758e46f0..2e2d1297 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -455,6 +455,9 @@ def set_contents(self, contents: AnyStr, if they are a unicode string. If not given, the locale preferred encoding is used. + Returns: + True if the contents have been changed. + Raises: OSError: if `st_size` is not a non-negative integer, or if it exceeds the available file system space. @@ -5049,8 +5052,9 @@ def flush(self) -> None: self._set_stream_contents(contents) else: self._io.flush() + changed = self.file_object.set_contents(contents, self._encoding) self.update_flush_pos() - if self.file_object.set_contents(contents, self._encoding): + if changed: if self._filesystem.is_windows_fs: self._changed = True else: diff --git a/pyfakefs/tests/fake_filesystem_test.py b/pyfakefs/tests/fake_filesystem_test.py index 95953f14..b95db8fd 100644 --- a/pyfakefs/tests/fake_filesystem_test.py +++ b/pyfakefs/tests/fake_filesystem_test.py @@ -1790,7 +1790,7 @@ def test_disk_size_on_auto_mounted_drive_on_directory_creation(self): self.filesystem.create_file('d:!foo!bar!baz', st_size=100) self.filesystem.create_file('d:!foo!baz', st_size=100) self.filesystem.set_disk_usage(total_size=1000, path='d:') - self.assertEqual(self.filesystem.get_disk_usage('d:!foo').free, 800) + self.assertEqual(800, self.filesystem.get_disk_usage('d:!foo').free) def test_copying_preserves_byte_contents(self): source_file = self.filesystem.create_file('foo', contents=b'somebytes') @@ -1802,16 +1802,30 @@ def test_diskusage_after_open_write(self): with self.open('bar.txt', 'w') as f: f.write('a' * 60) f.flush() - self.assertEqual(self.filesystem.get_disk_usage()[1], 60) + self.assertEqual(60, self.filesystem.get_disk_usage()[1]) def test_disk_full_after_reopened(self): with self.open('bar.txt', 'w') as f: f.write('a' * 60) with self.open('bar.txt') as f: - self.assertEqual(f.read(), 'a' * 60) + self.assertEqual('a' * 60, f.read()) with self.raises_os_error(errno.ENOSPC): with self.open('bar.txt', 'w') as f: f.write('b' * 110) + with self.raises_os_error(errno.ENOSPC): + f.flush() + + def test_disk_full_append(self): + file_path = 'bar.txt' + with self.open(file_path, 'w') as f: + f.write('a' * 60) + with self.open(file_path) as f: + self.assertEqual('a' * 60, f.read()) + with self.raises_os_error(errno.ENOSPC): + with self.open(file_path, 'a') as f: + f.write('b' * 41) + with self.raises_os_error(errno.ENOSPC): + f.flush() def test_disk_full_after_reopened_rplus_seek(self): with self.open('bar.txt', 'w') as f: @@ -1822,6 +1836,8 @@ def test_disk_full_after_reopened_rplus_seek(self): with self.open('bar.txt', 'r+') as f: f.seek(50) f.write('b' * 60) + with self.raises_os_error(errno.ENOSPC): + f.flush() class MountPointTest(TestCase):