Mock stream that simulates short reads from a pipe. This simulates the behavior of Unix pipes when reading data larger than the pipe buffer (typically 64KB). The read() method will return fewer bytes than requested, requiring multiple read calls.
| 29 | |
| 30 | |
| 31 | class ShortReadStream: |
| 32 | """ |
| 33 | Mock stream that simulates short reads from a pipe. |
| 34 | |
| 35 | This simulates the behavior of Unix pipes when reading data larger than |
| 36 | the pipe buffer (typically 64KB). The read() method will return fewer |
| 37 | bytes than requested, requiring multiple read calls. |
| 38 | """ |
| 39 | |
| 40 | def __init__(self, data: bytes, chunk_size: int = 32768): |
| 41 | """ |
| 42 | Args: |
| 43 | data: Complete data to be read |
| 44 | chunk_size: Maximum bytes to return per read() call (simulates pipe buffer) |
| 45 | """ |
| 46 | self.data = data |
| 47 | self.chunk_size = chunk_size |
| 48 | self.pos = 0 |
| 49 | |
| 50 | def readline(self): |
| 51 | """Read until newline""" |
| 52 | end = self.data.find(b"\n", self.pos) + 1 |
| 53 | if end == 0: # Not found |
| 54 | result = self.data[self.pos :] |
| 55 | self.pos = len(self.data) |
| 56 | else: |
| 57 | result = self.data[self.pos : end] |
| 58 | self.pos = end |
| 59 | return result |
| 60 | |
| 61 | def read(self, n: int) -> bytes: |
| 62 | """ |
| 63 | Read at most n bytes, but may return fewer (short read). |
| 64 | |
| 65 | This simulates the behavior of pipes when data exceeds buffer size. |
| 66 | """ |
| 67 | # Calculate how much we can return (limited by chunk_size) |
| 68 | available = len(self.data) - self.pos |
| 69 | to_read = min(n, available, self.chunk_size) |
| 70 | |
| 71 | result = self.data[self.pos : self.pos + to_read] |
| 72 | self.pos += to_read |
| 73 | return result |
| 74 | |
| 75 | |
| 76 | class TestReadExact: |
no outgoing calls
searching dependent graphs…