-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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
Lib/asyncio/unix_events.py
Outdated
# 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please chain the exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use self.sock_fd
Lib/asyncio/selector_events.py
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, use self.sock_fd
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to check the error code rather than the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
Lib/asyncio/base_events.py
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it a proper exception -- TypeError
in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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