summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Marshall <catchjosh@gmail.com>2021-03-30 11:01:58 +0900
committerGitHub <noreply@github.com>2021-03-30 11:01:58 +0900
commit9f1cb474c7e0f7e5ff87d5fa3acd5cb6adab2ae1 (patch)
treec5b8205303f473bf5178ec511f32375bdae77087
parente7cb8ba791bd89109022ff7b516787f16922a39b (diff)
parentee90663dde0e46927d11d049f9a516e5381b0d0f (diff)
downloadjsonrpclib-9f1cb474c7e0f7e5ff87d5fa3acd5cb6adab2ae1.tar.gz
Merge pull request #59 from prs247au/master
Updates for Python 3.x compatibility
-rw-r--r--.travis.yml5
-rw-r--r--dev-requirements.txt14
-rw-r--r--jsonrpclib/SimpleJSONRPCServer.py39
-rw-r--r--jsonrpclib/jsonclass.py49
-rw-r--r--jsonrpclib/jsonrpc.py61
5 files changed, 91 insertions, 77 deletions
diff --git a/.travis.yml b/.travis.yml
index fe1cd05..b855e1b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,10 @@
language: python
sudo: false
python:
-- '2.7'
+- "2.7"
+- "3.3"
+- "3.4"
+- "3.5"
install:
- pip install -r dev-requirements.txt
- pip install twine
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 95cb849..c1c28fa 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,11 +1,11 @@
-coverage==4.0
+coverage==4.4
linecache2==1.0.0
nose==1.3.7
-pluggy==0.3.1
-py==1.4.30
-six==1.9.0
-tox==2.1.1
+pluggy==0.4.0
+py==1.4.33
+six==1.10.0
+tox==2.7.0
traceback2==1.4.0
unittest2==1.1.0
-virtualenv==13.1.2
-wheel==0.24.0
+virtualenv==15.1.0
+wheel==0.29.0
diff --git a/jsonrpclib/SimpleJSONRPCServer.py b/jsonrpclib/SimpleJSONRPCServer.py
index 3a0a3bb..708c5d2 100644
--- a/jsonrpclib/SimpleJSONRPCServer.py
+++ b/jsonrpclib/SimpleJSONRPCServer.py
@@ -1,12 +1,15 @@
import jsonrpclib
from jsonrpclib import Fault
from jsonrpclib.jsonrpc import USE_UNIX_SOCKETS
-import SimpleXMLRPCServer
-import SocketServer
+try:
+ import xmlrpc.server as SimpleXMLRPCServer # Python 3.x
+ import socketserver as SocketServer
+except ImportError:
+ import SimpleXMLRPCServer # Python 2.7
+ import SocketServer
import socket
import logging
import os
-import types
import traceback
import sys
try:
@@ -15,6 +18,10 @@ except ImportError:
# For Windows
fcntl = None
+try:
+ basestring # Python 2.7
+except NameError:
+ basestring = str # Python 3.x
def get_version(request):
# must be a dict
@@ -39,9 +46,8 @@ def validate_request(request):
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:
+ if not method or not isinstance(method, basestring) or \
+ not isinstance(params, (list, dict, tuple)):
fault = Fault(
-32600, 'Invalid request parameters or method.', rpcid=rpcid
)
@@ -59,7 +65,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
response = None
try:
request = jsonrpclib.loads(data)
- except Exception, e:
+ except Exception as e:
fault = Fault(-32700, 'Request %s invalid. (%s)' % (data, e))
response = fault.response()
return response
@@ -134,7 +140,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
pass
if func is not None:
try:
- if isinstance(params, types.ListType):
+ if isinstance(params, list):
response = func(*params)
else:
response = func(**params)
@@ -164,12 +170,13 @@ class SimpleJSONRPCRequestHandler(
L = []
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
- L.append(self.rfile.read(chunk_size))
+ chunk = self.rfile.read(chunk_size).decode()
+ L.append(chunk)
size_remaining -= len(L[-1])
data = ''.join(L)
response = self.server._marshaled_dispatch(data)
self.send_response(200)
- except Exception:
+ except Exception as ex:
self.send_response(500)
err_lines = traceback.format_exc().splitlines()
trace_string = '%s | %s' % (err_lines[-3], err_lines[-1])
@@ -180,7 +187,10 @@ class SimpleJSONRPCRequestHandler(
self.send_header("Content-type", "application/json-rpc")
self.send_header("Content-length", str(len(response)))
self.end_headers()
- self.wfile.write(response)
+ if isinstance(response, bytes):
+ self.wfile.write(response)
+ else:
+ self.wfile.write(response.encode())
self.wfile.flush()
self.connection.shutdown(1)
@@ -218,7 +228,6 @@ class SimpleJSONRPCServer(SocketServer.TCPServer, SimpleJSONRPCDispatcher):
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
-
class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher):
def __init__(self, encoding=None):
@@ -226,9 +235,9 @@ class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher):
def handle_jsonrpc(self, request_text):
response = self._marshaled_dispatch(request_text)
- print 'Content-Type: application/json-rpc'
- print 'Content-Length: %d' % len(response)
- print
+ print( 'Content-Type: application/json-rpc' )
+ print( 'Content-Length: %d' % len(response) )
+ print()
sys.stdout.write(response)
handle_xmlrpc = handle_jsonrpc
diff --git a/jsonrpclib/jsonclass.py b/jsonrpclib/jsonclass.py
index 4326f28..31f829d 100644
--- a/jsonrpclib/jsonclass.py
+++ b/jsonrpclib/jsonclass.py
@@ -1,30 +1,16 @@
-import types
import inspect
import re
from jsonrpclib import config
-iter_types = [
- types.DictType,
- types.ListType,
- types.TupleType
-]
-
-string_types = [
- types.StringType,
- types.UnicodeType
-]
-
-numeric_types = [
- types.IntType,
- types.LongType,
- types.FloatType
-]
-
-value_types = [
- types.BooleanType,
- types.NoneType
-]
+iter_types = (dict, list, tuple)
+value_types = (bool, )
+try:
+ string_types = (basestring, ) # Python 2.7
+ numeric_types = (int, long, float)
+except NameError:
+ string_types = (str, ) # Python 3.x
+ numeric_types = (int, float)
supported_types = iter_types+string_types+numeric_types+value_types
invalid_module_chars = r'[^a-zA-Z0-9\_\.]'
@@ -39,23 +25,22 @@ def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
serialize_method = config.serialize_method
if not ignore_attribute:
ignore_attribute = config.ignore_attribute
- obj_type = type(obj)
# Parse / return default "types"...
- if obj_type in numeric_types+string_types+value_types:
+ if obj is None or isinstance(obj, numeric_types+string_types+value_types):
return obj
- if obj_type in iter_types:
- if obj_type in (types.ListType, types.TupleType):
+ if isinstance(obj, iter_types):
+ if isinstance(obj, (list, tuple)):
new_obj = []
for item in obj:
new_obj.append(
dump(item, serialize_method, ignore_attribute, ignore))
- if isinstance(obj_type, types.TupleType):
+ if isinstance(obj, tuple):
new_obj = tuple(new_obj)
return new_obj
# It's a dict...
else:
new_obj = {}
- for key, value in obj.iteritems():
+ for key, value in obj.items():
new_obj[key] = dump(
value, serialize_method, ignore_attribute, ignore)
return new_obj
@@ -81,7 +66,7 @@ def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
return_obj['__jsonclass__'].append([])
attrs = {}
ignore_list = getattr(obj, ignore_attribute, [])+ignore
- for attr_name, attr_value in obj.__dict__.iteritems():
+ for attr_name, attr_value in obj.__dict__.items():
if type(attr_value) in supported_types and \
attr_name not in ignore_list and \
attr_value not in ignore_list:
@@ -92,7 +77,7 @@ def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
def load(obj):
- if type(obj) in string_types + numeric_types + value_types:
+ if obj is None or isinstance(obj, string_types + numeric_types + value_types):
return obj
if isinstance(obj, list):
@@ -103,7 +88,7 @@ def load(obj):
# Othewise, it's a dict type
if '__jsonclass__' not in obj:
return_dict = {}
- for key, value in obj.iteritems():
+ for key, value in obj.items():
new_value = load(value)
return_dict[key] = new_value
return return_dict
@@ -148,7 +133,7 @@ def load(obj):
new_obj = json_class(**params)
else:
raise TranslationError('Constructor args must be a dict or list.')
- for key, value in obj.iteritems():
+ for key, value in obj.items():
if key == '__jsonclass__':
continue
setattr(new_obj, key, value)
diff --git a/jsonrpclib/jsonrpc.py b/jsonrpclib/jsonrpc.py
index 167bcd7..4861e4a 100644
--- a/jsonrpclib/jsonrpc.py
+++ b/jsonrpclib/jsonrpc.py
@@ -46,14 +46,28 @@ appropriately.
See http://code.google.com/p/jsonrpclib/ for more info.
"""
-import types
-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
+try:
+ # Python 3.x
+ from xmlrpc.client import Transport as XMLTransport
+ from xmlrpc.client import SafeTransport as XMLSafeTransport
+ from xmlrpc.client import ServerProxy as XMLServerProxy
+ from xmlrpc.client import _Method as XML_Method
+except ImportError:
+ # Python 2.7
+ 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 string
import random
+try:
+ basestring # Python 2.7
+except NameError:
+ basestring = str # Python 3.x
+
+
# Library includes
from jsonrpclib import config
from jsonrpclib import history
@@ -95,7 +109,8 @@ def jdumps(obj, encoding='utf-8'):
if cjson:
return cjson.encode(obj)
else:
- return json.dumps(obj, encoding=encoding)
+# return json.dumps(obj, encoding=encoding)
+ return json.dumps(obj)
def jloads(json_string):
@@ -151,7 +166,7 @@ class JSONTarget(object):
self.data.append(data)
def close(self):
- return ''.join(self.data)
+ return ''.join([d.decode() for d in self.data])
class Transport(TransportMixIn, XMLTransport):
@@ -165,7 +180,10 @@ class SafeTransport(TransportMixIn, XMLSafeTransport):
TransportMixIn.__init__(self)
XMLSafeTransport.__init__(self)
-from httplib import HTTP, HTTPConnection
+try:
+ from httplib import HTTPConnection
+except ImportError:
+ from http.client import HTTPConnection
from socket import socket
USE_UNIX_SOCKETS = False
@@ -183,14 +201,11 @@ if (USE_UNIX_SOCKETS):
self.sock = socket(AF_UNIX, SOCK_STREAM)
self.sock.connect(self.host)
- class UnixHTTP(HTTP):
- _connection_class = UnixHTTPConnection
-
class UnixTransport(TransportMixIn, XMLTransport):
def make_connection(self, host):
host, extra_headers, x509 = self.get_host_info(host)
- return UnixHTTP(host)
+ return UnixHTTPConnection(host)
class ServerProxy(XMLServerProxy):
@@ -201,11 +216,14 @@ class ServerProxy(XMLServerProxy):
def __init__(self, uri, transport=None, encoding=None,
verbose=0, version=None):
- import urllib
+ try:
+ from urllib.parse import splittype, splithost # python 3.x
+ except ImportError:
+ from urllib import splittype, splithost
if not version:
version = config.version
self.__version = version
- schema, uri = urllib.splittype(uri)
+ schema, uri = splittype(uri)
if schema not in ('http', 'https', 'unix'):
raise IOError('Unsupported JSON-RPC protocol.')
if schema == 'unix':
@@ -215,7 +233,7 @@ class ServerProxy(XMLServerProxy):
self.__host = uri
self.__handler = '/'
else:
- self.__host, self.__handler = urllib.splithost(uri)
+ self.__host, self.__handler = splithost(uri)
if not self.__handler:
# Not sure if this is in the JSON spec?
# self.__handler = '/'
@@ -445,7 +463,7 @@ class Payload(dict):
self.version = float(version)
def request(self, method, params=[]):
- if type(method) not in types.StringTypes:
+ if not isinstance(method, basestring):
raise ValueError('Method name must be a string.')
if not self.id:
self.id = random_id()
@@ -491,9 +509,8 @@ def dumps(
"""
if not version:
version = config.version
- valid_params = (types.TupleType, types.ListType, types.DictType)
- if methodname in types.StringTypes and \
- type(params) not in valid_params and \
+ if isinstance(methodname, str) and \
+ not isinstance(params, (tuple, list, dict)) and \
not isinstance(params, Fault):
"""
If a method, and params are not in a listish or a Fault,
@@ -505,11 +522,11 @@ def dumps(
payload = Payload(rpcid=rpcid, version=version)
if not encoding:
encoding = 'utf-8'
- if type(params) is Fault:
+ if isinstance(params, Fault):
response = payload.error(params.faultCode, params.faultString)
return jdumps(response, encoding=encoding)
- if type(methodname) not in types.StringTypes and \
+ if not isinstance(methodname, str) and \
methodresponse is not True:
raise ValueError(
'Method name must be a string, or methodresponse must '
@@ -569,7 +586,7 @@ def check_for_errors(result):
def isbatch(result):
- if type(result) not in (types.ListType, types.TupleType):
+ if not isinstance(result, (list, tuple)):
return False
if len(result) < 1:
return False