Current behavior:
The msb client crashes at getSelfDescription() when a function callback is bound to a object instance instead of a global method. Hence no registration to the MSB is possible.
Expected behavior:
There should be no difference using static methods as callbacks or methods bound to an object (non-static).
Steps to reproduce:
Create a MsbClient with a function handler using a callback of a bound method
Or call myMsbClient.register() to call getSelfDescription indirectly
2. Observe the crash at: (Line number might be slightly off since i added debug output)
File "c:\Users\xx\Downloads\msb-client-websocket-python\test.py", line 56, in
print(myMsbClient.objectToJson(myMsbClient.getSelfDescription()))
File "c:\Users\xx\Downloads\msb-client-websocket-python\msb_client\MsbClient.py", line 819, in getSelfDescription
del f["implementation"]
KeyError: 'implementation'
**MSB client version:** 1.0.2
**Anything else:**
The issue is related to the jsonpickle library, especially jsonpickle.encode(). Static method delegates get added to the json-tree with the value "None" whilst object bound methods don't get added to the json tree at all. The key error occurs since the "implementation" (= method delegate) is not found in the json tree when using object bound methods. The following example illustrates the behaviour that only the static method delegate gets pickled:
```python
class myClass():
def myMethod(self,msg):
print(str(msg))
@staticmethod
def myStaticMethod(parameter_list):
pass
def __init__(self):
self.myMethodDelegate = self.myMethod
self.myMethodStaticDelegate = myClass.myStaticMethod
myInstance = myClass()
print(jsonpickle.encode(myInstance, unpicklable=False))
# prints { "myMethodStaticDelegate": null }
Possible fix: Check for the existence of the "implementation" key in the cloned object and remove the key only when its present.
Additional remark: Bound methods work out of the box in python with the msb client. This can be seen when calling the implementation directly (usually gets called from the websocket callback):
I'm submitting a ...
Current behavior: The msb client crashes at getSelfDescription() when a function callback is bound to a object instance instead of a global method. Hence no registration to the MSB is possible.
Expected behavior: There should be no difference using static methods as callbacks or methods bound to an object (non-static).
Steps to reproduce:
class myClass(): def myMethod(self,msg): print(str(msg))
myMsbClient = MsbClient(SERVICE_TYPE, SO_UUID,SO_NAME,SO_DESCRIPTION,SO_TOKEN,)
myInstance = myClass()
myFunction = Function("FUNCTION2", "Function2", "Function2_description", DataType.STRING, myInstance.myMethod,)
myMsbClient.addFunction(myFunction)
print(myMsbClient.objectToJson(myMsbClient.getSelfDescription()))
Or call myMsbClient.register() to call getSelfDescription indirectly
File "c:\Users\xx\Downloads\msb-client-websocket-python\test.py", line 56, in
print(myMsbClient.objectToJson(myMsbClient.getSelfDescription()))
File "c:\Users\xx\Downloads\msb-client-websocket-python\msb_client\MsbClient.py", line 819, in getSelfDescription
del f["implementation"]
KeyError: 'implementation'
Possible fix: Check for the existence of the "implementation" key in the cloned object and remove the key only when its present.
Additional remark: Bound methods work out of the box in python with the msb client. This can be seen when calling the implementation directly (usually gets called from the websocket callback):