Spurious "unclosed transport" and "Exception ignored in" message when connecting Unix pipes #368
Description
If connect_read_pipe() or connect_write_pipe() is called with an object which is not a pipe, socket, or character device, a ValueError is raised indicating that other file types are not allowed. However, the partially constructed transport object triggers an incorrect "unclosed transport" error when del is called on it, and another exception is raised during that call due to the "_closing" member variable having not yet been set due to the constructor never finishing. Here's a test program which reproduces this:
import asyncio
class Writer:
pass
async def run(loop):
f = open('/tmp/x', 'wb')
try:
transport, protocol = await loop.connect_write_pipe(Writer, f)
except ValueError as exc:
print('Exception:', exc)
loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))
loop.close()
Here's the output I get when running this with Python 3.5.2:
Exception: Pipe transport is only for pipes, sockets and character devices
Exception ignored in: <object repr() failed>
Traceback (most recent call last):
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/unix_events.py", line 576, in __del__
warnings.warn("unclosed transport %r" % self, ResourceWarning)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/unix_events.py", line 456, in __repr__
elif self._closing:
AttributeError: '_UnixWritePipeTransport' object has no attribute '_closing'
The first line of output is expected, but the "Exception ignored in" message is the problem.
Before Python 3.5.2, this would show up as an "Exception ignored in " message with no traceback, due to another exception raised when calling repr() on this object. This is also related to _closing not having been set yet.
It would be good to set always set _closing before any exception is raised, and probably not set _pipe until after this, so the "unclosed transport" message won't be triggered in del().