Skip to content

Commit

Permalink
Added support for os.pipe
Browse files Browse the repository at this point in the history
  • Loading branch information
mrbean-bremen committed Mar 27, 2019
1 parent 67a57fa commit 78543fb
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ The release versions are PyPi releases.

## Version 3.6 (as yet unreleased)

#### New Features
* added support for `os.pipe` (see [#473](../../issues/473))

## [Version 3.5.8](https://pypi.python.org/pypi/pyfakefs/3.5.8)

Another bug-fix release that mainly fixes a regression wih Python 2 that has
Expand Down
45 changes: 45 additions & 0 deletions pyfakefs/fake_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -3738,13 +3738,27 @@ def write(self, file_des, contents):
file_handle = self.filesystem.get_open_file(file_des)
if isinstance(file_handle, FakeDirWrapper):
self.filesystem.raise_os_error(errno.EBADF, file_handle.file_path)

if isinstance(file_handle, FakePipeWrapper):
return file_handle.write(contents)

file_handle.raw_io = True
file_handle._sync_io()
file_handle.update_flush_pos()
file_handle.write(contents)
file_handle.flush()
return len(contents)

def pipe(self):
read_fd, write_fd = os.pipe()
read_wrapper = FakePipeWrapper(self.filesystem, read_fd)
file_des = self.filesystem._add_open_file(read_wrapper)
read_wrapper.filedes = file_des
write_wrapper = FakePipeWrapper(self.filesystem, write_fd)
file_des = self.filesystem._add_open_file(write_wrapper)
write_wrapper.filedes = file_des
return read_wrapper.filedes, write_wrapper.filedes

@staticmethod
def stat_float_times(newvalue=None):
"""Determine whether a file's time stamps are reported as floats
Expand Down Expand Up @@ -5019,6 +5033,37 @@ def close(self):
self._filesystem._close_open_file(self.filedes)


class FakePipeWrapper(object):
"""Wrapper for a read or write descriptor of a real pipe object to be
used in open files list.
"""

def __init__(self, filesystem, fd):
self._filesystem = filesystem
self.fd = fd # the real file descriptor
self.filedes = None

def get_object(self):
return None

def fileno(self):
"""Return the fake file descriptor of the pipe object."""
return self.filedes

def read(self, numBytes):
"""Read from the real pipe."""
return os.read(self.fd, numBytes)

def write(self, contents):
"""Write to the real pipe."""
return os.write(self.fd, contents)

def close(self):
"""Close the pipe descriptor."""
self._filesystem.open_files[self.filedes].remove(self)
os.close(self.fd)


Deprecator.add(FakeFileWrapper, FakeFileWrapper.get_object, 'GetObject')
Deprecator.add(FakeFileWrapper, FakeFileWrapper.size, 'Size')

Expand Down
36 changes: 36 additions & 0 deletions pyfakefs/tests/fake_os_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2649,6 +2649,42 @@ def test_open_umask_applied(self):
self.open(file2, 'w').close()
self.assert_mode_equal(0o640, self.os.stat(file2).st_mode)

def test_open_pipe(self):
read_fd, write_fd = self.os.pipe()
self.os.close(read_fd)
self.os.close(write_fd)

def test_open_pipe_with_existing_fd(self):
file1 = self.make_path('file1')
fd = self.os.open(file1, os.O_CREAT)
read_fd, write_fd = self.os.pipe()
self.assertGreater(read_fd, fd)
self.os.close(fd)
self.os.close(read_fd)
self.os.close(write_fd)

def test_open_file_with_existing_pipe(self):
read_fd, write_fd = self.os.pipe()
file1 = self.make_path('file1')
fd = self.os.open(file1, os.O_CREAT)
self.assertGreater(fd, write_fd)
self.os.close(read_fd)
self.os.close(write_fd)
self.os.close(fd)

def test_write_to_pipe(self):
read_fd, write_fd = self.os.pipe()
self.os.write(write_fd, b'test')
self.assertEqual(b'test', self.os.read(read_fd, 4))
self.os.close(read_fd)
self.os.close(write_fd)

def test_write_to_read_fd(self):
read_fd, write_fd = self.os.pipe()
self.assert_raises_os_error(errno.EBADF,
self.os.write, read_fd, b'test')
self.os.close(read_fd)
self.os.close(write_fd)

class RealOsModuleTest(FakeOsModuleTest):
def use_real_fs(self):
Expand Down

0 comments on commit 78543fb

Please sign in to comment.