Skip to content

Commit 3abe457

Browse files
committed
Add support for os.readinto in Python 3.14
1 parent d074a35 commit 3abe457

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

CHANGES.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,27 @@ The released versions correspond to PyPI releases.
1313
the real filesystem behavior
1414
* remove support for Python versions before 3.10 (if needed, patches may be backported to the 5.x branch)
1515

16-
### Unreleased
16+
## Unreleased
1717

1818
## Changes
1919
* the `errno` codes set in `OSError` have changed for some specific error conditions
2020
in Windows 11/Windows Server 2025; pyfakefs now matches this behavior
2121
instead of the previous behavior under Windows 10
2222

23-
## Fixes
23+
### Enhancements
24+
* added support for `os.readinto` in Python 3.14
25+
26+
### Fixes
2427
* fixes patching of Debian-specific `tempfile` in Python 3.13 (see [#1214](../../issues/1214))
2528

2629
## [Version 5.9.3](https://pypi.python.org/pypi/pyfakefs/5.9.3) (2025-08-28)
2730
Fixes a utility method.
2831

29-
## Changes
32+
### Changes
3033
* a warning is now issued if trying to create a nested fake filesystem with custom arguments
3134
(custom arguments are ignored in this case, as the existing fake filesystem is used)
3235

33-
## Fixes
36+
### Fixes
3437
* fixed `fake_filesystem.add_package_metadata` that had never worked correctly
3538
(see [#1205](../../issues/1205))
3639

pyfakefs/fake_os.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,16 @@ def getgid(self) -> int:
14061406
raise NameError("name 'getgid' is not defined")
14071407
return get_gid()
14081408

1409+
if sys.version_info >= (3, 14):
1410+
1411+
def readinto(self, fd, buffer):
1412+
"""Read from a file descriptor fd into a mutable buffer object buffer."""
1413+
wrapper = self.filesystem.get_open_file(fd)
1414+
contents = wrapper.read(len(buffer))
1415+
count = len(contents)
1416+
buffer[:count] = contents
1417+
return count
1418+
14091419
def fake_functions(self, original_functions) -> Set:
14101420
functions = set()
14111421
for fn in original_functions:

pyfakefs/tests/fake_os_test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3076,6 +3076,25 @@ def test_dup2_with_new_fd(self):
30763076
self.assertEqual(fd1 + 1, fd3)
30773077
self.assertEqual(fd1 + 3, fd4)
30783078

3079+
@unittest.skipIf(sys.version_info < (3, 14), "Introduced in Python 3.14")
3080+
def test_readinto(self):
3081+
file_path = self.make_path("foo", "bar.txt")
3082+
contents = b"Testing readinto"
3083+
self.create_file(file_path, contents=contents)
3084+
fd = self.os.open(file_path, os.O_RDONLY)
3085+
try:
3086+
buffer = bytearray(b"")
3087+
self.assertEqual(0, self.os.readinto(fd, buffer))
3088+
buffer = bytearray(b" " * 20)
3089+
self.assertEqual(len(contents), self.os.readinto(fd, buffer))
3090+
self.assertEqual(b"Testing readinto ", buffer)
3091+
self.assertEqual(0, self.os.readinto(fd, buffer))
3092+
self.os.lseek(fd, 5, os.SEEK_SET)
3093+
self.assertEqual(len(contents) - 5, self.os.readinto(fd, buffer))
3094+
self.assertEqual(b"ng readintodinto ", buffer)
3095+
finally:
3096+
self.os.close(fd)
3097+
30793098

30803099
class RealOsModuleTest(FakeOsModuleTest):
30813100
def use_real_fs(self):

0 commit comments

Comments
 (0)