[Python-checkins] cpython: Closes #20218: Added convenience methods read_text/write_text and read_bytes/

georg.brandl python-checkins at python.org
Wed Oct 1 19:14:36 CEST 2014


https://hg.python.org/cpython/rev/a4da150fbfd4
changeset:   92713:a4da150fbfd4
user:        Georg Brandl <georg at python.org>
date:        Wed Oct 01 19:12:33 2014 +0200
summary:
  Closes #20218: Added convenience methods read_text/write_text and read_bytes/
write_bytes to pathlib.Path objects.

Thanks to Christopher Welborn and Ram Rachum for original patches.

files:
  Doc/library/pathlib.rst  |  61 ++++++++++++++++++++++++++++
  Lib/pathlib.py           |  33 +++++++++++++++
  Lib/test/test_pathlib.py |  17 +++++++
  Misc/NEWS                |   3 +
  4 files changed, 114 insertions(+), 0 deletions(-)


diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst
--- a/Doc/library/pathlib.rst
+++ b/Doc/library/pathlib.rst
@@ -834,6 +834,34 @@
    if the file's uid isn't found in the system database.
 
 
+.. method:: Path.read_bytes()
+
+   Return the binary contents of the pointed-to file as a bytes object::
+
+      >>> p = Path('my_binary_file')
+      >>> p.write_bytes(b'Binary file contents')
+      20
+      >>> p.read_bytes()
+      b'Binary file contents'
+
+   .. versionadded:: 3.5
+
+
+.. method:: Path.read_text(encoding=None, errors=None)
+
+   Return the decoded contents of the pointed-to file as a string::
+
+      >>> p = Path('my_text_file')
+      >>> p.write_text('Text file contents')
+      18
+      >>> p.read_text()
+      'Text file contents'
+
+   The optional parameters have the same meaning as in :func:`open`.
+
+   .. versionadded:: 3.5
+
+
 .. method:: Path.rename(target)
 
    Rename this file or directory to the given *target*.  *target* can be
@@ -946,3 +974,36 @@
 
    Remove this file or symbolic link.  If the path points to a directory,
    use :func:`Path.rmdir` instead.
+
+
+.. method:: Path.write_bytes(data)
+
+   Open the file pointed to in bytes mode, write *data* to it, and close the
+   file::
+
+      >>> p = Path('my_binary_file')
+      >>> p.write_bytes(b'Binary file contents')
+      20
+      >>> p.read_bytes()
+      b'Binary file contents'
+
+   An existing file of the same name is overwritten.
+
+   .. versionadded:: 3.5
+
+
+.. method:: Path.write_text(data, encoding=None, errors=None)
+
+   Open the file pointed to in text mode, write *data* to it, and close the
+   file::
+
+      >>> p = Path('my_text_file')
+      >>> p.write_text('Text file contents')
+      18
+      >>> p.read_text()
+      'Text file contents'
+
+   An existing file of the same name is overwritten.  The optional parameters
+   have the same meaning as in :func:`open`.
+
+   .. versionadded:: 3.5
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -1083,6 +1083,39 @@
         return io.open(str(self), mode, buffering, encoding, errors, newline,
                        opener=self._opener)
 
+    def read_bytes(self):
+        """
+        Open the file in bytes mode, read it, and close the file.
+        """
+        with self.open(mode='rb') as f:
+            return f.read()
+
+    def read_text(self, encoding=None, errors=None):
+        """
+        Open the file in text mode, read it, and close the file.
+        """
+        with self.open(mode='r', encoding=encoding, errors=errors) as f:
+            return f.read()
+
+    def write_bytes(self, data):
+        """
+        Open the file in bytes mode, write to it, and close the file.
+        """
+        # type-check for the buffer interface before truncating the file
+        view = memoryview(data)
+        with self.open(mode='wb') as f:
+            return f.write(view)
+
+    def write_text(self, data, encoding=None, errors=None):
+        """
+        Open the file in text mode, write to it, and close the file.
+        """
+        if not isinstance(data, str):
+            raise TypeError('data must be str, not %s' %
+                            data.__class__.__name__)
+        with self.open(mode='w', encoding=encoding, errors=errors) as f:
+            return f.write(data)
+
     def touch(self, mode=0o666, exist_ok=True):
         """
         Create this file with the given access mode, if it doesn't exist.
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -1310,6 +1310,23 @@
             self.assertIsInstance(f, io.RawIOBase)
             self.assertEqual(f.read().strip(), b"this is file A")
 
+    def test_read_write_bytes(self):
+        p = self.cls(BASE)
+        (p / 'fileA').write_bytes(b'abcdefg')
+        self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg')
+        # check that trying to write str does not truncate the file
+        self.assertRaises(TypeError, (p / 'fileA').write_bytes, 'somestr')
+        self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg')
+
+    def test_read_write_text(self):
+        p = self.cls(BASE)
+        (p / 'fileA').write_text('äbcdefg', encoding='latin-1')
+        self.assertEqual((p / 'fileA').read_text(
+            encoding='utf-8', errors='ignore'), 'bcdefg')
+        # check that trying to write bytes does not truncate the file
+        self.assertRaises(TypeError, (p / 'fileA').write_text, b'somebytes')
+        self.assertEqual((p / 'fileA').read_text(encoding='latin-1'), 'äbcdefg')
+
     def test_iterdir(self):
         P = self.cls
         p = P(BASE)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -156,6 +156,9 @@
 Library
 -------
 
+- Issue #20218: Added convenience methods read_text/write_text and read_bytes/
+  write_bytes to pathlib.Path objects.
+
 - Issue #22437: Number of capturing groups in regular expression is no longer
   limited by 100.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list