-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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-35934: Add socket.create_server() utility function #11784
Conversation
…REUSEPORT is not supported
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 like the proposal but have a few comments regarding implementation.
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.
added reuse_addr
parameter
Hum, the constant is used in the following example: Do we miss some header files? |
Yes it appears we miss some constants on Windows. That is being tracked here: |
Doc/library/socket.rst
Outdated
@@ -595,6 +595,53 @@ The following functions all create :ref:`socket objects <socket-objects>`. | |||
.. versionchanged:: 3.2 | |||
*source_address* was added. | |||
|
|||
.. function:: create_server(address, *, family=AF_INET, backlog=0, reuse_port=False, dualstack_ipv6=False) | |||
|
|||
Convenience function which creates a :data:`SOCK_STREAM` type socket |
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.
Any reason why you don't just say it creates a TCP socket? I think this is guaranteed by Posix for AF_INET and AF_INET6 with SOCK_STREAM and proto set to zero.
Doc/library/socket.rst
Outdated
.. function:: has_dualstack_ipv6() | ||
|
||
Return ``True`` if the platform supports creating a :data:`SOCK_STREAM` | ||
socket which can handle both :data:`AF_INET` or :data:`AF_INET6` |
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 think AF_INET and AF_INET6 are mutually exclusive for a given socket. Perhaps it is more accurate to say the socket can handle both IP v4 and v6.
Lib/idlelib/rpc.py
Outdated
self.listening_sock.bind(address) | ||
self.listening_sock.listen(1) | ||
self.listening_sock = socket.create_server( | ||
address, family=family, type=type, backlog=1) |
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.
Is type a valid keyword? If not, maybe this needs a test 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.
Ouch! I missed that, thanks. I just removed this part and left idlelib alone in f786884. I will probably get back at this in a separate PR because it's more controversial.
Lib/socket.py
Outdated
raise error(err.errno, msg) from None | ||
sock.listen(backlog) | ||
return sock | ||
except 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.
Use plain except to catch all exceptions (e.g. KeyboardInterrupt could be raised during a slow DNS lookup)
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.
Good point. I think it's saner to just catch socket.error
, the same way it's done in create_connection()
. Changed it in f786884.
with sock: | ||
conn, _ = sock.accept() | ||
with conn: | ||
event.wait(self.timeout) |
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.
Is this event necessary? It is set just after the thread is started.
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.
Yes it is because you want to wait for accept()
to succeed before doing connect()
. Without this sync primitive in place the test will fail.
@giampaolo: Sorry, I don't have the bandwidth right now to review this PR. |
@vstinner it's ok, we still depend on https://bugs.python.org/issue29515 which should be fixed first. |
OK, I just committed a fix for https://bugs.python.org/issue29515 which adds IPPROTO_IPV6 constant on Windows. Since dual-stack is supported on Windows I removed the reference to the external recipe from the doc (at this point I am not aware of any platform NOT supporting dual-stack). I think this is good to go but I will wait one more week before merging just in case somebody else wants to comment. Thanks everybody for the great review and suggestions without which this couldn't have happened. |
|
|
|
It turns out doing socket.listen(0) does not equal to "choose a reasonable default". It actually means "set backlog to 0". As such set backlog=None as the default for socket.create_server. Fixes the following BB failures: #11784 (comment) Ref. BPO-1756, GH-11784.
https://bugs.python.org/issue35934