docs: def read(self, length, timeout=None):
          """Read up to `length` number of bytes from the serial port with an
          optional timeout.
  
          `timeout` can be positive for a timeout in seconds, 0 for a
          non-blocking read, or negative or None for a blocking read that will
          block until `length` number of bytes are read. Default is a blocking
          read.
  
          For a non-blocking or timeout-bound read, read() may return data whose
          length is less than or equal to the requested length.
  
          Args:
              length (int): length in bytes.
              timeout (int, float, None): timeout duration in seconds.
  
          Returns:
              bytes: data read.
  
          Raises:
              SerialError: if an I/O or OS error occurs.
  
          """
          data = b""
  
          # Read length bytes if timeout is None
  
          # Read up to length bytes if timeout is not None
          while True:
              if timeout is not None:
                  # Select
                  (rlist, _, _) = select.select([self._fd], [], [], timeout)
                  # If timeout
                  if self._fd not in rlist:
                      break
  
              try:
                  data += os.read(self._fd, length - len(data))
              except OSError as e:
                  raise SerialError(e.errno, "Reading serial port: " + e.strerror)
  
              if len(data) == length:
                  break
  
          return data