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.
This commit is contained in:
parent
5c4725e5bc
commit
ea68398355
|
@ -834,6 +834,34 @@ call fails (for example because the path doesn't exist):
|
|||
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 @@ call fails (for example because the path doesn't exist):
|
|||
|
||||
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
|
||||
|
|
|
@ -1083,6 +1083,39 @@ class Path(PurePath):
|
|||
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.
|
||||
|
|
|
@ -1310,6 +1310,23 @@ class _BasePathTest(object):
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue