bpo-31245: Asyncio unix socket datagram#3164
Conversation
Split the loop.create_unix_datagram_endpoint method into loop.create_unix_datagram_connection and loop.create_unix_datagram_server for cleaner API
| # Let's improve the error message by adding | ||
| # with what exact address it occurs. | ||
| msg = 'Address {!r} is already in use'.format(path) | ||
| raise OSError(errno.EADDRINUSE, msg) from None |
There was a problem hiding this comment.
This was made to improve the error message by including the address that failed the bind. I'm not sure chaining the exception will provide more information on the error.
| tr = self.socket_datagram_transport(waiter=waiter) | ||
| self.loop.run_until_complete(waiter) | ||
|
|
||
| self.loop.assert_reader(7, tr._read_ready) |
| raise TypeError('data argument must be a bytes-like object, ' | ||
| 'not %r' % type(data).__name__) | ||
| if not data: | ||
| return |
There was a problem hiding this comment.
Are you sure about the semantics? Can't you use send ("") as a cheap ping for example?
I suggest to remove this test.
There was a problem hiding this comment.
It seems to be working without the check. I wonder if it's also not necessary for the SelectorDatagramTransport
There was a problem hiding this comment.
That's correct – on a datagram socket, sending a packet with empty payload is totally legal, and is different from sending no packet at all.
| transport = self.socket_datagram_transport() | ||
| transport._closing = True | ||
| transport._buffer.append(data) | ||
| self.loop._add_writer(7, transport._send_ready) |
| coro = self.loop.create_unix_datagram_server(mock.MagicMock, | ||
| file.name) | ||
| with self.assertRaisesRegex(OSError, | ||
| 'Address.*is already in use'): |
There was a problem hiding this comment.
I would prefer to check the error code rather than the message.
There was a problem hiding this comment.
I will check both. So we make sure the error message is also correctly rewritten
| @@ -0,0 +1,2 @@ | |||
| Added `create_unix_datagram_connection` and `create_unix_datagram_server` to | |||
There was a problem hiding this comment.
Please mention asyncio. Maybe "asyncio: ...".
|
This is a ton of new code (mostly copy/pasted?) for what's basically just... changing one constant. At the very least can't you share |
+1. This should be refactored, and I wouldn't expect to see a patch that's longer than +- 50 lines of code. Also, please don't merge without my final review. |
|
Thanks for the feedback. I'll try to refactor to shorten the patch. Concerning the protocol I'm not sure on the direction to take. I could use the |
|
Well it appears I had some misconception about how unix datagram socket works. I think this patch is much more reasonable. Sorry for the mess it was previously. |
| elif hasattr(socket, 'AF_UNIX') and family == socket.AF_UNIX: | ||
| for addr in (local_addr, remote_addr): | ||
| if addr is not None: | ||
| assert isinstance(addr, str) |
There was a problem hiding this comment.
Make it a proper exception -- TypeError in this case.
1st1
left a comment
There was a problem hiding this comment.
Please resolve one remaining nit. Otherwise LGTM
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
|
I have made the requested changes; please review again |
|
Thanks for making the requested changes! @1st1: please review the changes made to this pull request. |
|
Thanks! |
See https://github.com/python/cpython/blob/main/Lib/asyncio/base_events.py#L1319 Support for unix sockets was added to this function in python 3.7: python/cpython#3164
Since python 3.7, asyncio.loop.create_datagram_endpoint expects the arguments `local_addr` and `remote_addr` to be `str` or `None` when the argument family=`socket.AF_UNIX` and the argument `sock` is `None` or also a unix socket. Here is a link to the relevant line in the standard library: https://github.com/python/cpython/blob/main/Lib/asyncio/base_events.py#L1319 And here is a link to the pull request for the change which introduced this in python 3.7: python/cpython#3164
https://bugs.python.org/issue31245