Skip to content

Commit 78543fb

Browse files
committed
Added support for os.pipe
- see #473
1 parent 67a57fa commit 78543fb

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ The release versions are PyPi releases.
33

44
## Version 3.6 (as yet unreleased)
55

6+
#### New Features
7+
* added support for `os.pipe` (see [#473](../../issues/473))
8+
69
## [Version 3.5.8](https://pypi.python.org/pypi/pyfakefs/3.5.8)
710

811
Another bug-fix release that mainly fixes a regression wih Python 2 that has

pyfakefs/fake_filesystem.py

+45
Original file line numberDiff line numberDiff line change
@@ -3738,13 +3738,27 @@ def write(self, file_des, contents):
37383738
file_handle = self.filesystem.get_open_file(file_des)
37393739
if isinstance(file_handle, FakeDirWrapper):
37403740
self.filesystem.raise_os_error(errno.EBADF, file_handle.file_path)
3741+
3742+
if isinstance(file_handle, FakePipeWrapper):
3743+
return file_handle.write(contents)
3744+
37413745
file_handle.raw_io = True
37423746
file_handle._sync_io()
37433747
file_handle.update_flush_pos()
37443748
file_handle.write(contents)
37453749
file_handle.flush()
37463750
return len(contents)
37473751

3752+
def pipe(self):
3753+
read_fd, write_fd = os.pipe()
3754+
read_wrapper = FakePipeWrapper(self.filesystem, read_fd)
3755+
file_des = self.filesystem._add_open_file(read_wrapper)
3756+
read_wrapper.filedes = file_des
3757+
write_wrapper = FakePipeWrapper(self.filesystem, write_fd)
3758+
file_des = self.filesystem._add_open_file(write_wrapper)
3759+
write_wrapper.filedes = file_des
3760+
return read_wrapper.filedes, write_wrapper.filedes
3761+
37483762
@staticmethod
37493763
def stat_float_times(newvalue=None):
37503764
"""Determine whether a file's time stamps are reported as floats
@@ -5019,6 +5033,37 @@ def close(self):
50195033
self._filesystem._close_open_file(self.filedes)
50205034

50215035

5036+
class FakePipeWrapper(object):
5037+
"""Wrapper for a read or write descriptor of a real pipe object to be
5038+
used in open files list.
5039+
"""
5040+
5041+
def __init__(self, filesystem, fd):
5042+
self._filesystem = filesystem
5043+
self.fd = fd # the real file descriptor
5044+
self.filedes = None
5045+
5046+
def get_object(self):
5047+
return None
5048+
5049+
def fileno(self):
5050+
"""Return the fake file descriptor of the pipe object."""
5051+
return self.filedes
5052+
5053+
def read(self, numBytes):
5054+
"""Read from the real pipe."""
5055+
return os.read(self.fd, numBytes)
5056+
5057+
def write(self, contents):
5058+
"""Write to the real pipe."""
5059+
return os.write(self.fd, contents)
5060+
5061+
def close(self):
5062+
"""Close the pipe descriptor."""
5063+
self._filesystem.open_files[self.filedes].remove(self)
5064+
os.close(self.fd)
5065+
5066+
50225067
Deprecator.add(FakeFileWrapper, FakeFileWrapper.get_object, 'GetObject')
50235068
Deprecator.add(FakeFileWrapper, FakeFileWrapper.size, 'Size')
50245069

pyfakefs/tests/fake_os_test.py

+36
Original file line numberDiff line numberDiff line change
@@ -2649,6 +2649,42 @@ def test_open_umask_applied(self):
26492649
self.open(file2, 'w').close()
26502650
self.assert_mode_equal(0o640, self.os.stat(file2).st_mode)
26512651

2652+
def test_open_pipe(self):
2653+
read_fd, write_fd = self.os.pipe()
2654+
self.os.close(read_fd)
2655+
self.os.close(write_fd)
2656+
2657+
def test_open_pipe_with_existing_fd(self):
2658+
file1 = self.make_path('file1')
2659+
fd = self.os.open(file1, os.O_CREAT)
2660+
read_fd, write_fd = self.os.pipe()
2661+
self.assertGreater(read_fd, fd)
2662+
self.os.close(fd)
2663+
self.os.close(read_fd)
2664+
self.os.close(write_fd)
2665+
2666+
def test_open_file_with_existing_pipe(self):
2667+
read_fd, write_fd = self.os.pipe()
2668+
file1 = self.make_path('file1')
2669+
fd = self.os.open(file1, os.O_CREAT)
2670+
self.assertGreater(fd, write_fd)
2671+
self.os.close(read_fd)
2672+
self.os.close(write_fd)
2673+
self.os.close(fd)
2674+
2675+
def test_write_to_pipe(self):
2676+
read_fd, write_fd = self.os.pipe()
2677+
self.os.write(write_fd, b'test')
2678+
self.assertEqual(b'test', self.os.read(read_fd, 4))
2679+
self.os.close(read_fd)
2680+
self.os.close(write_fd)
2681+
2682+
def test_write_to_read_fd(self):
2683+
read_fd, write_fd = self.os.pipe()
2684+
self.assert_raises_os_error(errno.EBADF,
2685+
self.os.write, read_fd, b'test')
2686+
self.os.close(read_fd)
2687+
self.os.close(write_fd)
26522688

26532689
class RealOsModuleTest(FakeOsModuleTest):
26542690
def use_real_fs(self):

0 commit comments

Comments
 (0)