Socket.socket extension with new attribute

I want to extend Python socket.socket with a new attribute (specifically queue.Queue , but there could be anything). I am trying to decide whether I should use inheritance or composition, but at some point both problems I don’t know how to solve:

A) If I use inheritance, with something like:

 class MySocket(socket.socket): def __init__(self, *args, **kwargs): socket.socket.__init__(self, *args, **kwargs) self.queue = queue.Queue() 

then I have problems when I use operations such as

 connection, client_address = s.accept() 

since the accept socket method returns objects of type socket.socket , not of type MySocket , and I'm not sure how to convert one to the other. If there is a trivial way to OOP for this, I don't know that.

B) The problem was trivially solved before, if instead I used the composition:

 class MySocket(socket.socket): def __init__(self, true_socket): self.true_socket = true_socket self.queue = queue.Queue() 

I would just implement something like

 def accept(self, *args, **kwargs): con, cli = socket.socket.accept(self, *args, **kwargs) return self.__class__(con), cli 

But then I have another problem. When i need to do

 readable, writable, exceptional = select.select(inputs, outputs, inputs) 

select works for socket.socket . With version A), I expect this to work just as it is, but with the composition, now that MySockets are not socket.socket instances, select violated.

So what is the best, pythonic approach for this?

EDIT . I forgot to say that the first thing I tried was to add the attribute directly to the `socket.socket 'instances:

 s = socket.socket(...) s.queue = queue.Queue() 

but I got an exception saying the attribute is unknown for "socket.socket".

+5
source share
2 answers

You can use the following based on socket.socket.dup() in Lib/socket.py :

  import _socket class MySocket(socket.socket): def __init__(self, *args, **kwargs): super(MySocket, self).__init__(*args, **kwargs) self.queue = queue.Queue @classmethod def copy(cls, sock): fd = _socket.dup(sock.fileno()) copy = cls(sock.family, sock.type, sock.proto, fileno=fd) copy.settimeout(sock.gettimeout()) return copy 

Now you can use the constructor to create new MySocket s or use MySocket.copy() to create MySocket from an existing socket.socket . Note that in most cases you should close the source socket after creating the copy.

+3
source

Maybe you should try inheritance with super

 class NewSocket(socket.socket): def __init__(self): super(NewSocket, self).__init__() 
-1
source

Source: https://habr.com/ru/post/1270003/


All Articles