Search code examples
pythonpython-3.xxml-rpc

Python XMLRPC: Cannot allow None even after allow_none = True


I'm trying to write a simple application that communicates using RPCs. I'm using python 3.7's xmlrpc.

This is my server code


MY_ADDR = ("localhost", int(sys.argv[1]))
HOST_ADDR = ("localhost", int(sys.argv[2]))

class RpcServer(threading.Thread):

    def __init__(self):

        threading.Thread.__init__(self)
        self.port = MY_ADDR[1]
        self.addr = MY_ADDR[0]

        # serve other hosts using this
        self.server = SimpleXMLRPCServer((self.addr, self.port))
        self.server.register_function(self.recv_ops)

    def run(self):
        self.server.serve_forever()

    def recv_ops(self, sender, op):
        print("Sender ", sender, " sent: ", op)
        pass

And this is what I'm using as my client's code

def send_ops(host_addr, op):
    # contact the other host using this
    proxy_addr = "http://{addr}:{port}/".format(addr=host_addr[0], port=host_addr[1])
    client_proxy = xmlrpc.client.ServerProxy(proxy_addr, allow_none=True)

    resp = client_proxy.recv_ops(MY_ADDR, op)

...

send_ops(HOST_ADDR, ("d", ii, last_line[ii])) # THE RPC CALL I MAKE

Despite setting allow_none=True, I keep getting this:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "nb.py", line 102, in editor
    send_ops(HOST_ADDR, ("d", ii, last_line[ii]))
  File "nb.py", line 63, in send_ops
    resp = client_proxy.recv_ops(MY_ADDR, op)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xmlrpc/client.py", line 1112, in __call__
    return self.__send(self.__name, args)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xmlrpc/client.py", line 1452, in __request
    verbose=self.__verbose
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xmlrpc/client.py", line 1154, in request
    return self.single_request(host, handler, request_body, verbose)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xmlrpc/client.py", line 1170, in single_request
    return self.parse_response(resp)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xmlrpc/client.py", line 1342, in parse_response
    return u.close()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xmlrpc/client.py", line 656, in close
    raise Fault(**self._stack[0])
xmlrpc.client.Fault: <Fault 1: "<class 'TypeError'>:cannot marshal None unless allow_none is enabled">

What's tripping my is that the server on the other side actually receives the message (without any None)

Sender  ['localhost', 8001]  sent:  ['d', 4, 'o']

What am I missing here? Any help would be appreciated.

Thanks!


Solution

  • In your server class, add allow_none=True to your SimpleXMLRPCServer instantiation.

    self.server = SimpleXMLRPCServer((self.addr, self.port), allow_none=True)
    

    The allow_none and encoding parameters are passed on to xmlrpc.client and control the XML-RPC responses that will be returned from the server.