pythonencodingword-wrapreadlines

How to create and write to a textiowrapper and readlines


So I am trying to create a text io wrapper that I can then use readlines() from for a unittest. Here is my attempt, but when I run it the readlines() returns nothing:

output = io.BytesIO()
wrapper =  io.TextIOWrapper(
 output,
 encoding='cp1252',
 line_buffering=True,
 )

wrapper.write('Text1')
wrapper.write('Text2')
wrapper.write('Text3')
wrapper.write('Text4')

for line in wrapper.readlines():
    print(line)

What do I need to change to get this output:

 Text1
 Text2
 Text3
 Text4

Solution

  • Read about TextIOWrapper class in the io module documentation:

    A buffered text stream over a BufferedIOBase binary stream.

    Edit: use seek function:

    seek(offset[, whence])
    

    Change the stream position to the given byte offset. offset is interpreted relative to the position indicated by whence. The default value for whence is SEEK_SET. Values for whence are:

    • SEEK_SET or 0 – start of the stream (the default); offset should be zero or positive
    • SEEK_CUR or 1 – current stream position; offset may be negative
    • SEEK_END or 2 – end of the stream; offset is usually negative

    Return the new absolute position.

    New in version 3.1: The SEEK_* constants.

    New in version 3.3: Some operating systems could support additional values, like os.SEEK_HOLE or os.SEEK_DATA. The valid values for a file could depend on it being open in text or binary mode.

    Try the following commented code snippet:

    import io, os
    output  = io.BytesIO()
    wrapper = io.TextIOWrapper(
     output,
     encoding='cp1252',
     # errors=None,         #  default
     # newline=None,        #  default
     line_buffering=True,
     # write_through=False  #  default
     )
    
    wrapper.write('Text1\n')
    wrapper.write('Text2\n')
    wrapper.write('Text3\n')
    # wrapper.flush()                #  If line_buffering is True, flush() is implied
                                     ## when a call to write contains a newline character.
    
    wrapper.seek(0,0)                #  start of the stream
    for line in wrapper.readlines():
        print(line)
    

    The rest of my original answer:

    print(output.getvalue())         # for debugging purposes
    
    print( wrapper.write('Text4\n')) #  for debugging purposes
    
    # for line in wrapper.read():
    for line in output.getvalue().decode('cp1252').split(os.linesep):
        print(line)
    

    Output:

    ==> D:\test\Python\q44702487.py
    b'Text1\r\nText2\r\nText3\r\n'
    6
    Text1
    Text2
    Text3
    Text4
    
    ==>