I'm in the process of writing an bidirectional, asynchronous socket server and server handler. The base handler class I'm working off of is as follows:

class BaseAsyncSocketHandler:
    async def send(self, data: bytes) -> int

However, I want to write a subclass that sends two arguments, an event and arbitrary corresponding data, which suggests the signature:

   async def send(self, event: str, data: object) -> int:
       return await super().send(event_data_magic_to_bytes(event, data))

Unfortunately, this violates the Liskov substitution principle, and I don't think writing it as a mixin will makes the situation any better, so I'm hoping somebody has either seen this before or can think of a better design pattern (or tell me this is an unnecessary abstraction in the first place).

  • Does your subclass allow its users to send arbitrary bytes in addition to sending event/data combinations? Apr 13, 2017 at 6:11
  • No, it wouldn't. I intended for the data bytes to consist of the packaged event and serialized object. I definitely was considering optional/keyword arguments, if that's what you were suggesting though.
    – noahbkim
    Apr 13, 2017 at 13:55
  • Why not change the name of the method? Liskov substitution is about behavior specifications as well as signatures, but in this case, I think you are only talking about the signature. Apr 13, 2017 at 22:44
  • Ultimately, this is sort of what I did. I'll add my solution below.
    – noahbkim
    Apr 13, 2017 at 23:13
  • 2
    Why are you even using inheritance? That's the real issue here!
    – gardenhead
    May 14, 2017 at 3:51

1 Answer 1


In the end, I settled on providing the following:

class BaseAsyncSocketHandler:

    async def _send(self, data: bytes) -> int:

    async def send(self, *args, **kwargs) -> int:

This way the user can implement subsets of the send method while using the base send method provided by the socket wrapper. As to why I wanted to use send instead of just creating another class method like send_event, I think I mostly just wanted the interface to the class to remain compact and usable while allowing for different socket methodologies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.