summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/rpc.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/idlelib/rpc.py')
-rw-r--r--Lib/idlelib/rpc.py180
1 files changed, 71 insertions, 109 deletions
diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py
index aa8cbd3..43328e7 100644
--- a/Lib/idlelib/rpc.py
+++ b/Lib/idlelib/rpc.py
@@ -5,7 +5,7 @@ connect to the Idle process, which listens for the connection. Since Idle has
only one client per server, this was not a limitation.
+---------------------------------+ +-------------+
- | socketserver.BaseRequestHandler | | SocketIO |
+ | SocketServer.BaseRequestHandler | | SocketIO |
+---------------------------------+ +-------------+
^ | register() |
| | unregister()|
@@ -26,56 +26,52 @@ See the Idle run.main() docstring for further information on how this was
accomplished in Idle.
"""
-import builtins
-import copyreg
-import io
-import marshal
+
+import sys
import os
-import pickle
-import queue
-import select
import socket
-import socketserver
+import select
+import SocketServer
import struct
-import sys
+import cPickle as pickle
import threading
+import Queue
import traceback
+import copy_reg
import types
+import marshal
+
def unpickle_code(ms):
- "Return code object from marshal string ms."
co = marshal.loads(ms)
assert isinstance(co, types.CodeType)
return co
def pickle_code(co):
- "Return unpickle function and tuple with marshalled co code object."
assert isinstance(co, types.CodeType)
ms = marshal.dumps(co)
return unpickle_code, (ms,)
-def dumps(obj, protocol=None):
- "Return pickled (or marshalled) string for obj."
- # IDLE passes 'None' to select pickle.DEFAULT_PROTOCOL.
- f = io.BytesIO()
- p = CodePickler(f, protocol)
- p.dump(obj)
- return f.getvalue()
-
+# XXX KBK 24Aug02 function pickling capability not used in Idle
+# def unpickle_function(ms):
+# return ms
-class CodePickler(pickle.Pickler):
- dispatch_table = {types.CodeType: pickle_code, **copyreg.dispatch_table}
+# def pickle_function(fn):
+# assert isinstance(fn, type.FunctionType)
+# return repr(fn)
+copy_reg.pickle(types.CodeType, pickle_code, unpickle_code)
+# copy_reg.pickle(types.FunctionType, pickle_function, unpickle_function)
BUFSIZE = 8*1024
LOCALHOST = '127.0.0.1'
-class RPCServer(socketserver.TCPServer):
+class RPCServer(SocketServer.TCPServer):
def __init__(self, addr, handlerclass=None):
if handlerclass is None:
handlerclass = RPCHandler
- socketserver.TCPServer.__init__(self, addr, handlerclass)
+ SocketServer.TCPServer.__init__(self, addr, handlerclass)
def server_bind(self):
"Override TCPServer method, no bind() phase for connecting entity"
@@ -108,21 +104,21 @@ class RPCServer(socketserver.TCPServer):
raise
except:
erf = sys.__stderr__
- print('\n' + '-'*40, file=erf)
- print('Unhandled server exception!', file=erf)
- print('Thread: %s' % threading.current_thread().name, file=erf)
- print('Client Address: ', client_address, file=erf)
- print('Request: ', repr(request), file=erf)
+ print>>erf, '\n' + '-'*40
+ print>>erf, 'Unhandled server exception!'
+ print>>erf, 'Thread: %s' % threading.currentThread().getName()
+ print>>erf, 'Client Address: ', client_address
+ print>>erf, 'Request: ', repr(request)
traceback.print_exc(file=erf)
- print('\n*** Unrecoverable, server exiting!', file=erf)
- print('-'*40, file=erf)
+ print>>erf, '\n*** Unrecoverable, server exiting!'
+ print>>erf, '-'*40
os._exit(0)
#----------------- end class RPCServer --------------------
objecttable = {}
-request_queue = queue.Queue(0)
-response_queue = queue.Queue(0)
+request_queue = Queue.Queue(0)
+response_queue = Queue.Queue(0)
class SocketIO(object):
@@ -130,7 +126,7 @@ class SocketIO(object):
nextseq = 0
def __init__(self, sock, objtable=None, debugging=None):
- self.sockthread = threading.current_thread()
+ self.sockthread = threading.currentThread()
if debugging is not None:
self.debugging = debugging
self.sock = sock
@@ -153,10 +149,10 @@ class SocketIO(object):
def debug(self, *args):
if not self.debugging:
return
- s = self.location + " " + str(threading.current_thread().name)
+ s = self.location + " " + str(threading.currentThread().getName())
for a in args:
s = s + " " + str(a)
- print(s, file=sys.__stderr__)
+ print>>sys.__stderr__, s
def register(self, oid, object):
self.objtable[oid] = object
@@ -200,16 +196,12 @@ class SocketIO(object):
return ("ERROR", "Unsupported message type: %s" % how)
except SystemExit:
raise
- except KeyboardInterrupt:
+ except socket.error:
raise
- except OSError:
- raise
- except Exception as ex:
- return ("CALLEXC", ex)
except:
msg = "*** Internal Error: rpc.py:SocketIO.localcall()\n\n"\
" Object: %s \n Method: %s \n Args: %s\n"
- print(msg % (oid, method, args), file=sys.__stderr__)
+ print>>sys.__stderr__, msg % (oid, method, args)
traceback.print_exc(file=sys.__stderr__)
return ("EXCEPTION", None)
@@ -226,7 +218,7 @@ class SocketIO(object):
def asynccall(self, oid, methodname, args, kwargs):
request = ("CALL", (oid, methodname, args, kwargs))
seq = self.newseq()
- if threading.current_thread() != self.sockthread:
+ if threading.currentThread() != self.sockthread:
cvar = threading.Condition()
self.cvars[seq] = cvar
self.debug(("asynccall:%d:" % seq), oid, methodname, args, kwargs)
@@ -236,7 +228,7 @@ class SocketIO(object):
def asyncqueue(self, oid, methodname, args, kwargs):
request = ("QUEUE", (oid, methodname, args, kwargs))
seq = self.newseq()
- if threading.current_thread() != self.sockthread:
+ if threading.currentThread() != self.sockthread:
cvar = threading.Condition()
self.cvars[seq] = cvar
self.debug(("asyncqueue:%d:" % seq), oid, methodname, args, kwargs)
@@ -264,11 +256,8 @@ class SocketIO(object):
return None
if how == "ERROR":
self.debug("decoderesponse: Internal ERROR:", what)
- raise RuntimeError(what)
- if how == "CALLEXC":
- self.debug("decoderesponse: Call Exception:", what)
- raise what
- raise SystemError(how, what)
+ raise RuntimeError, what
+ raise SystemError, (how, what)
def decode_interrupthook(self):
""
@@ -298,14 +287,14 @@ class SocketIO(object):
def _proxify(self, obj):
if isinstance(obj, RemoteProxy):
return RPCProxy(self, obj.oid)
- if isinstance(obj, list):
- return list(map(self._proxify, obj))
+ if isinstance(obj, types.ListType):
+ return map(self._proxify, obj)
# XXX Check for other types -- not currently needed
return obj
def _getresponse(self, myseq, wait):
self.debug("_getresponse:myseq:", myseq)
- if threading.current_thread() is self.sockthread:
+ if threading.currentThread() is self.sockthread:
# this thread does all reading of requests or responses
while 1:
response = self.pollresponse(myseq, wait)
@@ -332,9 +321,9 @@ class SocketIO(object):
def putmessage(self, message):
self.debug("putmessage:%d:" % message[0])
try:
- s = dumps(message)
+ s = pickle.dumps(message)
except pickle.PicklingError:
- print("Cannot pickle:", repr(message), file=sys.__stderr__)
+ print >>sys.__stderr__, "Cannot pickle:", repr(message)
raise
s = struct.pack("<i", len(s)) + s
while len(s) > 0:
@@ -342,40 +331,40 @@ class SocketIO(object):
r, w, x = select.select([], [self.sock], [])
n = self.sock.send(s[:BUFSIZE])
except (AttributeError, TypeError):
- raise OSError("socket no longer exists")
+ raise IOError, "socket no longer exists"
s = s[n:]
- buff = b''
+ buffer = ""
bufneed = 4
bufstate = 0 # meaning: 0 => reading count; 1 => reading data
def pollpacket(self, wait):
self._stage0()
- if len(self.buff) < self.bufneed:
+ if len(self.buffer) < self.bufneed:
r, w, x = select.select([self.sock.fileno()], [], [], wait)
if len(r) == 0:
return None
try:
s = self.sock.recv(BUFSIZE)
- except OSError:
+ except socket.error:
raise EOFError
if len(s) == 0:
raise EOFError
- self.buff += s
+ self.buffer += s
self._stage0()
return self._stage1()
def _stage0(self):
- if self.bufstate == 0 and len(self.buff) >= 4:
- s = self.buff[:4]
- self.buff = self.buff[4:]
+ if self.bufstate == 0 and len(self.buffer) >= 4:
+ s = self.buffer[:4]
+ self.buffer = self.buffer[4:]
self.bufneed = struct.unpack("<i", s)[0]
self.bufstate = 1
def _stage1(self):
- if self.bufstate == 1 and len(self.buff) >= self.bufneed:
- packet = self.buff[:self.bufneed]
- self.buff = self.buff[self.bufneed:]
+ if self.bufstate == 1 and len(self.buffer) >= self.bufneed:
+ packet = self.buffer[:self.bufneed]
+ self.buffer = self.buffer[self.bufneed:]
self.bufneed = 4
self.bufstate = 0
return packet
@@ -387,10 +376,10 @@ class SocketIO(object):
try:
message = pickle.loads(packet)
except pickle.UnpicklingError:
- print("-----------------------", file=sys.__stderr__)
- print("cannot unpickle packet:", repr(packet), file=sys.__stderr__)
+ print >>sys.__stderr__, "-----------------------"
+ print >>sys.__stderr__, "cannot unpickle packet:", repr(packet)
traceback.print_stack(file=sys.__stderr__)
- print("-----------------------", file=sys.__stderr__)
+ print >>sys.__stderr__, "-----------------------"
raise
return message
@@ -421,7 +410,7 @@ class SocketIO(object):
# send queued response if there is one available
try:
qmsg = response_queue.get(0)
- except queue.Empty:
+ except Queue.Empty:
pass
else:
seq, response = qmsg
@@ -490,20 +479,17 @@ class RemoteObject(object):
# Token mix-in class
pass
-
def remoteref(obj):
oid = id(obj)
objecttable[oid] = obj
return RemoteProxy(oid)
-
class RemoteProxy(object):
def __init__(self, oid):
self.oid = oid
-
-class RPCHandler(socketserver.BaseRequestHandler, SocketIO):
+class RPCHandler(SocketServer.BaseRequestHandler, SocketIO):
debugging = False
location = "#S" # Server
@@ -511,16 +497,15 @@ class RPCHandler(socketserver.BaseRequestHandler, SocketIO):
def __init__(self, sock, addr, svr):
svr.current_handler = self ## cgt xxx
SocketIO.__init__(self, sock)
- socketserver.BaseRequestHandler.__init__(self, sock, addr, svr)
+ SocketServer.BaseRequestHandler.__init__(self, sock, addr, svr)
def handle(self):
- "handle() method required by socketserver"
+ "handle() method required by SocketServer"
self.mainloop()
def get_remote_proxy(self, oid):
return RPCProxy(self, oid)
-
class RPCClient(SocketIO):
debugging = False
@@ -536,17 +521,16 @@ class RPCClient(SocketIO):
def accept(self):
working_sock, address = self.listening_sock.accept()
if self.debugging:
- print("****** Connection request from ", address, file=sys.__stderr__)
+ print>>sys.__stderr__, "****** Connection request from ", address
if address[0] == LOCALHOST:
SocketIO.__init__(self, working_sock)
else:
- print("** Invalid host: ", address, file=sys.__stderr__)
- raise OSError
+ print>>sys.__stderr__, "** Invalid host: ", address
+ raise socket.error
def get_remote_proxy(self, oid):
return RPCProxy(self, oid)
-
class RPCProxy(object):
__methods = None
@@ -568,7 +552,7 @@ class RPCProxy(object):
(name,), {})
return value
else:
- raise AttributeError(name)
+ raise AttributeError, name
def __getattributes(self):
self.__attributes = self.sockio.remotecall(self.oid,
@@ -583,19 +567,20 @@ def _getmethods(obj, methods):
# Adds names to dictionary argument 'methods'
for name in dir(obj):
attr = getattr(obj, name)
- if callable(attr):
+ if hasattr(attr, '__call__'):
methods[name] = 1
- if isinstance(obj, type):
+ if type(obj) == types.InstanceType:
+ _getmethods(obj.__class__, methods)
+ if type(obj) == types.ClassType:
for super in obj.__bases__:
_getmethods(super, methods)
def _getattributes(obj, attributes):
for name in dir(obj):
attr = getattr(obj, name)
- if not callable(attr):
+ if not hasattr(attr, '__call__'):
attributes[name] = 1
-
class MethodProxy(object):
def __init__(self, sockio, oid, name):
@@ -603,33 +588,10 @@ class MethodProxy(object):
self.oid = oid
self.name = name
- def __call__(self, /, *args, **kwargs):
+ def __call__(self, *args, **kwargs):
value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
return value
# XXX KBK 09Sep03 We need a proper unit test for this module. Previously
# existing test code was removed at Rev 1.27 (r34098).
-
-def displayhook(value):
- """Override standard display hook to use non-locale encoding"""
- if value is None:
- return
- # Set '_' to None to avoid recursion
- builtins._ = None
- text = repr(value)
- try:
- sys.stdout.write(text)
- except UnicodeEncodeError:
- # let's use ascii while utf8-bmp codec doesn't present
- encoding = 'ascii'
- bytes = text.encode(encoding, 'backslashreplace')
- text = bytes.decode(encoding, 'strict')
- sys.stdout.write(text)
- sys.stdout.write("\n")
- builtins._ = value
-
-
-if __name__ == '__main__':
- from unittest import main
- main('idlelib.idle_test.test_rpc', verbosity=2,)