Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bc28613

Browse files
committed
M PyShell.py
M RemoteDebugger.py M rpc.py Fix the incorrect shell exception tracebacks generated when running under debugger control: 1. Use rpc.SocketIO.asynccall() instead of remotecall() to handle the IdbProxy.run() command. 2. Add a 'shell' attribute to RemoteDebugger.IdbProxy to allow setting of ModifiedInterpreter's active_seq attribute from RemoteDebugger code. 3. Cleanup PyShell.ModifiedInterpreter.runcode() and remove ambiguity regarding use of begin/endexecuting(). 4. In runcode() and cleanup_traceback() use 'console' instead of 'file' to denote the entity to which the exception traceback is printed. 5. Enhance cleanup_traceback() so if the traceback is pruned entirely away (the error is in IDLE internals) it will be displayed in its entirety instead. 6. ModifiedInterpreter.runcode() now prints ERROR RPC returns to both console and __stderr__. 7. Make a small tweak to the rpc.py debug messages.
1 parent cd5c8c2 commit bc28613

3 files changed

Lines changed: 45 additions & 40 deletions

File tree

Lib/idlelib/PyShell.py

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -399,16 +399,16 @@ def poll_subprocess(self):
399399
self.tkconsole.resetoutput()
400400
self.active_seq = None
401401
how, what = response
402-
file = self.tkconsole.console
402+
console = self.tkconsole.console
403403
if how == "OK":
404404
if what is not None:
405-
print >>file, `what`
405+
print >>console, `what`
406406
elif how == "EXCEPTION":
407407
mod, name, args, tb = what
408-
print >>file, 'Traceback (most recent call last):'
409-
exclude = ("run.py", "rpc.py")
410-
self.cleanup_traceback(tb, exclude)
411-
traceback.print_list(tb, file=file)
408+
print >>console, 'Traceback (most recent call last):'
409+
exclude = ("run.py", "rpc.py", "RemoteDebugger.py", "bdb.py")
410+
self.cleanup_traceback(tb, exclude, console)
411+
traceback.print_list(tb, file=console)
412412
# try to reinstantiate the exception, stuff in the args:
413413
try:
414414
etype = eval(mod + '.' + name)
@@ -419,18 +419,20 @@ def poll_subprocess(self):
419419
val = args
420420
lines = traceback.format_exception_only(etype, val)
421421
for line in lines[:-1]:
422-
traceback._print(file, line, '')
423-
traceback._print(file, lines[-1], '')
422+
traceback._print(console, line, '')
423+
traceback._print(console, lines[-1], '')
424424
if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
425425
self.remote_stack_viewer()
426426
elif how == "ERROR":
427427
errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
428428
print >>sys.__stderr__, errmsg, what
429-
print >>file, errmsg, what
429+
print >>console, errmsg, what
430+
# we received a response to the currently active seq number:
430431
self.tkconsole.endexecuting()
431432

432-
def cleanup_traceback(self, tb, exclude):
433+
def cleanup_traceback(self, tb, exclude, console):
433434
"Remove excluded traces from beginning/end of tb; get cached lines"
435+
orig_tb = tb[:]
434436
while tb:
435437
for rpcfile in exclude:
436438
if tb[0][0].count(rpcfile):
@@ -445,6 +447,11 @@ def cleanup_traceback(self, tb, exclude):
445447
else:
446448
break
447449
del tb[-1]
450+
if len(tb) == 0:
451+
# error was in IDLE internals, don't prune!
452+
tb[:] = orig_tb[:]
453+
print>>sys.__stderr__, "** IDLE Internal Error: ", tb
454+
print>>console, "** IDLE Internal Error **"
448455
for i in range(len(tb)):
449456
fn, ln, nm, line = tb[i]
450457
if nm == '?':
@@ -617,31 +624,26 @@ def runcode(self, code):
617624
warnings.filters[:] = self.save_warnings_filters
618625
self.save_warnings_filters = None
619626
debugger = self.debugger
620-
if not debugger and self.rpcclt is not None:
621-
self.tkconsole.beginexecuting()
622-
self.active_seq = self.rpcclt.asynccall("exec", "runcode",
623-
(code,), {})
624-
return
627+
self.tkconsole.beginexecuting()
625628
try:
626-
self.tkconsole.beginexecuting()
627-
try:
628-
if debugger:
629-
debugger.run(code, self.locals)
630-
else:
631-
exec code in self.locals
632-
except SystemExit:
633-
if tkMessageBox.askyesno(
634-
"Exit?",
635-
"Do you want to exit altogether?",
636-
default="yes",
637-
master=self.tkconsole.text):
638-
raise
639-
else:
640-
self.showtraceback()
641-
except:
629+
if not debugger and self.rpcclt is not None:
630+
self.active_seq = self.rpcclt.asynccall("exec", "runcode",
631+
(code,), {})
632+
elif debugger:
633+
debugger.run(code, self.locals)
634+
else:
635+
exec code in self.locals
636+
except SystemExit:
637+
if tkMessageBox.askyesno(
638+
"Exit?",
639+
"Do you want to exit altogether?",
640+
default="yes",
641+
master=self.tkconsole.text):
642+
raise
643+
else:
642644
self.showtraceback()
643-
finally:
644-
self.tkconsole.endexecuting()
645+
except:
646+
self.showtraceback()
645647

646648
def write(self, s):
647649
"Override base class method"

Lib/idlelib/RemoteDebugger.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,19 +287,21 @@ def interaction(self, message, fid, modified_info):
287287

288288
class IdbProxy:
289289

290-
def __init__(self, conn, oid):
290+
def __init__(self, conn, shell, oid):
291291
self.oid = oid
292292
self.conn = conn
293+
self.shell = shell
293294

294295
def call(self, methodname, *args, **kwargs):
295-
##print "call %s %s %s" % (methodname, args, kwargs)
296+
##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs)
296297
value = self.conn.remotecall(self.oid, methodname, args, kwargs)
297-
##print "return %s" % `value`
298+
##print "**IdbProxy.call %s returns %s" % (methodname, `value`)
298299
return value
299300

300301
def run(self, cmd, locals):
301302
# Ignores locals on purpose!
302-
self.call("run", cmd)
303+
seq = self.conn.asynccall(self.oid, "run", (cmd,), {})
304+
self.shell.interp.active_seq = seq
303305

304306
def get_stack(self, frame, tbid):
305307
# passing frame and traceback IDs, not the objects themselves
@@ -352,7 +354,7 @@ def start_remote_debugger(rpcclt, pyshell):
352354

353355
idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
354356
(gui_adap_oid,), {})
355-
idb_proxy = IdbProxy(rpcclt, idb_adap_oid)
357+
idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid)
356358
gui = Debugger.Debugger(pyshell, idb_proxy)
357359
gui_adap = GUIAdapter(rpcclt, gui)
358360
rpcclt.register(gui_adap_oid, gui_adap)

Lib/idlelib/rpc.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,10 @@ def pollresponse(self, myseq, wait=0.0):
361361
seq, resq = message
362362
self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
363363
if resq[0] == "call":
364-
self.debug("pollresponse:%d:call_localcall" % seq)
364+
self.debug("pollresponse:%d:localcall:call:" % seq)
365365
response = self.localcall(resq)
366-
self.debug("pollresponse:%d:response:%s" % (seq, response))
366+
self.debug("pollresponse:%d:localcall:response:%s"
367+
% (seq, response))
367368
self.putmessage((seq, response))
368369
continue
369370
elif seq == myseq:

0 commit comments

Comments
 (0)