docs: def read_frames(cls, reader):
          '''
          Read one or more frames from an IO stream.  Buffer must support file
          object interface.
  
          After reading, caller will need to check if there are bytes remaining
          in the stream. If there are, then that implies that there is one or
          more incomplete frames and more data needs to be read.  The position
          of the cursor in the frame stream will mark the point at which the
          last good frame was read. If the caller is expecting a sequence of
          frames and only received a part of that sequence, they are responsible
          for buffering those frames until the rest of the frames in the sequence
          have arrived.
          '''
          rval = deque()
  
          while True:
              frame_start_pos = reader.tell()
              try:
                  frame = Frame._read_frame(reader)
              except Reader.BufferUnderflow:
                  # No more data in the stream
                  frame = None
              except Reader.ReaderError as e:
                  # Some other format error
                  raise Frame.FormatError, str(e), sys.exc_info()[-1]
              except struct.error as e:
                  raise Frame.FormatError, str(e), sys.exc_info()[-1]
  
              if frame is None:
                  reader.seek(frame_start_pos)
                  break
  
              rval.append(frame)
  
          return rval