New submission from twisteroid ambassador <twisteroid.ambassa...@gmail.com>:

Currently, if one attempts to do write_eof() on a StreamWriter after the 
underlying transport is already closed, an AttributeError is raised:


Traceback (most recent call last):
  File "<snip>\scratch_3.py", line 34, in main_coro
    writer.write_eof()
  File "C:\Program Files\Python36\lib\asyncio\streams.py", line 300, in 
write_eof
    return self._transport.write_eof()
  File "C:\Program Files\Python36\lib\asyncio\selector_events.py", line 808, in 
write_eof
    self._sock.shutdown(socket.SHUT_WR)
AttributeError: 'NoneType' object has no attribute 'shutdown'


This is because _SelectorSocketTransport.write_eof() only checks for self._eof 
before calling self._sock.shutdown(), and self._sock has already been assigned 
None after _call_connection_lost().

Compare with StreamWriter.write() after close, which either does nothing or 
logs a warning after 5 attempts; or StreamWriter.drain() after close, which 
raises a ConnectionResetError; or even StreamWriter.close() after close, which 
does nothing.

Trying to do write_eof() after close may happen unintentionally, for example 
when the following sequence of events happen:
* the remote side closes the connection
* the local side attempts to write, so the socket "figures out" the connection 
is closed, and close this side of the socket. Note the write fails silently, 
except when loop.set_debug(True) where asyncio logs "Fatal write error on 
socket transport".
* the local side does write_eof(). An AttributError is raised.

Currently the only way to handle this gracefully is to either catch 
AttributeError or check StreamWriter.transport.is_closing() before write_eof(). 
Neither is pretty.

I suggest making write_eof() after close either do nothing, or raise a subclass 
of ConnectionError. Both will be easier to handle then the current behavior.

Attached repro.

----------
components: asyncio
files: asyncio_write_eof_after_close_test.py
messages: 303391
nosy: twisteroid ambassador, yselivanov
priority: normal
severity: normal
status: open
title: asyncio: StreamWriter write_eof() after close raises mysterious 
AttributeError
type: behavior
versions: Python 3.4, Python 3.5, Python 3.6, Python 3.7, Python 3.8
Added file: 
https://bugs.python.org/file47180/asyncio_write_eof_after_close_test.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue31647>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to