Search code examples
pythonautobahn

python classmethod complains when called


I have a classmethod:

class MyServerProtocol(WebSocketServerProtocol):

    @classmethod
    def send(cls, text):
        cls.sendMessage(cls, text)

    def onMessage(self, payload, isBinary):
        msp=MyServerProtocol
        msp.send('test')

I am trying to call this classmethod (as a test for now, from within the class) and I am getting:

exceptions.TypeError: unbound method sendMessage() must be called with MyServerProtocol instance as first argument (got type instance instead)

It is expecting an instance and complaining that it got an instance... Anyone know how to correctly call this. Once I get it working I can test from within another class, just want to get it working first before I migrate.

EDIT:

I have modified my code to call the method as follows but it is still now working.

class MyServerProtocol(WebSocketServerProtocol):

    def onMessage(self, payload, isBinary):

        myInput = literal_eval(payload)
        cg = coreg.DataGatherCg()
        cg.test(myInput, self)


    def send(self, text):
        self.sendMessage(text)

class DataGatherCg():

    def test(self, myInput, obj):
        obj.send(myInput)

SendMessage from AutoBahn is as follows, after passing self I am getting an assertionError:

def sendMessage(self,
                payload,
                isBinary=False,
                fragmentSize=None,
                sync=False,
                doNotCompress=False):
    """
    Implements :func:`autobahn.websocket.interfaces.IWebSocketChannel.sendMessage`
    """
    assert(type(payload) == bytes)

    if self.state != WebSocketProtocol.STATE_OPEN:
        return

    if self.trackedTimings:
        self.trackedTimings.track("sendMessage")

    # (initial) frame opcode
    #
    if isBinary:
        opcode = 2
    else:
        opcode = 1

    self.trafficStats.outgoingWebSocketMessages += 1

    # setup compressor
    #
    if self._perMessageCompress is not None and not doNotCompress:
        sendCompressed = True

        self._perMessageCompress.startCompressMessage()

        self.trafficStats.outgoingOctetsAppLevel += len(payload)

        payload1 = self._perMessageCompress.compressMessageData(payload)
        payload2 = self._perMessageCompress.endCompressMessage()
        payload = b''.join([payload1, payload2])

        self.trafficStats.outgoingOctetsWebSocketLevel += len(payload)

    else:
        sendCompressed = False
        l = len(payload)
        self.trafficStats.outgoingOctetsAppLevel += l
        self.trafficStats.outgoingOctetsWebSocketLevel += l

    # explicit fragmentSize arguments overrides autoFragmentSize setting
    #
    if fragmentSize is not None:
        pfs = fragmentSize
    else:
        if self.autoFragmentSize > 0:
            pfs = self.autoFragmentSize
        else:
            pfs = None

    # send unfragmented
    #
    if pfs is None or len(payload) <= pfs:
        self.sendFrame(opcode=opcode, payload=payload, sync=sync, rsv=4 if sendCompressed else 0)

    # send data message in fragments
    #
    else:
        if pfs < 1:
            raise Exception("payload fragment size must be at least 1 (was %d)" % pfs)
        n = len(payload)
        i = 0
        done = False
        first = True
        while not done:
            j = i + pfs
            if j > n:
                done = True
                j = n
            if first:
                self.sendFrame(opcode=opcode, payload=payload[i:j], fin=done, sync=sync, rsv=4 if sendCompressed else 0)
                first = False
            else:
                self.sendFrame(opcode=0, payload=payload[i:j], fin=done, sync=sync)
            i += pfs

    # if self.debug:
    #   self.log.debug("Traffic statistics:\n" + str(self.trafficStats))

Solution

  • sendMessage looks like it is an instance method, requiring that it be bound to an instance, to illustrate, the following should work:

    class MyServerProtocol(WebSocketServerProtocol):
    
        def onMessage(self, payload, isBinary):
            msp=MyServerProtocol
            self.sendMessage('test')