mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-26826: Expose copy_file_range in the os module (GH-7255)
This commit is contained in:
parent
545a3b8814
commit
aac4d0342c
9 changed files with 363 additions and 19 deletions
|
@ -231,6 +231,89 @@ class FileTests(unittest.TestCase):
|
|||
except (NotImplementedError, OSError):
|
||||
pass # No OS support or unprivileged user
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()')
|
||||
def test_copy_file_range_invalid_values(self):
|
||||
with self.assertRaises(ValueError):
|
||||
os.copy_file_range(0, 1, -10)
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()')
|
||||
def test_copy_file_range(self):
|
||||
TESTFN2 = support.TESTFN + ".3"
|
||||
data = b'0123456789'
|
||||
|
||||
create_file(support.TESTFN, data)
|
||||
self.addCleanup(support.unlink, support.TESTFN)
|
||||
|
||||
in_file = open(support.TESTFN, 'rb')
|
||||
self.addCleanup(in_file.close)
|
||||
in_fd = in_file.fileno()
|
||||
|
||||
out_file = open(TESTFN2, 'w+b')
|
||||
self.addCleanup(support.unlink, TESTFN2)
|
||||
self.addCleanup(out_file.close)
|
||||
out_fd = out_file.fileno()
|
||||
|
||||
try:
|
||||
i = os.copy_file_range(in_fd, out_fd, 5)
|
||||
except OSError as e:
|
||||
# Handle the case in which Python was compiled
|
||||
# in a system with the syscall but without support
|
||||
# in the kernel.
|
||||
if e.errno != errno.ENOSYS:
|
||||
raise
|
||||
self.skipTest(e)
|
||||
else:
|
||||
# The number of copied bytes can be less than
|
||||
# the number of bytes originally requested.
|
||||
self.assertIn(i, range(0, 6));
|
||||
|
||||
with open(TESTFN2, 'rb') as in_file:
|
||||
self.assertEqual(in_file.read(), data[:i])
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()')
|
||||
def test_copy_file_range_offset(self):
|
||||
TESTFN4 = support.TESTFN + ".4"
|
||||
data = b'0123456789'
|
||||
bytes_to_copy = 6
|
||||
in_skip = 3
|
||||
out_seek = 5
|
||||
|
||||
create_file(support.TESTFN, data)
|
||||
self.addCleanup(support.unlink, support.TESTFN)
|
||||
|
||||
in_file = open(support.TESTFN, 'rb')
|
||||
self.addCleanup(in_file.close)
|
||||
in_fd = in_file.fileno()
|
||||
|
||||
out_file = open(TESTFN4, 'w+b')
|
||||
self.addCleanup(support.unlink, TESTFN4)
|
||||
self.addCleanup(out_file.close)
|
||||
out_fd = out_file.fileno()
|
||||
|
||||
try:
|
||||
i = os.copy_file_range(in_fd, out_fd, bytes_to_copy,
|
||||
offset_src=in_skip,
|
||||
offset_dst=out_seek)
|
||||
except OSError as e:
|
||||
# Handle the case in which Python was compiled
|
||||
# in a system with the syscall but without support
|
||||
# in the kernel.
|
||||
if e.errno != errno.ENOSYS:
|
||||
raise
|
||||
self.skipTest(e)
|
||||
else:
|
||||
# The number of copied bytes can be less than
|
||||
# the number of bytes originally requested.
|
||||
self.assertIn(i, range(0, bytes_to_copy+1));
|
||||
|
||||
with open(TESTFN4, 'rb') as in_file:
|
||||
read = in_file.read()
|
||||
# seeked bytes (5) are zero'ed
|
||||
self.assertEqual(read[:out_seek], b'\x00'*out_seek)
|
||||
# 012 are skipped (in_skip)
|
||||
# 345678 are copied in the file (in_skip + bytes_to_copy)
|
||||
self.assertEqual(read[out_seek:],
|
||||
data[in_skip:in_skip+i])
|
||||
|
||||
# Test attributes on return values from os.*stat* family.
|
||||
class StatAttributeTests(unittest.TestCase):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue