code: def fill(self, source, size=-1):
          
          size = size if size >= 0 else self._chunk_size
          size = min(size, self._chunk_size)
  
          if self._pos != 0:
              self._bytes = self._bytes[self._pos:]
              self._pos = 0
  
          if hasattr(source, 'read'):
              new_bytes = source.read(size)
          else:
              new_bytes = b''
              for more_bytes in source:
                  new_bytes += more_bytes
                  if len(new_bytes) >= size:
                      break
  
          self._bytes += new_bytes
          return len(new_bytes)
docs: Fill the buffer with bytes from source until one of these
          conditions is met:
              * size bytes have been read from source (if size >= 0);
              * chunk_size bytes have been read from source;
              * no more bytes can be read from source;
          Returns the number of new bytes added to the buffer.
          Note: all previously-read bytes in the buffer are removed.
  
          Parameters
          ----------
          source: a file-like object, or iterable/list that contains bytes
              The source of bytes to fill the buffer with. If this argument has
              the `read` attribute, it's assumed to be a file-like object and
              `read` is called to get the bytes; otherwise it's assumed to be an
              iterable or list that contains bytes, and a for loop is used to get
              the bytes.
          size: int, optional
              The number of bytes to try to read from source. If not supplied,
              negative, or larger than the buffer's chunk_size, then chunk_size
              bytes are read. Note that if source is an iterable or list, then
              it's possible that more than size bytes will be read if iterating
              over source produces more than one byte at a time.
  
          Returns
          -------
          int, the number of new bytes added to the buffer.