prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Can't initiate simplejsonrpc service object
  When attempting to instatiate a simplejsonrpc service using Python3, the following happens:
  ```
  >>> from gluon.contrib.simplejsonrpc import ServerProxy
  >>> URL = "http://localhost:8000/app/webservice/call/jsonrpc"
  >>> service = ServerProxy(URL, verbose=False)
  Traceback (most recent call last):
    File "<console>", line 1, in <module>
    File "/opt/web2py/gluon/contrib/simplejsonrpc.py", line 92, in __init__
      type, uri = urllib.splittype(uri)
  AttributeError: module 'urllib' has no attribute 'splittype'
  ```
  As far as I could see, the main problem is, among other little issues, that the function splittype has been moved to urllib.request, therefore it is not found.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `gluon/contrib/simplejsonrpc.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 # This program is free software; you can redistribute it and/or modify
  3 # it under the terms of the GNU Lesser General Public License as published by the
  4 # Free Software Foundation; either version 3, or (at your option) any later
  5 # version.
  6 #
  7 # This program is distributed in the hope that it will be useful, but
  8 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
  9 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  10 # for more details.
  11 
  12 "Pythonic simple JSON RPC Client implementation"
  13 from __future__ import print_function
  14 
  15 __author__ = "Mariano Reingart (reingart@gmail.com)"
  16 __copyright__ = "Copyright (C) 2011 Mariano Reingart"
  17 __license__ = "LGPL 3.0"
  18 __version__ = "0.05"
  19 
  20 import sys
  21 PY2 = sys.version_info[0] == 2
  22 
  23 import urllib
  24 if PY2:
  25     from xmlrpclib import Transport, SafeTransport
  26     from cStringIO import StringIO
  27 else:
  28     from xmlrpc.client import Transport, SafeTransport
  29     from io import StringIO
  30 import random
  31 import json
  32 
  33 
  34 class JSONRPCError(RuntimeError):
  35     "Error object for remote procedure call fail"
  36     def __init__(self, code, message, data=''):
  37         value = "%s: %s\n%s" % (code, message, '\n'.join(data))
  38         RuntimeError.__init__(self, value)
  39         self.code = code
  40         self.message = message
  41         self.data = data
  42 
  43 
  44 class JSONDummyParser:
  45     "json wrapper for xmlrpclib parser interfase"
  46     def __init__(self):
  47         self.buf = StringIO()
  48 
  49     def feed(self, data):
  50         self.buf.write(data)
  51 
  52     def close(self):
  53         return self.buf.getvalue()
  54 
  55 
  56 class JSONTransportMixin:
  57     "json wrapper for xmlrpclib transport interfase"
  58 
  59     def send_content(self, connection, request_body):
  60         connection.putheader("Content-Type", "application/json")
  61         connection.putheader("Content-Length", str(len(request_body)))
  62         connection.endheaders()
  63         if request_body:
  64             connection.send(request_body)
  65         # todo: add gzip compression
  66 
  67     def getparser(self):
  68         # get parser and unmarshaller
  69         parser = JSONDummyParser()
  70         return parser, parser
  71 
  72 
  73 class JSONTransport(JSONTransportMixin, Transport):
  74     pass
  75 
  76 
  77 class JSONSafeTransport(JSONTransportMixin, SafeTransport):
  78     pass
  79 
  80 
  81 class ServerProxy(object):
  82     "JSON RPC Simple Client Service Proxy"
  83 
  84     def __init__(self, uri, transport=None, encoding=None, verbose=0,version=None):
  85         self.location = uri             # server location (url)
  86         self.trace = verbose            # show debug messages
  87         self.exceptions = True          # raise errors? (JSONRPCError)
  88         self.timeout = None
  89         self.json_request = self.json_response = ''
  90         self.version = version          # '2.0' for jsonrpc2
  91 
  92         type, uri = urllib.splittype(uri)
  93         if type not in ("http", "https"):
  94             raise IOError("unsupported JSON-RPC protocol")
  95         self.__host, self.__handler = urllib.splithost(uri)
  96 
  97         if transport is None:
  98             if type == "https":
  99                 transport = JSONSafeTransport()
  100             else:
  101                 transport = JSONTransport()
  102         self.__transport = transport
  103         self.__encoding = encoding
  104         self.__verbose = verbose
  105 
  106     def __getattr__(self, attr):
  107         "pseudo method that can be called"
  108         return lambda *args, **vars: self.call(attr, *args, **vars)
  109 
  110     def call(self, method, *args, **vars):
  111         "JSON RPC communication (method invocation)"
  112 
  113         # build data sent to the service
  114         request_id = random.randint(0, sys.maxsize)
  115         data = {'id': request_id, 'method': method, 'params': args or vars, }
  116         if self.version:
  117             data['jsonrpc'] = self.version #mandatory key/value for jsonrpc2 validation else err -32600
  118         request = json.dumps(data)
  119 
  120         # make HTTP request (retry if connection is lost)
  121         response = self.__transport.request(
  122             self.__host,
  123             self.__handler,
  124             request,
  125             verbose=self.__verbose
  126         )
  127 
  128         # store plain request and response for further debugging
  129         self.json_request = request
  130         self.json_response = response
  131 
  132         # parse json data coming from service
  133         # {'version': '1.1', 'id': id, 'result': result, 'error': None}
  134         response = json.loads(response)
  135 
  136         self.error = response.get('error', {})
  137         if self.error and self.exceptions:
  138             raise JSONRPCError(self.error.get('code', 0),
  139                                self.error.get('message', ''),
  140                                self.error.get('data', None))
  141         if response['id'] != request_id:
  142             raise JSONRPCError(0, "JSON Request ID != Response ID")
  143 
  144         return response.get('result')
  145 
  146 
  147 ServiceProxy = ServerProxy
  148 
  149 
  150 if __name__ == "__main__":
  151     # basic tests:
  152     location = "http://www.web2py.com.ar/webservices/sample/call/jsonrpc"
  153     client = ServerProxy(location, verbose='--verbose' in sys.argv,)
  154     print(client.add(1, 2))
  155
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/gluon/contrib/simplejsonrpc.py b/gluon/contrib/simplejsonrpc.py
  --- a/gluon/contrib/simplejsonrpc.py
  +++ b/gluon/contrib/simplejsonrpc.py
  @@ -20,11 +20,12 @@
   import sys
   PY2 = sys.version_info[0] == 2
   
  -import urllib
   if PY2:
  +    import urllib
       from xmlrpclib import Transport, SafeTransport
       from cStringIO import StringIO
   else:
  +    import urllib.request as urllib
       from xmlrpc.client import Transport, SafeTransport
       from io import StringIO
   import random
  @@ -47,7 +48,7 @@
           self.buf = StringIO()
   
       def feed(self, data):
  -        self.buf.write(data)
  +        self.buf.write(data.decode('utf-8'))
   
       def close(self):
           return self.buf.getvalue()
  @@ -61,7 +62,7 @@
           connection.putheader("Content-Length", str(len(request_body)))
           connection.endheaders()
           if request_body:
  -            connection.send(request_body)
  +            connection.send(str.encode(request_body))
           # todo: add gzip compression
   
       def getparser(self):
  
verification_info: {"golden_diff": "diff --git a/gluon/contrib/simplejsonrpc.py b/gluon/contrib/simplejsonrpc.py\n--- a/gluon/contrib/simplejsonrpc.py\n+++ b/gluon/contrib/simplejsonrpc.py\n@@ -20,11 +20,12 @@\n import sys\n PY2 = sys.version_info[0] == 2\n \n-import urllib\n if PY2:\n+    import urllib\n     from xmlrpclib import Transport, SafeTransport\n     from cStringIO import StringIO\n else:\n+    import urllib.request as urllib\n     from xmlrpc.client import Transport, SafeTransport\n     from io import StringIO\n import random\n@@ -47,7 +48,7 @@\n         self.buf = StringIO()\n \n     def feed(self, data):\n-        self.buf.write(data)\n+        self.buf.write(data.decode('utf-8'))\n \n     def close(self):\n         return self.buf.getvalue()\n@@ -61,7 +62,7 @@\n         connection.putheader(\"Content-Length\", str(len(request_body)))\n         connection.endheaders()\n         if request_body:\n-            connection.send(request_body)\n+            connection.send(str.encode(request_body))\n         # todo: add gzip compression\n \n     def getparser(self):\n", "issue": "Can't initiate simplejsonrpc service object\nWhen attempting to instatiate a simplejsonrpc service using Python3, the following happens:\r\n```\r\n>>> from gluon.contrib.simplejsonrpc import ServerProxy\r\n>>> URL = \"http://localhost:8000/app/webservice/call/jsonrpc\"\r\n>>> service = ServerProxy(URL, verbose=False)\r\nTraceback (most recent call last):\r\n  File \"<console>\", line 1, in <module>\r\n  File \"/opt/web2py/gluon/contrib/simplejsonrpc.py\", line 92, in __init__\r\n    type, uri = urllib.splittype(uri)\r\nAttributeError: module 'urllib' has no attribute 'splittype'\r\n```\r\nAs far as I could see, the main problem is, among other little issues, that the function splittype has been moved to urllib.request, therefore it is not found.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License as published by the\n# Free Software Foundation; either version 3, or (at your option) any later\n# version.\n#\n# This program is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY\n# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# for more details.\n\n\"Pythonic simple JSON RPC Client implementation\"\nfrom __future__ import print_function\n\n__author__ = \"Mariano Reingart (reingart@gmail.com)\"\n__copyright__ = \"Copyright (C) 2011 Mariano Reingart\"\n__license__ = \"LGPL 3.0\"\n__version__ = \"0.05\"\n\nimport sys\nPY2 = sys.version_info[0] == 2\n\nimport urllib\nif PY2:\n    from xmlrpclib import Transport, SafeTransport\n    from cStringIO import StringIO\nelse:\n    from xmlrpc.client import Transport, SafeTransport\n    from io import StringIO\nimport random\nimport json\n\n\nclass JSONRPCError(RuntimeError):\n    \"Error object for remote procedure call fail\"\n    def __init__(self, code, message, data=''):\n        value = \"%s: %s\\n%s\" % (code, message, '\\n'.join(data))\n        RuntimeError.__init__(self, value)\n        self.code = code\n        self.message = message\n        self.data = data\n\n\nclass JSONDummyParser:\n    \"json wrapper for xmlrpclib parser interfase\"\n    def __init__(self):\n        self.buf = StringIO()\n\n    def feed(self, data):\n        self.buf.write(data)\n\n    def close(self):\n        return self.buf.getvalue()\n\n\nclass JSONTransportMixin:\n    \"json wrapper for xmlrpclib transport interfase\"\n\n    def send_content(self, connection, request_body):\n        connection.putheader(\"Content-Type\", \"application/json\")\n        connection.putheader(\"Content-Length\", str(len(request_body)))\n        connection.endheaders()\n        if request_body:\n            connection.send(request_body)\n        # todo: add gzip compression\n\n    def getparser(self):\n        # get parser and unmarshaller\n        parser = JSONDummyParser()\n        return parser, parser\n\n\nclass JSONTransport(JSONTransportMixin, Transport):\n    pass\n\n\nclass JSONSafeTransport(JSONTransportMixin, SafeTransport):\n    pass\n\n\nclass ServerProxy(object):\n    \"JSON RPC Simple Client Service Proxy\"\n\n    def __init__(self, uri, transport=None, encoding=None, verbose=0,version=None):\n        self.location = uri             # server location (url)\n        self.trace = verbose            # show debug messages\n        self.exceptions = True          # raise errors? (JSONRPCError)\n        self.timeout = None\n        self.json_request = self.json_response = ''\n        self.version = version          # '2.0' for jsonrpc2\n\n        type, uri = urllib.splittype(uri)\n        if type not in (\"http\", \"https\"):\n            raise IOError(\"unsupported JSON-RPC protocol\")\n        self.__host, self.__handler = urllib.splithost(uri)\n\n        if transport is None:\n            if type == \"https\":\n                transport = JSONSafeTransport()\n            else:\n                transport = JSONTransport()\n        self.__transport = transport\n        self.__encoding = encoding\n        self.__verbose = verbose\n\n    def __getattr__(self, attr):\n        \"pseudo method that can be called\"\n        return lambda *args, **vars: self.call(attr, *args, **vars)\n\n    def call(self, method, *args, **vars):\n        \"JSON RPC communication (method invocation)\"\n\n        # build data sent to the service\n        request_id = random.randint(0, sys.maxsize)\n        data = {'id': request_id, 'method': method, 'params': args or vars, }\n        if self.version:\n            data['jsonrpc'] = self.version #mandatory key/value for jsonrpc2 validation else err -32600\n        request = json.dumps(data)\n\n        # make HTTP request (retry if connection is lost)\n        response = self.__transport.request(\n            self.__host,\n            self.__handler,\n            request,\n            verbose=self.__verbose\n        )\n\n        # store plain request and response for further debugging\n        self.json_request = request\n        self.json_response = response\n\n        # parse json data coming from service\n        # {'version': '1.1', 'id': id, 'result': result, 'error': None}\n        response = json.loads(response)\n\n        self.error = response.get('error', {})\n        if self.error and self.exceptions:\n            raise JSONRPCError(self.error.get('code', 0),\n                               self.error.get('message', ''),\n                               self.error.get('data', None))\n        if response['id'] != request_id:\n            raise JSONRPCError(0, \"JSON Request ID != Response ID\")\n\n        return response.get('result')\n\n\nServiceProxy = ServerProxy\n\n\nif __name__ == \"__main__\":\n    # basic tests:\n    location = \"http://www.web2py.com.ar/webservices/sample/call/jsonrpc\"\n    client = ServerProxy(location, verbose='--verbose' in sys.argv,)\n    print(client.add(1, 2))\n", "path": "gluon/contrib/simplejsonrpc.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License as published by the\n# Free Software Foundation; either version 3, or (at your option) any later\n# version.\n#\n# This program is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY\n# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# for more details.\n\n\"Pythonic simple JSON RPC Client implementation\"\nfrom __future__ import print_function\n\n__author__ = \"Mariano Reingart (reingart@gmail.com)\"\n__copyright__ = \"Copyright (C) 2011 Mariano Reingart\"\n__license__ = \"LGPL 3.0\"\n__version__ = \"0.05\"\n\nimport sys\nPY2 = sys.version_info[0] == 2\n\nif PY2:\n    import urllib\n    from xmlrpclib import Transport, SafeTransport\n    from cStringIO import StringIO\nelse:\n    import urllib.request as urllib\n    from xmlrpc.client import Transport, SafeTransport\n    from io import StringIO\nimport random\nimport json\n\n\nclass JSONRPCError(RuntimeError):\n    \"Error object for remote procedure call fail\"\n    def __init__(self, code, message, data=''):\n        value = \"%s: %s\\n%s\" % (code, message, '\\n'.join(data))\n        RuntimeError.__init__(self, value)\n        self.code = code\n        self.message = message\n        self.data = data\n\n\nclass JSONDummyParser:\n    \"json wrapper for xmlrpclib parser interfase\"\n    def __init__(self):\n        self.buf = StringIO()\n\n    def feed(self, data):\n        self.buf.write(data.decode('utf-8'))\n\n    def close(self):\n        return self.buf.getvalue()\n\n\nclass JSONTransportMixin:\n    \"json wrapper for xmlrpclib transport interfase\"\n\n    def send_content(self, connection, request_body):\n        connection.putheader(\"Content-Type\", \"application/json\")\n        connection.putheader(\"Content-Length\", str(len(request_body)))\n        connection.endheaders()\n        if request_body:\n            connection.send(str.encode(request_body))\n        # todo: add gzip compression\n\n    def getparser(self):\n        # get parser and unmarshaller\n        parser = JSONDummyParser()\n        return parser, parser\n\n\nclass JSONTransport(JSONTransportMixin, Transport):\n    pass\n\n\nclass JSONSafeTransport(JSONTransportMixin, SafeTransport):\n    pass\n\n\nclass ServerProxy(object):\n    \"JSON RPC Simple Client Service Proxy\"\n\n    def __init__(self, uri, transport=None, encoding=None, verbose=0,version=None):\n        self.location = uri             # server location (url)\n        self.trace = verbose            # show debug messages\n        self.exceptions = True          # raise errors? (JSONRPCError)\n        self.timeout = None\n        self.json_request = self.json_response = ''\n        self.version = version          # '2.0' for jsonrpc2\n\n        type, uri = urllib.splittype(uri)\n        if type not in (\"http\", \"https\"):\n            raise IOError(\"unsupported JSON-RPC protocol\")\n        self.__host, self.__handler = urllib.splithost(uri)\n\n        if transport is None:\n            if type == \"https\":\n                transport = JSONSafeTransport()\n            else:\n                transport = JSONTransport()\n        self.__transport = transport\n        self.__encoding = encoding\n        self.__verbose = verbose\n\n    def __getattr__(self, attr):\n        \"pseudo method that can be called\"\n        return lambda *args, **vars: self.call(attr, *args, **vars)\n\n    def call(self, method, *args, **vars):\n        \"JSON RPC communication (method invocation)\"\n\n        # build data sent to the service\n        request_id = random.randint(0, sys.maxsize)\n        data = {'id': request_id, 'method': method, 'params': args or vars, }\n        if self.version:\n            data['jsonrpc'] = self.version #mandatory key/value for jsonrpc2 validation else err -32600\n        request = json.dumps(data)\n\n        # make HTTP request (retry if connection is lost)\n        response = self.__transport.request(\n            self.__host,\n            self.__handler,\n            request,\n            verbose=self.__verbose\n        )\n\n        # store plain request and response for further debugging\n        self.json_request = request\n        self.json_response = response\n\n        # parse json data coming from service\n        # {'version': '1.1', 'id': id, 'result': result, 'error': None}\n        response = json.loads(response)\n\n        self.error = response.get('error', {})\n        if self.error and self.exceptions:\n            raise JSONRPCError(self.error.get('code', 0),\n                               self.error.get('message', ''),\n                               self.error.get('data', None))\n        if response['id'] != request_id:\n            raise JSONRPCError(0, \"JSON Request ID != Response ID\")\n\n        return response.get('result')\n\n\nServiceProxy = ServerProxy\n\n\nif __name__ == \"__main__\":\n    # basic tests:\n    location = \"http://www.web2py.com.ar/webservices/sample/call/jsonrpc\"\n    client = ServerProxy(location, verbose='--verbose' in sys.argv,)\n    print(client.add(1, 2))\n", "path": "gluon/contrib/simplejsonrpc.py"}]}