(self, data)
| 336 | self._empty_waiter = None |
| 337 | |
| 338 | def write(self, data): |
| 339 | if not isinstance(data, (bytes, bytearray, memoryview)): |
| 340 | raise TypeError( |
| 341 | f"data argument must be a bytes-like object, " |
| 342 | f"not {type(data).__name__}") |
| 343 | if self._eof_written: |
| 344 | raise RuntimeError('write_eof() already called') |
| 345 | if self._empty_waiter is not None: |
| 346 | raise RuntimeError('unable to write; sendfile is in progress') |
| 347 | |
| 348 | if not data: |
| 349 | return |
| 350 | |
| 351 | if self._conn_lost: |
| 352 | if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES: |
| 353 | logger.warning('socket.send() raised exception.') |
| 354 | self._conn_lost += 1 |
| 355 | return |
| 356 | |
| 357 | # Observable states: |
| 358 | # 1. IDLE: _write_fut and _buffer both None |
| 359 | # 2. WRITING: _write_fut set; _buffer None |
| 360 | # 3. BACKED UP: _write_fut set; _buffer a bytearray |
| 361 | # We always copy the data, so the caller can't modify it |
| 362 | # while we're still waiting for the I/O to happen. |
| 363 | if self._write_fut is None: # IDLE -> WRITING |
| 364 | assert self._buffer is None |
| 365 | # Pass a copy, except if it's already immutable. |
| 366 | self._loop_writing(data=bytes(data)) |
| 367 | elif not self._buffer: # WRITING -> BACKED UP |
| 368 | # Make a mutable copy which we can extend. |
| 369 | self._buffer = bytearray(data) |
| 370 | self._maybe_pause_protocol() |
| 371 | else: # BACKED UP |
| 372 | # Append to buffer (also copies). |
| 373 | self._buffer.extend(data) |
| 374 | self._maybe_pause_protocol() |
| 375 | |
| 376 | def _loop_writing(self, f=None, data=None): |
| 377 | try: |
nothing calls this directly
no test coverage detected