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
socket.type value changes after using settimeout() #65526
Comments
>>> s = socket.socket()
>>> s.type
<SocketType.SOCK_STREAM: 1>
>>> s.settimeout(2)
>>> s.type
2049
>>> I can reproduce this with Python 3.5, 3.4 and 3.3. |
It seems this was introduced in bpo-7523 / revision 12442ac3f7dd. |
Generally speaking I think it's fine to have this behavior only if the socket object is instantiated like this: >>> s = socket.socket(type=socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
>>> s.type
2049 ...but when it comes to using settimeout() I would not expect that to happen (it's not cross platform). |
I think distinguishing between the two situations would make the code yet more complicated (and fragile). It's a bit unfortunate that the The fact that you are the first to complain though it was introduced in 3.2 does not make it very compelling to change the current behaviour, IMHO. |
I would prefer to add something to get the type without SOCK_NONBLOCK nor Anyway, all sockets are now created with SOCK_CLOEXEC since Python 3.4 We can add a new .sock_type attribute. Or .type could be an object with Or simply a short helper method can be added. Ex: |
@Haypo Would you expect the new function to return a tuple? i.e:
>>> socket.get_socket_type(sock)
(socket.SOCK_STREAM, socket.SOCK_NONBLOCK)
>>> socket.get_socket_type(sock2)
(socket.SOCK_STREAM,) |
after conversation with @r.david.murray I understand that we only want to return the type, not all the flags, so the function will return just the socket.SOCK_STREAM or socket.SOCK_DGRAM ... |
While reproducing it I've seen that this has been already solved:
>>> sock = socket.socket(type=socket.SOCK_STREAM)
>>> sock.type
<SocketKind.SOCK_STREAM: 1>
>>> sock.settimeout(2)
>>> sock.type
<SocketKind.SOCK_STREAM: 1>
But the next is still not correct:
>>> sock = socket.socket(type=socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
>>> sock.type
2049 |
Forget my previous comment. Done with Linux and had the initial behavior again:
>>> s = socket.socket()
>>> s.type
<SocketType.SOCK_STREAM: 1>
>>> s.settimeout(2)
>>> s.type
2049 |
Added patch that solves issue, but I am not sure this is what you expect. If you think this is the expected behavior I will add docs and tests:
>>> sock = socket.socket(type=socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
>>> sock.type
2049
>>> socket.get_socket_type(sock)
<SocketKind.SOCK_STREAM: 1>
>>> sock = socket.socket(type=socket.SOCK_STREAM | socket.SOCK_NONBLOCK |socket.SOCK_CLOEXEC)
>>> sock.type
526337
>>> socket.get_socket_type(sock)
<SocketKind.SOCK_STREAM: 1> |
Added docs and test in the patch. |
Maybe it would be better if the type property on socket had this behavior, rather than creating a new method. |
If we were designing from scratch, that would be true. But we are stuck with the behavior that we have, and cannot change it because we need to preserve backward compatibility. This is why we need to make it a new method. |
Added new patch as per review comments. |
ping, any comment on the patch that was provided during the PyCon 2015 sprints? |
The behavior of s.type has changed in 3.5: it now behaves like the proposed new method behaves. Looking at the source I can't figure out why this is so. It doesn't seem as though it should be, but this needs to be sorted out before we can proceed. |
Wait, I take it back. I must have run the test incorrectly. |
I added some review comments. Something I don't understand: if settimeout sets NONBLOCK, and CLOEXEC is always set now, why does s=socket.socket() yield something whose type is SOCK_STREAM, while settimeout causes type to change? I don't understand the relationship between SOCK_NONBLOCK and O_NONBLOCK, either. Whoever came up with this API in linux was crazy, if you ask me. On the other hand, having type return what it does is clearly correct, given that we are mirroring the C API. Having a new sock_type attribute that provides the value without the extra flags makes sense in that context, IMO. |
This issue is resolved in 3.7: https://bugs.python.org/issue32331 |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: