diff --git a/CHANGELOG.md b/CHANGELOG.md index 562645b3..fa072e2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) @@ -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 diff --git a/fs/ftpfs.py b/fs/ftpfs.py index 11d2c4cc..6442a1ba 100644 --- a/fs/ftpfs.py +++ b/fs/ftpfs.py @@ -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): diff --git a/fs/memoryfs.py b/fs/memoryfs.py index 0814b2e0..2a011b21 100644 --- a/fs/memoryfs.py +++ b/fs/memoryfs.py @@ -75,6 +75,11 @@ def __str__(self): _template = "" 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] diff --git a/fs/test.py b/fs/test.py index 53ed290e..37751731 100644 --- a/fs/test.py +++ b/fs/test.py @@ -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()) @@ -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()) @@ -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()) @@ -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())