aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrbean-bremen <hansemrbean@googlemail.com>2022-01-28 19:51:25 +0100
committermrbean-bremen <mrbean-bremen@users.noreply.github.com>2022-01-28 20:13:44 +0100
commit9f486bcaa6fcd2ba4c77db1a668b21178a38169e (patch)
treef21f9336e9e45f1c57d5ba1c376d2270be75cf32
parentc25e65ef80838337c2206f098ca1fd0edd0633c7 (diff)
downloadpyfakefs-9f486bcaa6fcd2ba4c77db1a668b21178a38169e.tar.gz
Correctly handle reading/writing pipes via file
- make numBytes argument optional - open real pipe as file and store it if needed - fixes #661
-rw-r--r--CHANGES.md2
-rw-r--r--pyfakefs/fake_filesystem.py21
-rw-r--r--pyfakefs/tests/fake_os_test.py2
3 files changed, 19 insertions, 6 deletions
diff --git a/CHANGES.md b/CHANGES.md
index 36da884..9cbfb8d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -6,6 +6,8 @@ The released versions correspond to PyPi releases.
### Fixes
* correctly handle file system space for files opened in write mode
(see [#660](../../issues/660))
+* correctly handle reading/writing pipes via file
+ (see [#661](../../issues/661))
## [Version 4.5.4](https://pypi.python.org/pypi/pyfakefs/4.5.4) (2022-01-12)
Minor bugfix release.
diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py
index 2a863d1..758e46f 100644
--- a/pyfakefs/fake_filesystem.py
+++ b/pyfakefs/fake_filesystem.py
@@ -5383,7 +5383,7 @@ class StandardStreamWrapper:
return self.filedes
raise OSError(errno.EBADF, 'Invalid file descriptor')
- def read(self, n: int) -> bytes:
+ def read(self, n: int = -1) -> bytes:
return cast(bytes, self._stream_object.read())
def close(self) -> None:
@@ -5427,12 +5427,16 @@ class FakePipeWrapper:
used in open files list.
"""
- def __init__(self, filesystem: FakeFilesystem, fd: int, can_write: bool):
+ def __init__(self, filesystem: FakeFilesystem,
+ fd: int, can_write: bool, mode: str = ''):
self._filesystem = filesystem
self.fd = fd # the real file descriptor
self.can_write = can_write
self.file_object = None
self.filedes: Optional[int] = None
+ self.real_file = None
+ if mode:
+ self.real_file = open(fd, mode)
def __enter__(self) -> 'FakePipeWrapper':
"""To support usage of this fake pipe with the 'with' statement."""
@@ -5454,8 +5458,10 @@ class FakePipeWrapper:
return self.filedes
raise OSError(errno.EBADF, 'Invalid file descriptor')
- def read(self, numBytes: int) -> bytes:
+ def read(self, numBytes: int = -1) -> bytes:
"""Read from the real pipe."""
+ if self.real_file:
+ return self.real_file.read(numBytes)
return os.read(self.fd, numBytes)
def flush(self) -> None:
@@ -5464,6 +5470,8 @@ class FakePipeWrapper:
def write(self, contents: bytes) -> int:
"""Write to the real pipe."""
+ if self.real_file:
+ return self.real_file.write(contents)
return os.write(self.fd, contents)
def close(self) -> None:
@@ -5472,7 +5480,10 @@ class FakePipeWrapper:
open_files = self._filesystem.open_files[self.filedes]
assert open_files is not None
open_files.remove(self)
- os.close(self.fd)
+ if self.real_file:
+ self.real_file.close()
+ else:
+ os.close(self.fd)
def readable(self) -> bool:
"""The pipe end can either be readable or writable."""
@@ -5571,7 +5582,7 @@ class FakeFileOpen:
existing_wrapper = wrappers[0]
assert isinstance(existing_wrapper, FakePipeWrapper)
wrapper = FakePipeWrapper(self.filesystem, existing_wrapper.fd,
- existing_wrapper.can_write)
+ existing_wrapper.can_write, mode)
file_des = self.filesystem._add_open_file(wrapper)
wrapper.filedes = file_des
return wrapper
diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py
index fa923d7..7408d17 100644
--- a/pyfakefs/tests/fake_os_test.py
+++ b/pyfakefs/tests/fake_os_test.py
@@ -2750,7 +2750,7 @@ class FakeOsModuleTest(FakeOsModuleTestBase):
with self.open(write_fd, 'wb') as f:
self.assertEqual(4, f.write(b'test'))
with self.open(read_fd, 'rb') as f:
- self.assertEqual(b'test', f.read(4))
+ self.assertEqual(b'test', f.read())
for fd in fds:
self.os.close(fd)