Skip to content

Add os.readinto API for reading data into a caller provided buffer#129205

@cmaloney

Description

@cmaloney

Feature or enhancement

Proposal:

Code reading data in pure python tends to make a buffer variable, call os.read() which returns a separate newly allocated buffer of data, then copy/append that data onto the pre-allocated buffer[0]. That creates unnecessary extra buffer objects, as well as unnecessary copies. Provide os.readinto for directly filling a Buffer Protocol object.

os.readinto should closely mirror _Py_read which underlies os.read in order to get the same behaviors around retries as well as well-tested cross-platform support.

Move simple cases that use os.read (ex. [0]) to use the new API when it makes code simpler and more efficient. Potentially adding readinto to more readable/writeable file-like proxy objects or objects which transform the data (ex. Lib/_compression) is out of scope for this issue.

[0]

cpython/Lib/subprocess.py

Lines 1914 to 1921 in 298dda5

# Wait for exec to fail or succeed; possibly raising an
# exception (limited in size)
errpipe_data=bytearray()
whileTrue:
part=os.read(errpipe_read, 50000)
errpipe_data+=part
ifnotpartorlen(errpipe_data) >50000:
break

defread_signed(fd):
data=b''
length=SIGNED_STRUCT.size
whilelen(data) <length:
s=os.read(fd, length-len(data))
ifnots:
raiseEOFError('unexpected EOF')
data+=s
returnSIGNED_STRUCT.unpack(data)[0]

cpython/Lib/_pyio.py

Lines 1695 to 1701 in 298dda5

defreadinto(self, b):
"""Same as RawIOBase.readinto()."""
m=memoryview(b).cast('B')
data=self.read(len(m))
n=len(data)
m[:n] =data
returnn

os.read loops to migrate

Well contained os.read loops

os.read loop interleaved with other code

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

#129005 (comment)

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions