classification
Title: socket.type value changes after using settimeout()
Type: behavior Stage: resolved
Components: Versions: Python 3.3, Python 3.4, Python 3.5
process
Status: closed Resolution: out of date
Dependencies: Superseder: Fix socket.type on OSes with SOCK_NONBLOCK
View: 32331
Assigned To: Nosy List: giampaolo.rodola, lekma, neologix, nnja, nvetoshkin, pitrou, r.david.murray, raulcd, vstinner, yselivanov
Priority: normal Keywords: patch

Created on 2014-04-22 11:55 by giampaolo.rodola, last changed 2018-05-29 14:07 by yselivanov. This issue is now closed.

Files
File name Uploaded Description Edit
issue21327.patch raulcd, 2015-04-14 19:35 review
21327.2.patch raulcd, 2015-04-16 15:39 review
Messages (19)
msg216999 - (view) Author: Giampaolo Rodola' (giampaolo.rodola) * (Python committer) Date: 2014-04-22 11:55
>>> 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.
2.7 is not affected.
msg217000 - (view) Author: Giampaolo Rodola' (giampaolo.rodola) * (Python committer) Date: 2014-04-22 12:09
It seems this was introduced in issue 7523 / revision 12442ac3f7dd.
msg217002 - (view) Author: Giampaolo Rodola' (giampaolo.rodola) * (Python committer) Date: 2014-04-22 12:28
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).
Sounds reasonable?
msg217020 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-04-22 20:42
I think distinguishing between the two situations would make the code yet more complicated (and fragile). It's a bit unfortunate that the `type` attribute has become a kitchen sink for disparate pieces of configuration.

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.
msg217032 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-04-22 21:51
I would prefer to add something to get the type without SOCK_NONBLOCK nor
SOCK_CLOEXEC. So new feature can only be added to Python 3.5. For older
Python versions, you can to filter manually, which is difficult because you
have yo check if SOCK_NONBLOCK and/or SOCK_CLOEXEC are available. You have
the same issue in the C language.

Anyway, all sockets are now created with SOCK_CLOEXEC since Python 3.4
because of the PEP 446 (cloexec).

We can add a new .sock_type attribute. Or .type could be an object with
attributes like: type (int/enum), cloexec, nonblock, etc.

Or simply a short helper method can be added. Ex:
socket.get_socket_type(sock) or socket.get_socket_type(sock.type).
msg240910 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-14 15:31
@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,)
msg240914 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-14 15:39
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 ...
msg240933 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-14 16:24
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
msg240939 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-14 16:36
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
msg240996 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-14 19:34
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>
msg240997 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-14 19:35
Added docs and test in the patch.
msg241028 - (view) Author: Nina Zakharenko (nnja) * (Python triager) Date: 2015-04-14 21:08
Maybe it would be better if the type property on socket had this behavior, rather than creating a new method.
msg241031 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-04-14 21:26
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.
msg241225 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-16 15:39
Added new patch as per review comments.
msg241754 - (view) Author: Raúl Cumplido (raulcd) * Date: 2015-04-21 23:25
ping, any comment on the patch that was provided during the PyCon 2015 sprints?
msg242426 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-05-02 19:38
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.
msg242427 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-05-02 19:40
Wait, I take it back.  I must have run the test incorrectly.
msg242429 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-05-02 20:18
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.
msg318030 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2018-05-29 14:07
This issue is resolved in 3.7: https://bugs.python.org/issue32331
History
Date User Action Args
2018-05-29 14:07:06yselivanovsetstatus: open -> closed

superseder: Fix socket.type on OSes with SOCK_NONBLOCK
nosy: + yselivanov

messages: + msg318030
type: behavior
resolution: out of date
stage: resolved
2017-04-29 09:26:53martin.panterlinkissue30204 superseder
2015-07-21 07:17:49ethan.furmansetnosy: - ethan.furman
2015-05-02 20:18:12r.david.murraysetmessages: + msg242429
2015-05-02 19:40:06r.david.murraysetmessages: + msg242427
2015-05-02 19:38:35r.david.murraysetnosy: + ethan.furman
messages: + msg242426
2015-04-21 23:25:52raulcdsetmessages: + msg241754
2015-04-16 15:39:32raulcdsetfiles: + 21327.2.patch

messages: + msg241225
2015-04-15 11:25:48Jean-Paul Calderonesetnosy: - exarkun
2015-04-14 21:26:10r.david.murraysetmessages: + msg241031
2015-04-14 21:08:39nnjasetnosy: + nnja
messages: + msg241028
2015-04-14 19:35:18raulcdsetfiles: + issue21327.patch
keywords: + patch
messages: + msg240997
2015-04-14 19:34:41raulcdsetmessages: + msg240996
2015-04-14 16:36:35raulcdsetmessages: + msg240939
2015-04-14 16:24:01raulcdsetmessages: + msg240933
2015-04-14 15:39:30raulcdsetmessages: + msg240914
2015-04-14 15:31:52raulcdsetnosy: + raulcd
messages: + msg240910
2014-06-26 17:47:21BreamoreBoysetnosy: - BreamoreBoy
2014-04-22 21:51:36vstinnersetmessages: + msg217032
2014-04-22 20:42:22pitrousetnosy: + vstinner, neologix
messages: + msg217020
2014-04-22 12:28:09giampaolo.rodolasetmessages: + msg217002
2014-04-22 12:27:54giampaolo.rodolasetmessages: - msg217001
2014-04-22 12:27:15giampaolo.rodolasetnosy: + exarkun, r.david.murray, lekma, nvetoshkin, BreamoreBoy
messages: + msg217001
2014-04-22 12:09:31giampaolo.rodolasetnosy: + pitrou
messages: + msg217000
2014-04-22 11:55:07giampaolo.rodolacreate