[Idle-dev] CVS: idle RemoteObjectBrowser.py,NONE,1.1 RemoteDebugger.py,NONE,1.1 rpc.py,NONE,1.1 run.py,NONE,1.1 ScriptBinding.py,1.4,1.5 Debugger.py,1.4,1.5 PyShell.py,1.13,1.14
Chui Tey
teyc@users.sourceforge.net
Sun, 26 May 2002 06:36:44 -0700
Update of /cvsroot/idlefork/idle
In directory usw-pr-cvs1:/tmp/cvs-serv5459
Modified Files:
ScriptBinding.py Debugger.py PyShell.py
Added Files:
RemoteObjectBrowser.py RemoteDebugger.py rpc.py run.py
Log Message:
GvR's rpc patch
--- NEW FILE: RemoteObjectBrowser.py ---
import rpc
def remote_object_tree_item(item):
wrapper = WrappedObjectTreeItem(item)
oid = id(wrapper)
rpc.objecttable[oid] = wrapper
return oid
class WrappedObjectTreeItem:
# Lives in PYTHON subprocess
def __init__(self, item):
self.__item = item
def __getattr__(self, name):
value = getattr(self.__item, name)
return value
def _GetSubList(self):
list = self.__item._GetSubList()
return map(remote_object_tree_item, list)
class StubObjectTreeItem:
# Lives in IDLE process
def __init__(self, sockio, oid):
self.sockio = sockio
self.oid = oid
def __getattr__(self, name):
value = rpc.MethodProxy(self.sockio, self.oid, name)
return value
def _GetSubList(self):
list = self.sockio.remotecall(self.oid, "_GetSubList", (), {})
return [StubObjectTreeItem(self.sockio, oid) for oid in list]
--- NEW FILE: RemoteDebugger.py ---
"""Support for remote Python debugging.
Some ASCII art to describe the structure:
IN PYTHON SUBPROCESS # IN IDLE PROCESS
#
# oid='gui_adapter'
+----------+ # +------------+ +-----+
| GUIProxy |--remote#call-->| GUIAdapter |--calls-->| GUI |
+-----+--calls-->+----------+ # +------------+ +-----+
| Idb | # /
+-----+<-calls--+------------+ # +----------+<--calls-/
| IdbAdapter |<--remote#call--| IdbProxy |
+------------+ # +----------+
oid='idb_adapter' #
The purpose of the Proxy and Adapter classes is to translate certain
arguments and return values that cannot be transported through the RPC
barrier, in particular frame and traceback objects.
"""
import sys
import rpc
import Debugger
# In the PYTHON subprocess
frametable = {}
dicttable = {}
codetable = {}
def wrap_frame(frame):
fid = id(frame)
frametable[fid] = frame
return fid
def wrap_info(info):
if info is None:
return None
else:
return None # XXX for now
class GUIProxy:
def __init__(self, conn, oid):
self.conn = conn
self.oid = oid
def interaction(self, message, frame, info=None):
self.conn.remotecall(self.oid, "interaction",
(message, wrap_frame(frame), wrap_info(info)),
{})
class IdbAdapter:
def __init__(self, idb):
self.idb = idb
def set_step(self):
self.idb.set_step()
def set_quit(self):
self.idb.set_quit()
def set_continue(self):
self.idb.set_continue()
def set_next(self, fid):
frame = frametable[fid]
self.idb.set_next(frame)
def set_return(self, fid):
frame = frametable[fid]
self.idb.set_return(frame)
def get_stack(self, fid, tbid):
##print >>sys.__stderr__, "get_stack(%s, %s)" % (`fid`, `tbid`)
frame = frametable[fid]
tb = None # XXX for now
stack, i = self.idb.get_stack(frame, tb)
##print >>sys.__stderr__, "get_stack() ->", stack
stack = [(wrap_frame(frame), k) for frame, k in stack]
##print >>sys.__stderr__, "get_stack() ->", stack
return stack, i
def run(self, cmd):
import __main__
self.idb.run(cmd, __main__.__dict__)
def frame_attr(self, fid, name):
frame = frametable[fid]
return getattr(frame, name)
def frame_globals(self, fid):
frame = frametable[fid]
dict = frame.f_globals
did = id(dict)
dicttable[did] = dict
return did
def frame_locals(self, fid):
frame = frametable[fid]
dict = frame.f_locals
did = id(dict)
dicttable[did] = dict
return did
def frame_code(self, fid):
frame = frametable[fid]
code = frame.f_code
cid = id(code)
codetable[cid] = code
return cid
def code_name(self, cid):
code = codetable[cid]
return code.co_name
def code_filename(self, cid):
code = codetable[cid]
return code.co_filename
def dict_keys(self, did):
dict = dicttable[did]
return dict.keys()
def dict_item(self, did, key):
dict = dicttable[did]
value = dict[key]
try:
# Test for picklability
import cPickle
cPickle.dumps(value)
except:
value = None
return value
def start_debugger(conn, gui_oid):
#
# launched in the python subprocess
#
gui = GUIProxy(conn, gui_oid)
idb = Debugger.Idb(gui)
ada = IdbAdapter(idb)
ada_oid = "idb_adapter"
conn.register(ada_oid, ada)
return ada_oid
# In the IDLE process
class FrameProxy:
def __init__(self, conn, fid):
self._conn = conn
self._fid = fid
self._oid = "idb_adapter"
self._dictcache = {}
def __getattr__(self, name):
if name[:1] == "_":
raise AttributeError, name
if name == "f_code":
return self._get_f_code()
if name == "f_globals":
return self._get_f_globals()
if name == "f_locals":
return self._get_f_locals()
return self._conn.remotecall(self._oid, "frame_attr",
(self._fid, name), {})
def _get_f_code(self):
cid = self._conn.remotecall(self._oid, "frame_code", (self._fid,), {})
return CodeProxy(self._conn, self._oid, cid)
def _get_f_globals(self):
did = self._conn.remotecall(self._oid, "frame_globals",
(self._fid,), {})
return self._get_dict_proxy(did)
def _get_f_locals(self):
did = self._conn.remotecall(self._oid, "frame_locals",
(self._fid,), {})
return self._get_dict_proxy(did)
def _get_dict_proxy(self, did):
if self._dictcache.has_key(did):
return self._dictcache[did]
dp = DictProxy(self._conn, self._oid, did)
self._dictcache[did] = dp
return dp
class CodeProxy:
def __init__(self, conn, oid, cid):
self._conn = conn
self._oid = oid
self._cid = cid
def __getattr__(self, name):
if name == "co_name":
return self._conn.remotecall(self._oid, "code_name",
(self._cid,), {})
if name == "co_filename":
return self._conn.remotecall(self._oid, "code_filename",
(self._cid,), {})
class DictProxy:
def __init__(self, conn, oid, did):
self._conn = conn
self._oid = oid
self._did = did
def keys(self):
return self._conn.remotecall(self._oid, "dict_keys", (self._did,), {})
def __getitem__(self, key):
return self._conn.remotecall(self._oid, "dict_item",
(self._did, key), {})
def __getattr__(self, name):
##print >>sys.__stderr__, "failed DictProxy.__getattr__:", name
raise AttributeError, name
class GUIAdaper:
def __init__(self, conn, gui):
self.conn = conn
self.gui = gui
def interaction(self, message, fid, iid):
print "interaction(%s, %s, %s)" % (`message`, `fid`, `iid`)
frame = FrameProxy(self.conn, fid)
info = None # XXX for now
self.gui.interaction(message, frame, info)
class IdbProxy:
def __init__(self, conn, oid):
self.oid = oid
self.conn = conn
def call(self, methodname, *args, **kwargs):
##print "call %s %s %s" % (methodname, args, kwargs)
value = self.conn.remotecall(self.oid, methodname, args, kwargs)
##print "return %s" % `value`
return value
def run(self, cmd, locals):
# Ignores locals on purpose!
self.call("run", cmd)
def get_stack(self, frame, tb):
stack, i = self.call("get_stack", frame._fid, None)
stack = [(FrameProxy(self.conn, fid), k) for fid, k in stack]
return stack, i
def set_continue(self):
self.call("set_continue")
def set_step(self):
self.call("set_step")
def set_next(self, frame):
self.call("set_next", frame._fid)
def set_return(self, frame):
self.call("set_return", frame._fid)
def set_quit(self):
self.call("set_quit")
def start_remote_debugger(conn, pyshell):
#
# instruct the (remote) subprocess to create
# a debugger instance, and lets it know that
# the local GUIAdapter called "gui_adapter"
# is waiting notification of debugging events
#
ada_oid = "gui_adapter"
idb_oid = conn.remotecall("exec", "start_debugger", (ada_oid,), {})
idb = IdbProxy(conn, idb_oid)
gui = Debugger.Debugger(pyshell, idb)
ada = GUIAdaper(conn, gui)
conn.register(ada_oid, ada)
return gui
--- NEW FILE: rpc.py ---
# ASCII-art documentation
#
# +---------------------------------+ +----------+
# | SocketServer.BaseRequestHandler | | SocketIO |
# +---------------------------------+ +----------+
# ^ ^ ^
# | | |
# | + -------------------+ |
# | | |
# +-------------------------+ +-----------------+
# | RPCHandler | | RPCClient |
# |-------------------------| |-----------------|
# | register() | | remotecall() |
# | unregister() | | register() |
# | | | unregister() |
# | | | get_remote_proxy|
# +-------------------------+ +-----------------+
#
import sys
import socket
import select
import SocketServer
import struct
import cPickle as pickle
import threading
import traceback
import copy_reg
import types
import marshal
def unpickle_code(ms):
co = marshal.loads(ms)
assert isinstance(co, types.CodeType)
return co
def pickle_code(co):
assert isinstance(co, types.CodeType)
ms = marshal.dumps(co)
return unpickle_code, (ms,)
def unpickle_function(ms):
return ms
def pickle_function(fn):
assert isinstance(fn, type.FunctionType)
return `fn`
copy_reg.pickle(types.CodeType, pickle_code, unpickle_code)
copy_reg.pickle(types.FunctionType, pickle_function, unpickle_function)
BUFSIZE = 8*1024
class RPCServer(SocketServer.TCPServer):
def __init__(self, addr, handlerclass=None):
if handlerclass is None:
handlerclass = RPCHandler
self.objtable = objecttable
SocketServer.TCPServer.__init__(self, addr, handlerclass)
def verify_request(self, request, client_address):
host, port = client_address
if host != "127.0.0.1":
print "Disallowed host:", host
return 0
else:
return 1
def register(self, oid, object):
self.objtable[oid] = object
def unregister(self, oid):
try:
del self.objtable[oid]
except KeyError:
pass
objecttable = {}
class SocketIO:
debugging = 0
def __init__(self, sock, objtable=None, debugging=None):
self.mainthread = threading.currentThread()
if debugging is not None:
self.debugging = debugging
self.sock = sock
if objtable is None:
objtable = objecttable
self.objtable = objtable
self.statelock = threading.Lock()
self.responses = {}
self.cvars = {}
def close(self):
sock = self.sock
self.sock = None
if sock is not None:
sock.close()
def debug(self, *args):
if not self.debugging:
return
s = str(threading.currentThread().getName())
for a in args:
s = s + " " + str(a)
s = s + "\n"
sys.__stderr__.write(s)
def register(self, oid, object):
self.objtable[oid] = object
def unregister(self, oid):
try:
del self.objtable[oid]
except KeyError:
pass
def localcall(self, request):
##self.debug("localcall:", request)
try:
how, (oid, methodname, args, kwargs) = request
except TypeError:
return ("ERROR", "Bad request format")
assert how == "call"
if not self.objtable.has_key(oid):
return ("ERROR", "Unknown object id: %s" % `oid`)
obj = self.objtable[oid]
if methodname == "__methods__":
methods = {}
_getmethods(obj, methods)
return ("OK", methods)
if methodname == "__attributes__":
attributes = {}
_getattributes(obj, attributes)
return ("OK", attributes)
if not hasattr(obj, methodname):
return ("ERROR", "Unsupported method name: %s" % `methodname`)
method = getattr(obj, methodname)
try:
ret = method(*args, **kwargs)
if isinstance(ret, RemoteObject):
ret = remoteref(ret)
return ("OK", ret)
except:
##traceback.print_exc(file=sys.__stderr__)
typ, val, tb = info = sys.exc_info()
sys.last_type, sys.last_value, sys.last_traceback = info
if isinstance(typ, type(Exception)):
# Class exceptions
mod = typ.__module__
name = typ.__name__
if issubclass(typ, Exception):
args = val.args
else:
args = (str(val),)
else:
# String exceptions
mod = None
name = typ
args = (str(val),)
tb = traceback.extract_tb(tb)
return ("EXCEPTION", (mod, name, args, tb))
def remotecall(self, oid, methodname, args, kwargs):
seq = self.asynccall(oid, methodname, args, kwargs)
return self.asyncreturn(seq)
def asynccall(self, oid, methodname, args, kwargs):
request = ("call", (oid, methodname, args, kwargs))
seq = self.putrequest(request)
return seq
def asyncreturn(self, seq):
response = self.getresponse(seq)
return self.decoderesponse(response)
def decoderesponse(self, response):
how, what = response
if how == "OK":
return what
if how == "EXCEPTION":
mod, name, args, tb = what
self.traceback = tb
if mod:
try:
__import__(mod)
module = sys.modules[mod]
except ImportError:
pass
else:
try:
cls = getattr(module, name)
except AttributeError:
pass
else:
raise getattr(__import__(mod), name)(*args)
else:
if mod:
name = mod + "." + name
raise name, args
if how == "ERROR":
raise RuntimeError, what
raise SystemError, (how, what)
def mainloop(self):
try:
self.getresponse(None)
except EOFError:
pass
def getresponse(self, myseq):
response = self._getresponse(myseq)
if response is not None:
how, what = response
if how == "OK":
response = how, self._proxify(what)
return response
def _proxify(self, obj):
if isinstance(obj, RemoteProxy):
return RPCProxy(self, obj.oid)
if isinstance(obj, types.ListType):
return map(self._proxify, obj)
# XXX Check for other types -- not currently needed
return obj
def _getresponse(self, myseq):
if threading.currentThread() is self.mainthread:
# Main thread: does all reading of requests and responses
while 1:
response = self.pollresponse(myseq, None)
if response is not None:
return response
else:
# Auxiliary thread: wait for notification from main thread
cvar = threading.Condition(self.statelock)
self.statelock.acquire()
self.cvars[myseq] = cvar
while not self.responses.has_key(myseq):
cvar.wait()
response = self.responses[myseq]
del self.responses[myseq]
del self.cvars[myseq]
self.statelock.release()
return response
def putrequest(self, request):
seq = self.newseq()
self.putmessage((seq, request))
return seq
nextseq = 0
def newseq(self):
self.nextseq = seq = self.nextseq + 2
return seq
def putmessage(self, message):
try:
s = pickle.dumps(message)
except:
print >>sys.__stderr__, "Cannot pickle:", `message`
raise
s = struct.pack("<i", len(s)) + s
while len(s) > 0:
n = self.sock.send(s)
s = s[n:]
def ioready(self, wait=0.0):
r, w, x = select.select([self.sock.fileno()], [], [], wait)
return len(r)
buffer = ""
bufneed = 4
bufstate = 0 # meaning: 0 => reading count; 1 => reading data
def pollpacket(self, wait=0.0):
self._stage0()
if len(self.buffer) < self.bufneed:
if not self.ioready(wait):
return None
try:
s = self.sock.recv(BUFSIZE)
except socket.error:
raise EOFError
if len(s) == 0:
raise EOFError
self.buffer += s
self._stage0()
return self._stage1()
def _stage0(self):
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.buffer) >= self.bufneed:
packet = self.buffer[:self.bufneed]
self.buffer = self.buffer[self.bufneed:]
self.bufneed = 4
self.bufstate = 0
return packet
def pollmessage(self, wait=0.0):
packet = self.pollpacket(wait)
if packet is None:
return None
try:
message = pickle.loads(packet)
except:
print >>sys.__stderr__, "-----------------------"
print >>sys.__stderr__, "cannot unpickle packet:", `packet`
traceback.print_stack(file=sys.__stderr__)
print >>sys.__stderr__, "-----------------------"
raise
return message
def pollresponse(self, myseq, wait=0.0):
# Loop while there's no more buffered input or until specific response
while 1:
message = self.pollmessage(wait)
if message is None:
return None
wait = 0.0
seq, resq = message
if resq[0] == "call":
response = self.localcall(resq)
self.putmessage((seq, response))
continue
elif seq == myseq:
return resq
else:
self.statelock.acquire()
self.responses[seq] = resq
cv = self.cvars.get(seq)
if cv is not None:
cv.notify()
self.statelock.release()
continue
class RemoteObject:
# Token mix-in class
pass
def remoteref(obj):
oid = id(obj)
objecttable[oid] = obj
return RemoteProxy(oid)
class RemoteProxy:
def __init__(self, oid):
self.oid = oid
class RPCHandler(SocketServer.BaseRequestHandler, SocketIO):
debugging = 0
def __init__(self, sock, addr, svr):
svr.current_handler = self ## cgt xxx
SocketIO.__init__(self, sock)
SocketServer.BaseRequestHandler.__init__(self, sock, addr, svr)
def setup(self):
SocketServer.BaseRequestHandler.setup(self)
print >>sys.__stderr__, "Connection from", self.client_address
def finish(self):
print >>sys.__stderr__, "End connection from", self.client_address
SocketServer.BaseRequestHandler.finish(self)
def handle(self):
self.mainloop()
def get_remote_proxy(self, oid):
return RPCProxy(self, oid)
class RPCClient(SocketIO):
nextseq = 1 # Requests coming from the client are odd
def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM):
sock = socket.socket(family, type)
sock.connect(address)
SocketIO.__init__(self, sock)
def get_remote_proxy(self, oid):
return RPCProxy(self, oid)
class RPCProxy:
__methods = None
__attributes = None
def __init__(self, sockio, oid):
self.sockio = sockio
self.oid = oid
def __getattr__(self, name):
if self.__methods is None:
self.__getmethods()
if self.__methods.get(name):
return MethodProxy(self.sockio, self.oid, name)
if self.__attributes is None:
self.__getattributes()
if not self.__attributes.has_key(name):
raise AttributeError, name
__getattr__.DebuggerStepThrough=1
def __getattributes(self):
self.__attributes = self.sockio.remotecall(self.oid,
"__attributes__", (), {})
def __getmethods(self):
self.__methods = self.sockio.remotecall(self.oid,
"__methods__", (), {})
def _getmethods(obj, methods):
# Helper to get a list of methods from an object
# Adds names to dictionary argument 'methods'
for name in dir(obj):
attr = getattr(obj, name)
if callable(attr):
methods[name] = 1
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):
attributes[name] = 1
class MethodProxy:
def __init__(self, sockio, oid, name):
self.sockio = sockio
self.oid = oid
self.name = name
def __call__(self, *args, **kwargs):
value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
return value
#
# Self Test
#
def testServer(addr):
class RemotePerson:
def __init__(self,name):
self.name = name
def greet(self, name):
print "(someone called greet)"
print "Hello %s, I am %s." % (name, self.name)
print
def getName(self):
print "(someone called getName)"
print
return self.name
def greet_this_guy(self, name):
print "(someone called greet_this_guy)"
print "About to greet %s ..." % name
remote_guy = self.server.current_handler.get_remote_proxy(name)
remote_guy.greet("Thomas Edison")
print "Done."
print
person = RemotePerson("Thomas Edison")
svr = RPCServer(addr)
svr.register('thomas', person)
person.server = svr # only required if callbacks are used
# svr.serve_forever()
svr.handle_request() # process once only
def testClient(addr):
#
# demonstrates RPC Client
#
import time
clt=RPCClient(addr)
thomas = clt.get_remote_proxy("thomas")
print "The remote person's name is ..."
print thomas.getName()
# print clt.remotecall("thomas", "getName", (), {})
print
time.sleep(1)
print "Getting remote thomas to say hi..."
thomas.greet("Alexander Bell")
#clt.remotecall("thomas","greet",("Alexander Bell",), {})
print "Done."
print
time.sleep(2)
# demonstrates remote server calling local instance
class LocalPerson:
def __init__(self,name):
self.name = name
def greet(self, name):
print "You've greeted me!"
def getName(self):
return self.name
person = LocalPerson("Alexander Bell")
clt.register("alexander",person)
thomas.greet_this_guy("alexander")
# clt.remotecall("thomas","greet_this_guy",("alexander",), {})
def test():
addr=("localhost",8833)
if len(sys.argv) == 2:
if sys.argv[1]=='-server':
testServer(addr)
return
testClient(addr)
if __name__ == '__main__':
test()
--- NEW FILE: run.py ---
import sys
import rpc
def main():
port = 8833
if sys.argv[1:]:
port = int(sys.argv[1])
sys.argv[:] = [""]
addr = ("localhost", port)
svr = rpc.RPCServer(addr, MyHandler)
svr.handle_request() # A single request only
class MyHandler(rpc.RPCHandler):
def handle(self):
executive = Executive(self)
self.register("exec", executive)
sys.stdin = self.get_remote_proxy("stdin")
sys.stdout = self.get_remote_proxy("stdout")
sys.stderr = self.get_remote_proxy("stderr")
rpc.RPCHandler.handle(self)
class Executive:
def __init__(self, rpchandler):
self.conn = rpchandler
import __main__
self.locals = __main__.__dict__
def runcode(self, code):
exec code in self.locals
def start_debugger(self, gui_oid):
import RemoteDebugger
return RemoteDebugger.start_debugger(self.conn, gui_oid)
def stackviewer(self, flist_oid=None):
if not hasattr(sys, "last_traceback"):
return None
flist = None
if flist_oid is not None:
flist = self.conn.get_remote_proxy(flist_oid)
import RemoteObjectBrowser
import StackViewer
tb = sys.last_traceback
while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
tb = tb.tb_next
item = StackViewer.StackTreeItem(flist, tb)
return RemoteObjectBrowser.remote_object_tree_item(item)
Index: ScriptBinding.py
===================================================================
RCS file: /cvsroot/idlefork/idle/ScriptBinding.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** ScriptBinding.py 19 Jan 2002 10:41:51 -0000 1.4
--- ScriptBinding.py 26 May 2002 13:36:40 -0000 1.5
***************
*** 15,18 ****
--- 15,26 ----
code in the __main__ namespace.
+ XXX Redesign this interface (yet again) as follows:
+
+ - Present a dialog box for ``Run script''
+
+ - Allow specify command line arguments in the dialog box
+
+ - Restart the interpreter when running a script
+
"""
***************
*** 26,32 ****
This means that either:
! (1) your indentation is outright incorrect (easy to fix), or
! (2) your indentation mixes tabs and spaces in a way that depends on \
how many spaces a tab is worth.
--- 34,40 ----
This means that either:
! 1) your indentation is outright incorrect (easy to fix), or
! 2) your indentation mixes tabs and spaces in a way that depends on \
how many spaces a tab is worth.
***************
*** 106,109 ****
--- 114,121 ----
def import_module_event(self, event):
+ flist = self.editwin.flist
+ shell = flist.open_shell()
+ interp = shell.interp
+
filename = self.getfilename()
if not filename:
***************
*** 111,131 ****
modname, ext = os.path.splitext(os.path.basename(filename))
- if sys.modules.has_key(modname):
- mod = sys.modules[modname]
- else:
- mod = imp.new_module(modname)
- sys.modules[modname] = mod
- mod.__file__ = filename
- setattr(sys.modules['__main__'], modname, mod)
dir = os.path.dirname(filename)
dir = os.path.normpath(os.path.abspath(dir))
- if dir not in sys.path:
- sys.path.insert(0, dir)
! flist = self.editwin.flist
! shell = flist.open_shell()
! interp = shell.interp
! interp.runcode("reload(%s)" % modname)
def run_script_event(self, event):
--- 123,142 ----
modname, ext = os.path.splitext(os.path.basename(filename))
dir = os.path.dirname(filename)
dir = os.path.normpath(os.path.abspath(dir))
! interp.runcode("""if 1:
! import sys as _sys
! if %s not in _sys.path:
! _sys.path.insert(0, %s)
! if _sys.modules.get(%s):
! del _sys
! import %s
! reload(%s)
! else:
! del _sys
! import %s
! \n""" % (`dir`, `dir`, `modname`, modname, modname, modname))
def run_script_event(self, event):
***************
*** 137,144 ****
shell = flist.open_shell()
interp = shell.interp
! if (not sys.argv or
! os.path.basename(sys.argv[0]) != os.path.basename(filename)):
! # XXX Too often this discards arguments the user just set...
! sys.argv = [filename]
interp.execfile(filename)
--- 148,161 ----
shell = flist.open_shell()
interp = shell.interp
! # XXX Too often this discards arguments the user just set...
! interp.runcommand("""if 1:
! _filename = %s
! import sys as _sys
! from os.path import basename as _basename
! if (not _sys.argv or
! _basename(_sys.argv[0]) != _basename(_filename)):
! _sys.argv = [_filename]
! del _filename, _sys, _basename
! \n""" % `filename`)
interp.execfile(filename)
Index: Debugger.py
===================================================================
RCS file: /cvsroot/idlefork/idle/Debugger.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** Debugger.py 25 Feb 2002 23:22:08 -0000 1.4
--- Debugger.py 26 May 2002 13:36:40 -0000 1.5
***************
*** 1,4 ****
--- 1,5 ----
import os
import bdb
+ import types
import traceback
from Tkinter import *
***************
*** 8,25 ****
! class Debugger(bdb.Bdb):
- interacting = 0
vstack = vsource = vlocals = vglobals = None
! def __init__(self, pyshell):
! bdb.Bdb.__init__(self)
self.pyshell = pyshell
self.make_gui()
! def canonic(self, filename):
! # Canonicalize filename -- called by Bdb
! return os.path.normcase(os.path.abspath(filename))
def close(self, event=None):
--- 9,72 ----
! class Idb(bdb.Bdb):
!
! def __init__(self, gui):
! self.gui = gui
! bdb.Bdb.__init__(self)
!
! def user_line(self, frame):
! # get the currently executing function
! co_filename = frame.f_code.co_filename
! co_name = frame.f_code.co_name
! try:
! func = frame.f_locals[co_name]
! if getattr(func, "DebuggerStepThrough", 0):
! print "XXXX DEBUGGER STEPPING THROUGH"
! self.set_step()
! return
! except:
! pass
! if co_filename in ('rpc.py', '<string>'):
! self.set_step()
! return
! if co_filename.endswith('threading.py'):
! self.set_step()
! return
! message = self.__frame2message(frame)
! self.gui.interaction(message, frame)
!
! def user_exception(self, frame, info):
! message = self.__frame2message(frame)
! self.gui.interaction(message, frame, info)
!
! def __frame2message(self, frame):
! code = frame.f_code
! filename = code.co_filename
! lineno = frame.f_lineno
! basename = os.path.basename(filename)
! message = "%s:%s" % (basename, lineno)
! if code.co_name != "?":
! message = "%s: %s()" % (message, code.co_name)
! return message
+ class Debugger:
+
+ interacting = 0
vstack = vsource = vlocals = vglobals = None
! def __init__(self, pyshell, idb=None):
! if idb is None:
! idb = Idb(self)
self.pyshell = pyshell
+ self.idb = idb
self.make_gui()
! def run(self, *args):
! try:
! self.interacting = 1
! return self.idb.run(*args)
! finally:
! self.interacting = 0
def close(self, event=None):
***************
*** 32,53 ****
self.top.destroy()
- def run(self, *args):
- try:
- self.interacting = 1
- return apply(bdb.Bdb.run, (self,) + args)
- finally:
- self.interacting = 0
-
- def user_line(self, frame):
- self.interaction(frame)
-
- def user_return(self, frame, rv):
- # XXX show rv?
- ##self.interaction(frame)
- pass
-
- def user_exception(self, frame, info):
- self.interaction(frame, info)
-
def make_gui(self):
pyshell = self.pyshell
--- 79,82 ----
***************
*** 129,142 ****
frame = None
! def interaction(self, frame, info=None):
self.frame = frame
- code = frame.f_code
- file = code.co_filename
- base = os.path.basename(file)
- lineno = frame.f_lineno
- #
- message = "%s:%s" % (base, lineno)
- if code.co_name != "?":
- message = "%s: %s()" % (message, code.co_name)
self.status.configure(text=message)
#
--- 158,163 ----
frame = None
! def interaction(self, message, frame, info=None):
self.frame = frame
self.status.configure(text=message)
#
***************
*** 161,165 ****
sv = self.stackviewer
if sv:
! stack, i = self.get_stack(self.frame, tb)
sv.load_stack(stack, i)
#
--- 182,186 ----
sv = self.stackviewer
if sv:
! stack, i = self.idb.get_stack(self.frame, tb)
sv.load_stack(stack, i)
#
***************
*** 185,214 ****
if not frame:
return
code = frame.f_code
! file = code.co_filename
lineno = frame.f_lineno
! if file[:1] + file[-1:] != "<>" and os.path.exists(file):
! edit = self.flist.open(file)
! if edit:
! edit.gotoline(lineno)
def cont(self):
! self.set_continue()
self.root.quit()
def step(self):
! self.set_step()
self.root.quit()
def next(self):
! self.set_next(self.frame)
self.root.quit()
def ret(self):
! self.set_return(self.frame)
self.root.quit()
def quit(self):
! self.set_quit()
self.root.quit()
--- 206,237 ----
if not frame:
return
+ filename, lineno = self.__frame2fileline(frame)
+ if filename[:1] + filename[-1:] != "<>" and os.path.exists(filename):
+ self.flist.gotofileline(filename, lineno)
+
+ def __frame2fileline(self, frame):
code = frame.f_code
! filename = code.co_filename
lineno = frame.f_lineno
! return filename, lineno
def cont(self):
! self.idb.set_continue()
self.root.quit()
def step(self):
! self.idb.set_step()
self.root.quit()
def next(self):
! self.idb.set_next(self.frame)
self.root.quit()
def ret(self):
! self.idb.set_return(self.frame)
self.root.quit()
def quit(self):
! self.idb.set_quit()
self.root.quit()
***************
*** 220,224 ****
self.fstack, self.flist, self)
if self.frame:
! stack, i = self.get_stack(self.frame, None)
sv.load_stack(stack, i)
else:
--- 243,247 ----
self.fstack, self.flist, self)
if self.frame:
! stack, i = self.idb.get_stack(self.frame, None)
sv.load_stack(stack, i)
else:
***************
*** 234,237 ****
--- 257,261 ----
def show_frame(self, (frame, lineno)):
+ # Called from OldStackViewer
self.frame = frame
self.show_variables()
***************
*** 296,309 ****
# A literal copy of Bdb.set_break() without the print statement at the end
! def set_break(self, filename, lineno, temporary=0, cond = None):
! import linecache # Import as late as possible
! filename = self.canonic(filename)
! line = linecache.getline(filename, lineno)
! if not line:
! return 'That line does not exist!'
! if not self.breaks.has_key(filename):
! self.breaks[filename] = []
! list = self.breaks[filename]
! if not lineno in list:
! list.append(lineno)
! bp = bdb.Breakpoint(filename, lineno, temporary, cond)
--- 320,333 ----
# A literal copy of Bdb.set_break() without the print statement at the end
! #def set_break(self, filename, lineno, temporary=0, cond = None):
! # import linecache # Import as late as possible
! # filename = self.canonic(filename)
! # line = linecache.getline(filename, lineno)
! # if not line:
! # return 'That line does not exist!'
! # if not self.breaks.has_key(filename):
! # self.breaks[filename] = []
! # list = self.breaks[filename]
! # if not lineno in list:
! # list.append(lineno)
! # bp = bdb.Breakpoint(filename, lineno, temporary, cond)
Index: PyShell.py
===================================================================
RCS file: /cvsroot/idlefork/idle/PyShell.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -r1.13 -r1.14
*** PyShell.py 27 Mar 2002 00:51:53 -0000 1.13
--- PyShell.py 26 May 2002 13:36:41 -0000 1.14
***************
*** 1,908 ****
! #! /usr/bin/env python
!
! # changes by dscherer@cmu.edu
!
! # The main() function has been replaced by a whole class, in order to
! # address the constraint that only one process can sit on the port
! # hard-coded into the loader.
!
! # It attempts to load the RPC protocol server and publish itself. If
! # that fails, it assumes that some other copy of IDLE is already running
[...1958 lines suppressed...]
! interp.execfile(filename)
!
! if debug:
! shell.open_debugger()
! if cmd:
! interp.execsource(cmd)
! elif script:
! if os.path.isfile(script):
! interp.execfile(script)
! else:
! print "No script file: ", script
! shell.begin()
!
! self.idle()
! root.mainloop()
! root.destroy()
!
!
! if __name__ == "__main__":
! main()