summaryrefslogtreecommitdiff
path: root/jsonrpclib
diff options
context:
space:
mode:
authorefokschaner <efokschaner@riotgames.com>2015-10-08 15:08:04 -0700
committerefokschaner <efokschaner@riotgames.com>2015-10-08 15:08:04 -0700
commitb6b93baaed2cd49eb3e850655e5cc1cf6764cf11 (patch)
treeeea385cc02ea5c9dd739dfc0a59b4d7b211b7e25 /jsonrpclib
parent812a6834eec8b8286f4312b3fb8f748da714329d (diff)
parent3058181be3481ad7b3e4ae9646d357e57420f933 (diff)
downloadjsonrpclib-b6b93baaed2cd49eb3e850655e5cc1cf6764cf11.tar.gz
Merge upstream master into master
Diffstat (limited to 'jsonrpclib')
-rw-r--r--jsonrpclib/SimpleJSONRPCServer.py47
-rw-r--r--jsonrpclib/config.py8
-rw-r--r--jsonrpclib/history.py6
-rw-r--r--jsonrpclib/jsonclass.py31
-rw-r--r--jsonrpclib/jsonrpc.py155
5 files changed, 146 insertions, 101 deletions
diff --git a/jsonrpclib/SimpleJSONRPCServer.py b/jsonrpclib/SimpleJSONRPCServer.py
index d76da73..3a0a3bb 100644
--- a/jsonrpclib/SimpleJSONRPCServer.py
+++ b/jsonrpclib/SimpleJSONRPCServer.py
@@ -15,6 +15,7 @@ except ImportError:
# For Windows
fcntl = None
+
def get_version(request):
# must be a dict
if 'jsonrpc' in request.keys():
@@ -22,9 +23,10 @@ def get_version(request):
if 'id' in request.keys():
return 1.0
return None
-
+
+
def validate_request(request):
- if type(request) is not types.DictType:
+ if not isinstance(request, dict):
fault = Fault(
-32600, 'Request must be {}, not %s.' % type(request)
)
@@ -33,27 +35,27 @@ def validate_request(request):
version = get_version(request)
if not version:
fault = Fault(-32600, 'Request %s invalid.' % request, rpcid=rpcid)
- return fault
+ return fault
request.setdefault('params', [])
method = request.get('method', None)
params = request.get('params')
param_types = (types.ListType, types.DictType, types.TupleType)
if not method or type(method) not in types.StringTypes or \
- type(params) not in param_types:
+ type(params) not in param_types:
fault = Fault(
-32600, 'Invalid request parameters or method.', rpcid=rpcid
)
return fault
return True
+
class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
def __init__(self, encoding=None):
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self,
- allow_none=True,
- encoding=encoding)
+ SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(
+ self, allow_none=True, encoding=encoding)
- def _marshaled_dispatch(self, data, dispatch_method = None):
+ def _marshaled_dispatch(self, data, dispatch_method=None):
response = None
try:
request = jsonrpclib.loads(data)
@@ -64,7 +66,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
if not request:
fault = Fault(-32600, 'Request invalid -- no request data.')
return fault.response()
- if type(request) is types.ListType:
+ if isinstance(request, list):
# This SHOULD be a batch, by spec
responses = []
for req_entry in request:
@@ -79,7 +81,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
response = '[%s]' % ','.join(responses)
else:
response = ''
- else:
+ else:
result = validate_request(request)
if type(result) is Fault:
return result.response()
@@ -99,7 +101,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
exc_type, exc_value, exc_tb = sys.exc_info()
fault = Fault(-32603, '%s:%s' % (exc_type, exc_value))
return fault.response()
- if 'id' not in request.keys() or request['id'] == None:
+ if 'id' not in request.keys() or request['id'] is None:
# It's a notification
return None
try:
@@ -132,25 +134,26 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
pass
if func is not None:
try:
- if type(params) is types.ListType:
+ if isinstance(params, types.ListType):
response = func(*params)
else:
response = func(**params)
return response
- except TypeError:
- return Fault(-32602, 'Invalid parameters.')
+ # except TypeError:
+ # return Fault(-32602, 'Invalid parameters.')
except:
err_lines = traceback.format_exc().splitlines()
trace_string = '%s | %s' % (err_lines[-3], err_lines[-1])
- fault = jsonrpclib.Fault(-32603, 'Server error: %s' %
+ fault = jsonrpclib.Fault(-32603, 'Server error: %s' %
trace_string)
return fault
else:
return Fault(-32601, 'Method %s not supported.' % method)
+
class SimpleJSONRPCRequestHandler(
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
-
+
def do_POST(self):
if not self.is_rpc_path_valid():
self.report_404()
@@ -166,13 +169,13 @@ class SimpleJSONRPCRequestHandler(
data = ''.join(L)
response = self.server._marshaled_dispatch(data)
self.send_response(200)
- except Exception, e:
+ except Exception:
self.send_response(500)
err_lines = traceback.format_exc().splitlines()
trace_string = '%s | %s' % (err_lines[-3], err_lines[-1])
fault = jsonrpclib.Fault(-32603, 'Server error: %s' % trace_string)
response = fault.response()
- if response == None:
+ if response is None:
response = ''
self.send_header("Content-type", "application/json-rpc")
self.send_header("Content-length", str(len(response)))
@@ -181,6 +184,7 @@ class SimpleJSONRPCRequestHandler(
self.wfile.flush()
self.connection.shutdown(1)
+
class SimpleJSONRPCServer(SocketServer.TCPServer, SimpleJSONRPCDispatcher):
allow_reuse_address = True
@@ -198,7 +202,7 @@ class SimpleJSONRPCServer(SocketServer.TCPServer, SimpleJSONRPCDispatcher):
# Unix sockets can't be bound if they already exist in the
# filesystem. The convention of e.g. X11 is to unlink
# before binding again.
- if os.path.exists(addr):
+ if os.path.exists(addr):
try:
os.unlink(addr)
except OSError:
@@ -207,13 +211,14 @@ class SimpleJSONRPCServer(SocketServer.TCPServer, SimpleJSONRPCDispatcher):
if vi[0] < 3 and vi[1] < 6:
SocketServer.TCPServer.__init__(self, addr, requestHandler)
else:
- SocketServer.TCPServer.__init__(self, addr, requestHandler,
- bind_and_activate)
+ SocketServer.TCPServer.__init__(
+ self, addr, requestHandler, bind_and_activate)
if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
+
class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher):
def __init__(self, encoding=None):
diff --git a/jsonrpclib/config.py b/jsonrpclib/config.py
index 4d28f1b..ca926ca 100644
--- a/jsonrpclib/config.py
+++ b/jsonrpclib/config.py
@@ -1,12 +1,14 @@
import sys
+
class LocalClasses(dict):
def add(self, cls):
self[cls.__name__] = cls
+
class Config(object):
"""
- This is pretty much used exclusively for the 'jsonclass'
+ This is pretty much used exclusively for the 'jsonclass'
functionality... set use_jsonclass to False to turn it off.
You can change serialize_method and ignore_attribute, or use
the local_classes.add(class) to include "local" classes.
@@ -15,7 +17,7 @@ class Config(object):
# Change to False to keep __jsonclass__ entries raw.
serialize_method = '_serialize'
# The serialize_method should be a string that references the
- # method on a custom class object which is responsible for
+ # method on a custom class object which is responsible for
# returning a tuple of the constructor arguments and a dict of
# attributes.
ignore_attribute = '_ignore'
@@ -30,7 +32,7 @@ class Config(object):
'.'.join([str(ver) for ver in sys.version_info[0:3]])
# User agent to use for calls.
_instance = None
-
+
@classmethod
def instance(cls):
if not cls._instance:
diff --git a/jsonrpclib/history.py b/jsonrpclib/history.py
index d11863d..f052baa 100644
--- a/jsonrpclib/history.py
+++ b/jsonrpclib/history.py
@@ -2,13 +2,13 @@ class History(object):
"""
This holds all the response and request objects for a
session. A server using this should call "clear" after
- each request cycle in order to keep it from clogging
+ each request cycle in order to keep it from clogging
memory.
"""
requests = []
responses = []
_instance = None
-
+
@classmethod
def instance(cls):
if not cls._instance:
@@ -17,7 +17,7 @@ class History(object):
def add_response(self, response_obj):
self.responses.append(response_obj)
-
+
def add_request(self, request_obj):
self.requests.append(request_obj)
diff --git a/jsonrpclib/jsonclass.py b/jsonrpclib/jsonclass.py
index 1d86d5f..4326f28 100644
--- a/jsonrpclib/jsonclass.py
+++ b/jsonrpclib/jsonclass.py
@@ -1,7 +1,6 @@
import types
import inspect
import re
-import traceback
from jsonrpclib import config
@@ -30,9 +29,11 @@ value_types = [
supported_types = iter_types+string_types+numeric_types+value_types
invalid_module_chars = r'[^a-zA-Z0-9\_\.]'
+
class TranslationError(Exception):
pass
+
def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
if not serialize_method:
serialize_method = config.serialize_method
@@ -46,17 +47,17 @@ def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
if obj_type in (types.ListType, types.TupleType):
new_obj = []
for item in obj:
- new_obj.append(dump(item, serialize_method,
- ignore_attribute, ignore))
- if obj_type is types.TupleType:
+ new_obj.append(
+ dump(item, serialize_method, ignore_attribute, ignore))
+ if isinstance(obj_type, types.TupleType):
new_obj = tuple(new_obj)
return new_obj
# It's a dict...
else:
new_obj = {}
for key, value in obj.iteritems():
- new_obj[key] = dump(value, serialize_method,
- ignore_attribute, ignore)
+ new_obj[key] = dump(
+ value, serialize_method, ignore_attribute, ignore)
return new_obj
# It's not a standard type, so it needs __jsonclass__
module_name = inspect.getmodule(obj).__name__
@@ -64,7 +65,7 @@ def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
json_class = class_name
if module_name not in ['', '__main__']:
json_class = '%s.%s' % (module_name, json_class)
- return_obj = {"__jsonclass__":[json_class,]}
+ return_obj = {"__jsonclass__": [json_class]}
# If a serialization method is defined..
if serialize_method in dir(obj):
# Params can be a dict (keyword) or list (positional)
@@ -84,21 +85,23 @@ def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
if type(attr_value) in supported_types and \
attr_name not in ignore_list and \
attr_value not in ignore_list:
- attrs[attr_name] = dump(attr_value, serialize_method,
- ignore_attribute, ignore)
+ attrs[attr_name] = dump(
+ attr_value, serialize_method, ignore_attribute, ignore)
return_obj.update(attrs)
return return_obj
+
def load(obj):
- if type(obj) in string_types+numeric_types+value_types:
+ if type(obj) in string_types + numeric_types + value_types:
return obj
- if type(obj) is types.ListType:
+
+ if isinstance(obj, list):
return_list = []
for entry in obj:
return_list.append(load(entry))
return return_list
# Othewise, it's a dict type
- if '__jsonclass__' not in obj.keys():
+ if '__jsonclass__' not in obj:
return_dict = {}
for key, value in obj.iteritems():
new_value = load(value)
@@ -139,9 +142,9 @@ def load(obj):
json_class = getattr(temp_module, json_class_name)
# Creating the object...
new_obj = None
- if type(params) is types.ListType:
+ if isinstance(params, list):
new_obj = json_class(*params)
- elif type(params) is types.DictType:
+ elif isinstance(params, dict):
new_obj = json_class(**params)
else:
raise TranslationError('Constructor args must be a dict or list.')
diff --git a/jsonrpclib/jsonrpc.py b/jsonrpclib/jsonrpc.py
index 3812b34..167bcd7 100644
--- a/jsonrpclib/jsonrpc.py
+++ b/jsonrpclib/jsonrpc.py
@@ -1,15 +1,15 @@
"""
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
============================
JSONRPC Library (jsonrpclib)
@@ -29,7 +29,7 @@ Eventually, I'll add a SimpleXMLRPCServer compatible library,
and other things to tie the thing off nicely. :)
For a quick-start, just open a console and type the following,
-replacing the server address, method, and parameters
+replacing the server address, method, and parameters
appropriately.
>>> import jsonrpclib
>>> server = jsonrpclib.Server('http://localhost:8181')
@@ -47,17 +47,14 @@ See http://code.google.com/p/jsonrpclib/ for more info.
"""
import types
-import sys
from xmlrpclib import Transport as XMLTransport
from xmlrpclib import SafeTransport as XMLSafeTransport
from xmlrpclib import ServerProxy as XMLServerProxy
from xmlrpclib import _Method as XML_Method
-import time
import string
import random
# Library includes
-import jsonrpclib
from jsonrpclib import config
from jsonrpclib import history
@@ -80,14 +77,17 @@ except ImportError:
IDCHARS = string.ascii_lowercase+string.digits
+
class UnixSocketMissing(Exception):
- """
- Just a properly named Exception if Unix Sockets usage is
+ """
+ Just a properly named Exception if Unix Sockets usage is
attempted on a platform that doesn't support them (Windows)
"""
pass
-#JSON Abstractions
+
+# JSON Abstractions
+
def jdumps(obj, encoding='utf-8'):
# Do 'serialize' test at some point for other classes
@@ -97,6 +97,7 @@ def jdumps(obj, encoding='utf-8'):
else:
return json.dumps(obj, encoding=encoding)
+
def jloads(json_string):
global cjson
if cjson:
@@ -107,14 +108,17 @@ def jloads(json_string):
# XMLRPClib re-implementations
+
class ProtocolError(Exception):
pass
+
class TransportMixIn(object):
""" Just extends the XMLRPC transport where necessary. """
user_agent = config.user_agent
# for Python 2.7 support
- _connection = None
+ _connection = (None, None)
+ _extra_headers = []
def send_content(self, connection, request_body):
connection.putheader("Content-Type", "application/json-rpc")
@@ -127,6 +131,7 @@ class TransportMixIn(object):
target = JSONTarget()
return JSONParser(target), target
+
class JSONParser(object):
def __init__(self, target):
self.target = target
@@ -137,6 +142,7 @@ class JSONParser(object):
def close(self):
pass
+
class JSONTarget(object):
def __init__(self):
self.data = []
@@ -147,24 +153,31 @@ class JSONTarget(object):
def close(self):
return ''.join(self.data)
+
class Transport(TransportMixIn, XMLTransport):
- pass
+ def __init__(self):
+ TransportMixIn.__init__(self)
+ XMLTransport.__init__(self)
+
class SafeTransport(TransportMixIn, XMLSafeTransport):
- pass
+ def __init__(self):
+ TransportMixIn.__init__(self)
+ XMLSafeTransport.__init__(self)
+
from httplib import HTTP, HTTPConnection
from socket import socket
USE_UNIX_SOCKETS = False
-try:
+try:
from socket import AF_UNIX, SOCK_STREAM
USE_UNIX_SOCKETS = True
except ImportError:
pass
-
+
if (USE_UNIX_SOCKETS):
-
+
class UnixHTTPConnection(HTTPConnection):
def connect(self):
self.sock = socket(AF_UNIX, SOCK_STREAM)
@@ -174,19 +187,19 @@ if (USE_UNIX_SOCKETS):
_connection_class = UnixHTTPConnection
class UnixTransport(TransportMixIn, XMLTransport):
+
def make_connection(self, host):
- import httplib
host, extra_headers, x509 = self.get_host_info(host)
return UnixHTTP(host)
-
+
class ServerProxy(XMLServerProxy):
"""
Unfortunately, much more of this class has to be copied since
so much of it does the serialization.
"""
- def __init__(self, uri, transport=None, encoding=None,
+ def __init__(self, uri, transport=None, encoding=None,
verbose=0, version=None):
import urllib
if not version:
@@ -205,7 +218,7 @@ class ServerProxy(XMLServerProxy):
self.__host, self.__handler = urllib.splithost(uri)
if not self.__handler:
# Not sure if this is in the JSON spec?
- #self.__handler = '/'
+ # self.__handler = '/'
self.__handler == '/'
if transport is None:
if schema == 'unix':
@@ -241,13 +254,13 @@ class ServerProxy(XMLServerProxy):
request,
verbose=self.__verbose
)
-
+
# Here, the XMLRPC library translates a single list
# response to the single value -- should we do the
# same, and require a tuple / list to be passed to
- # the response object, or expect the Server to be
+ # the response object, or expect the Server to be
# outputting the response appropriately?
-
+
history.add_response(response)
if not response:
return None
@@ -265,11 +278,12 @@ class ServerProxy(XMLServerProxy):
class _Method(XML_Method):
-
+
def __call__(self, *args, **kwargs):
if len(args) > 0 and len(kwargs) > 0:
- raise ProtocolError('Cannot use both positional ' +
- 'and keyword arguments (according to JSON-RPC spec.)')
+ raise ProtocolError(
+ 'Cannot use both positional and keyword arguments '
+ '(according to JSON-RPC spec.)')
if len(args) > 0:
return self.__send(self.__name, args)
else:
@@ -287,17 +301,20 @@ class _Method(XML_Method):
def __dir__(self):
return self.__dict__.keys()
+
class _Notify(object):
def __init__(self, request):
self._request = request
def __getattr__(self, name):
return _Method(self._request, name)
-
+
+
# Batch implementation
+
class MultiCallMethod(object):
-
+
def __init__(self, method, notify=False):
self.method = method
self.params = []
@@ -318,14 +335,15 @@ class MultiCallMethod(object):
def __repr__(self):
return '%s' % self.request()
-
+
def __getattr__(self, method):
new_method = '%s.%s' % (self.method, method)
self.method = new_method
return self
+
class MultiCallNotify(object):
-
+
def __init__(self, multicall):
self.multicall = multicall
@@ -334,8 +352,9 @@ class MultiCallNotify(object):
self.multicall._job_list.append(new_job)
return new_job
+
class MultiCallIterator(object):
-
+
def __init__(self, results):
self.results = results
@@ -352,8 +371,9 @@ class MultiCallIterator(object):
def __len__(self):
return len(self.results)
+
class MultiCall(object):
-
+
def __init__(self, server):
self._server = server
self._job_list = []
@@ -362,8 +382,8 @@ class MultiCall(object):
if len(self._job_list) < 1:
# Should we alert? This /is/ pretty obvious.
return
- request_body = '[ %s ]' % ','.join([job.request() for
- job in self._job_list])
+ request_body = '[ {0} ]'.format(
+ ','.join([job.request() for job in self._job_list]))
responses = self._server._run_request(request_body)
del self._job_list[:]
if not responses:
@@ -381,19 +401,21 @@ class MultiCall(object):
__call__ = _request
-# These lines conform to xmlrpclib's "compatibility" line.
+# These lines conform to xmlrpclib's "compatibility" line.
# Not really sure if we should include these, but oh well.
Server = ServerProxy
+
class Fault(object):
# JSON-RPC error class
+
def __init__(self, code=-32000, message='Server error', rpcid=None):
self.faultCode = code
self.faultString = message
self.rpcid = rpcid
def error(self):
- return {'code':self.faultCode, 'message':self.faultString}
+ return {'code': self.faultCode, 'message': self.faultString}
def response(self, rpcid=None, version=None):
if not version:
@@ -407,25 +429,27 @@ class Fault(object):
def __repr__(self):
return '<Fault %s: %s>' % (self.faultCode, self.faultString)
+
def random_id(length=8):
return_id = ''
for i in range(length):
return_id += random.choice(IDCHARS)
return return_id
+
class Payload(dict):
def __init__(self, rpcid=None, version=None):
if not version:
version = config.version
self.id = rpcid
self.version = float(version)
-
+
def request(self, method, params=[]):
if type(method) not in types.StringTypes:
raise ValueError('Method name must be a string.')
if not self.id:
self.id = random_id()
- request = { 'id':self.id, 'method':method }
+ request = {'id': self.id, 'method': method}
if params:
request['params'] = params
if self.version >= 2:
@@ -441,7 +465,7 @@ class Payload(dict):
return request
def response(self, result=None):
- response = {'result':result, 'id':self.id}
+ response = {'result': result, 'id': self.id}
if self.version >= 2:
response['jsonrpc'] = str(self.version)
else:
@@ -454,13 +478,15 @@ class Payload(dict):
del error['result']
else:
error['result'] = None
- error['error'] = {'code':code, 'message':message}
+ error['error'] = {'code': code, 'message': message}
return error
-def dumps(params=[], methodname=None, methodresponse=None,
+
+def dumps(
+ params=[], methodname=None, methodresponse=None,
encoding=None, rpcid=None, version=None, notify=None):
"""
- This differs from the Python implementation in that it implements
+ This differs from the Python implementation in that it implements
the rpcid argument since the 2.0 spec requires it for responses.
"""
if not version:
@@ -469,7 +495,7 @@ def dumps(params=[], methodname=None, methodresponse=None,
if methodname in types.StringTypes and \
type(params) not in valid_params and \
not isinstance(params, Fault):
- """
+ """
If a method, and params are not in a listish or a Fault,
error out.
"""
@@ -482,10 +508,14 @@ def dumps(params=[], methodname=None, methodresponse=None,
if type(params) is Fault:
response = payload.error(params.faultCode, params.faultString)
return jdumps(response, encoding=encoding)
- if type(methodname) not in types.StringTypes and methodresponse != True:
- raise ValueError('Method name must be a string, or methodresponse '+
- 'must be set to True.')
- if config.use_jsonclass == True:
+
+ if type(methodname) not in types.StringTypes and \
+ methodresponse is not True:
+ raise ValueError(
+ 'Method name must be a string, or methodresponse must '
+ 'be set to True.')
+
+ if config.use_jsonclass is True:
from jsonrpclib import jsonclass
params = jsonclass.dump(params)
if methodresponse is True:
@@ -494,12 +524,13 @@ def dumps(params=[], methodname=None, methodresponse=None,
response = payload.response(params)
return jdumps(response, encoding=encoding)
request = None
- if notify == True:
+ if notify is True:
request = payload.notify(methodname, params)
else:
request = payload.request(methodname, params)
return jdumps(request, encoding=encoding)
+
def loads(data):
"""
This differs from the Python implementation, in that it returns
@@ -510,36 +541,39 @@ def loads(data):
# notification
return None
result = jloads(data)
- # if the above raises an error, the implementing server code
+ # if the above raises an error, the implementing server code
# should return something like the following:
# { 'jsonrpc':'2.0', 'error': fault.error(), id: None }
- if config.use_jsonclass == True:
+ if config.use_jsonclass is True:
from jsonrpclib import jsonclass
result = jsonclass.load(result)
return result
+
def check_for_errors(result):
if not result:
# Notification
return result
- if type(result) is not types.DictType:
+
+ if not isinstance(result, dict):
raise TypeError('Response is not a dict.')
if 'jsonrpc' in result.keys() and float(result['jsonrpc']) > 2.0:
raise NotImplementedError('JSON-RPC version not yet supported.')
if 'result' not in result.keys() and 'error' not in result.keys():
raise ValueError('Response does not have a result or error key.')
- if 'error' in result.keys() and result['error'] != None:
+ if 'error' in result.keys() and result['error'] is not None:
code = result['error']['code']
message = result['error']['message']
raise ProtocolError((code, message))
return result
+
def isbatch(result):
if type(result) not in (types.ListType, types.TupleType):
return False
if len(result) < 1:
return False
- if type(result[0]) is not types.DictType:
+ if not isinstance(result[0], dict):
return False
if 'jsonrpc' not in result[0].keys():
return False
@@ -551,11 +585,12 @@ def isbatch(result):
return False
return True
+
def isnotification(request):
if 'id' not in request.keys():
# 2.0 notification
return True
- if request['id'] == None:
+ if request['id'] is None:
# 1.0 notification
return True
return False