'Asynchronously write the given data to this stream.
If ``callback`` is given, we call it when all of the buffered write
data has been successfully written to the stream. If there was
previously buffered write data and an old write callback, that
callback is simply overwritten with this new callback.
If no ``callback`` is given, this method returns a `.Future` that
resolves (with a result of ``None``) when the write has been
completed.
The ``data`` argument may be of type `bytes` or `memoryview`.
.. versionchanged:: 4.0
Now returns a `.Future` if no callback is given.
.. versionchanged:: 4.5
Added support for `memoryview` arguments.'

def write(self, data, callback=None):

    self._check_closed()
    if data:
        if ((self.max_write_buffer_size is not None) and ((self._write_buffer_size + len(data)) > self.max_write_buffer_size)):
            raise StreamBufferFullError('Reached    maximum    write    buffer    size')
        if self._write_buffer_frozen:
            self._pending_writes_while_frozen.append(data)
        else:
            self._write_buffer += data
            self._write_buffer_size += len(data)
        self._total_write_index += len(data)
    if (callback is not None):
        self._write_callback = stack_context.wrap(callback)
        future = None
    else:
        future = TracebackFuture()
        future.add_done_callback((lambda f: f.exception()))
        self._write_futures.append((self._total_write_index, future))
    if (not self._connecting):
        self._handle_write()
        if self._write_buffer_size:
            self._add_io_state(self.io_loop.WRITE)
        self._maybe_add_error_listener()
    return future
