I think your code example is not very robust, because the “sock” object refers to a freed file descriptor, and could easily close an unrelated file:
$ python3.5 -q
>>> import socket
>>> sock0 = socket.socket()
>>> sock = socket.socket(fileno=sock0.fileno())
>>> sock0.close()
>>> f = open("/dev/null") # Unrelated code/thread opens a file
>>> sock.close() # Closes unrelated file descriptor!
>>> f.close() # Error even in 3.5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 9] Bad file descriptor
I am not familiar with your use case or library, but I would suggest that either:
1. Your code should call sock0.detach() rather than fileno(), so that sock0 no longer “owns” the file descriptor, or
2. libuv should not close file descriptors that it doesn’t own.
Calling socket.close() should be safe if the Python socket object is registered as closed, but IMO calling close(), or any other method, when the OS socket (file descriptor) has been released behind Python’s back is a programming error.