Skip to content

Commit

Permalink
Require FS.openbin to return a file-handle in binary mode (#435)
Browse files Browse the repository at this point in the history
* Add test to ensure mode of files opened with `openbin` contain `b` flag
* Fix `FTPFS.openbin` not implicitly converting mode to binary mode
* Add missing `mode` attribute to `_MemoryFile` objects
* Add missing type annotation to `_MemoryFile.mode` property
  • Loading branch information
althonos committed Oct 13, 2020
1 parent 9a8f94a commit 526438d
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [2.4.12] - (Unreleased)

### Added

- Missing `mode` attribute to `_MemoryFile` objects returned by `MemoryFS.openbin`.

### Changed

- Start testing on PyPy. Due to [#342](https://github.com/PyFilesystem/pyfilesystem2/issues/342)
Expand All @@ -23,6 +27,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Fixed documentation of `Mode.to_platform_bin`. Closes [#382](https://github.com/PyFilesystem/pyfilesystem2/issues/382).
- Fixed the code example in the "Testing Filesystems" section of the
"Implementing Filesystems" guide. Closes [#407](https://github.com/PyFilesystem/pyfilesystem2/issues/407).
- Fixed `FTPFS.openbin` not implicitly opening files in binary mode like expected
from `openbin`. Closes [#406](https://github.com/PyFilesystem/pyfilesystem2/issues/406).

## [2.4.11] - 2019-09-07

Expand Down
2 changes: 1 addition & 1 deletion fs/ftpfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ def openbin(self, path, mode="r", buffering=-1, **options):
raise errors.FileExpected(path)
if _mode.exclusive:
raise errors.FileExists(path)
ftp_file = FTPFile(self, _path, mode)
ftp_file = FTPFile(self, _path, _mode.to_platform_bin())
return ftp_file # type: ignore

def remove(self, path):
Expand Down
5 changes: 5 additions & 0 deletions fs/memoryfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ def __str__(self):
_template = "<memoryfile '{path}' '{mode}'>"
return _template.format(path=self._path, mode=self._mode)

@property
def mode(self):
# type: () -> Text
return self._mode.to_platform_bin()

@contextlib.contextmanager
def _seek_lock(self):
# type: () -> Iterator[None]
Expand Down
4 changes: 4 additions & 0 deletions fs/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@ def test_openbin_rw(self):

with self.fs.openbin("foo/hello", "w") as f:
repr(f)
self.assertIn("b", f.mode)
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.writable())
self.assertFalse(f.readable())
Expand All @@ -787,6 +788,7 @@ def test_openbin_rw(self):

# Read it back
with self.fs.openbin("foo/hello", "r") as f:
self.assertIn("b", f.mode)
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.readable())
self.assertFalse(f.writable())
Expand Down Expand Up @@ -927,6 +929,7 @@ def test_openbin(self):
with self.fs.openbin("file.bin", "wb") as write_file:
repr(write_file)
text_type(write_file)
self.assertIn("b", write_file.mode)
self.assertIsInstance(write_file, io.IOBase)
self.assertTrue(write_file.writable())
self.assertFalse(write_file.readable())
Expand All @@ -938,6 +941,7 @@ def test_openbin(self):
with self.fs.openbin("file.bin", "rb") as read_file:
repr(write_file)
text_type(write_file)
self.assertIn("b", read_file.mode)
self.assertIsInstance(read_file, io.IOBase)
self.assertTrue(read_file.readable())
self.assertFalse(read_file.writable())
Expand Down

0 comments on commit 526438d

Please sign in to comment.