Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions
idlelib.PyShell.ModifiedInterpreter Class Reference
Inheritance diagram for idlelib.PyShell.ModifiedInterpreter:
Inheritance graph
[legend]
Collaboration diagram for idlelib.PyShell.ModifiedInterpreter:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def spawn_subprocess
def build_subprocess_arglist
def start_subprocess
def restart_subprocess
def interrupt_subprocess
def kill_subprocess
def terminate_subprocess
def transfer_path
def poll_subprocess
def setdebugger
def getdebugger
def open_remote_stack_viewer
def remote_stack_viewer
def execsource
def execfile
def runsource
def stuffsource
def prepend_syspath
def showsyntaxerror
def showtraceback
def checklinecache
def runcommand
def runcode
def write
def display_port_binding_error
def display_no_subprocess_error
def display_executing_dialog
def runsource

Public Attributes

 tkconsole
 save_warnings_filters
 restarting
 subprocess_arglist
 port
 more
 gid
 locals
 compile

Static Public Attributes

 rpcclt = None
 rpcsubproc = None
 active_seq = None
 debugger = None
int gid = 0

Private Member Functions

def __request_interrupt

Detailed Description

Definition at line 331 of file PyShell.py.


Constructor & Destructor Documentation

def idlelib.PyShell.ModifiedInterpreter.__init__ (   self,
  locals 
)
Constructor.

The optional 'locals' argument specifies the dictionary in
which code will be executed; it defaults to a newly created
dictionary with key "__name__" set to "__console__" and key
"__doc__" set to None.

Reimplemented from code.InteractiveInterpreter.

Definition at line 333 of file PyShell.py.

00333 
00334     def __init__(self, tkconsole):
00335         self.tkconsole = tkconsole
00336         locals = sys.modules['__main__'].__dict__
00337         InteractiveInterpreter.__init__(self, locals=locals)
00338         self.save_warnings_filters = None
00339         self.restarting = False
00340         self.subprocess_arglist = None
00341         self.port = PORT

Here is the caller graph for this function:


Member Function Documentation

Definition at line 451 of file PyShell.py.

00451 
00452     def __request_interrupt(self):
00453         self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})

Here is the caller graph for this function:

Definition at line 350 of file PyShell.py.

00350 
00351     def build_subprocess_arglist(self):
00352         assert (self.port!=0), (
00353             "Socket should have been assigned a port number.")
00354         w = ['-W' + s for s in sys.warnoptions]
00355         # Maybe IDLE is installed and is being accessed via sys.path,
00356         # or maybe it's not installed and the idle.py script is being
00357         # run from the IDLE source directory.
00358         del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
00359                                        default=False, type='bool')
00360         if __name__ == 'idlelib.PyShell':
00361             command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
00362         else:
00363             command = "__import__('run').main(%r)" % (del_exitf,)
00364         return [sys.executable] + w + ["-c", command, str(self.port)]

Here is the caller graph for this function:

Definition at line 666 of file PyShell.py.

00666 
00667     def checklinecache(self):
00668         c = linecache.cache
00669         for key in list(c.keys()):
00670             if key[:1] + key[-1:] != "<>":
00671                 del c[key]

Here is the caller graph for this function:

Definition at line 756 of file PyShell.py.

00756 
00757     def display_executing_dialog(self):
00758         tkMessageBox.showerror(
00759             "Already executing",
00760             "The Python Shell window is already executing a command; "
00761             "please wait until it is finished.",
00762             master=self.tkconsole.text)
00763 

Here is the caller graph for this function:

Definition at line 748 of file PyShell.py.

00748 
00749     def display_no_subprocess_error(self):
00750         tkMessageBox.showerror(
00751             "Subprocess Startup Error",
00752             "IDLE's subprocess didn't make connection.  Either IDLE can't "
00753             "start a subprocess or personal firewall software is blocking "
00754             "the connection.",
00755             master=self.tkconsole.text)

Here is the caller graph for this function:

Definition at line 737 of file PyShell.py.

00737 
00738     def display_port_binding_error(self):
00739         tkMessageBox.showerror(
00740             "Port Binding Error",
00741             "IDLE can't bind to a TCP/IP port, which is necessary to "
00742             "communicate with its Python execution server.  This might be "
00743             "because no networking is installed on this computer.  "
00744             "Run IDLE with the -n command line switch to start without a "
00745             "subprocess and refer to Help/IDLE Help 'Running without a "
00746             "subprocess' for further details.",
00747             master=self.tkconsole.text)

Here is the caller graph for this function:

def idlelib.PyShell.ModifiedInterpreter.execfile (   self,
  filename,
  source = None 
)

Definition at line 571 of file PyShell.py.

00571 
00572     def execfile(self, filename, source=None):
00573         "Execute an existing file"
00574         if source is None:
00575             source = open(filename, "r").read()
00576         try:
00577             code = compile(source, filename, "exec")
00578         except (OverflowError, SyntaxError):
00579             self.tkconsole.resetoutput()
00580             tkerr = self.tkconsole.stderr
00581             print('*** Error in script or command!\n', file=tkerr)
00582             print('Traceback (most recent call last):', file=tkerr)
00583             InteractiveInterpreter.showsyntaxerror(self, filename)
00584             self.tkconsole.showprompt()
00585         else:
00586             self.runcode(code)

Here is the call graph for this function:

Here is the caller graph for this function:

def idlelib.PyShell.ModifiedInterpreter.execsource (   self,
  source 
)

Definition at line 566 of file PyShell.py.

00566 
00567     def execsource(self, source):
00568         "Like runsource() but assumes complete exec source"
00569         filename = self.stuffsource(source)
00570         self.execfile(filename, source)

Here is the call graph for this function:

Definition at line 531 of file PyShell.py.

00531 
00532     def getdebugger(self):
00533         return self.debugger

Here is the caller graph for this function:

Definition at line 454 of file PyShell.py.

Here is the call graph for this function:

Definition at line 457 of file PyShell.py.

00457 
00458     def kill_subprocess(self):
00459         try:
00460             self.rpcclt.close()
00461         except AttributeError:  # no socket
00462             pass
00463         self.terminate_subprocess()
00464         self.tkconsole.executing = False
00465         self.rpcclt = None

Here is the call graph for this function:

Initiate the remote stack viewer from a separate thread.

This method is called from the subprocess, and by returning from this
method we allow the subprocess to unblock.  After a bit the shell
requests the subprocess to open the remote stack viewer which returns a
static object looking at the last exception.  It is queried through
the RPC mechanism.

Definition at line 534 of file PyShell.py.

00534 
00535     def open_remote_stack_viewer(self):
00536         """Initiate the remote stack viewer from a separate thread.
00537 
00538         This method is called from the subprocess, and by returning from this
00539         method we allow the subprocess to unblock.  After a bit the shell
00540         requests the subprocess to open the remote stack viewer which returns a
00541         static object looking at the last exception.  It is queried through
00542         the RPC mechanism.
00543 
00544         """
00545         self.tkconsole.text.after(300, self.remote_stack_viewer)
00546         return

Here is the call graph for this function:

Definition at line 488 of file PyShell.py.

00488 
00489     def poll_subprocess(self):
00490         clt = self.rpcclt
00491         if clt is None:
00492             return
00493         try:
00494             response = clt.pollresponse(self.active_seq, wait=0.05)
00495         except (EOFError, IOError, KeyboardInterrupt):
00496             # lost connection or subprocess terminated itself, restart
00497             # [the KBI is from rpc.SocketIO.handle_EOF()]
00498             if self.tkconsole.closing:
00499                 return
00500             response = None
00501             self.restart_subprocess()
00502         if response:
00503             self.tkconsole.resetoutput()
00504             self.active_seq = None
00505             how, what = response
00506             console = self.tkconsole.console
00507             if how == "OK":
00508                 if what is not None:
00509                     print(repr(what), file=console)
00510             elif how == "EXCEPTION":
00511                 if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
00512                     self.remote_stack_viewer()
00513             elif how == "ERROR":
00514                 errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
00515                 print(errmsg, what, file=sys.__stderr__)
00516                 print(errmsg, what, file=console)
00517             # we received a response to the currently active seq number:
00518             try:
00519                 self.tkconsole.endexecuting()
00520             except AttributeError:  # shell may have closed
00521                 pass
00522         # Reschedule myself
00523         if not self.tkconsole.closing:
00524             self.tkconsole.text.after(self.tkconsole.pollinterval,
00525                                       self.poll_subprocess)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 620 of file PyShell.py.

00620 
00621     def prepend_syspath(self, filename):
00622         "Prepend sys.path with file's directory if not already included"
00623         self.runcommand("""if 1:
00624             _filename = %r
00625             import sys as _sys
00626             from os.path import dirname as _dirname
00627             _dir = _dirname(_filename)
00628             if not _dir in _sys.path:
00629                 _sys.path.insert(0, _dir)
00630             del _filename, _sys, _dirname, _dir
00631             \n""" % (filename,))

Here is the call graph for this function:

Definition at line 547 of file PyShell.py.

00547 
00548     def remote_stack_viewer(self):
00549         from idlelib import RemoteObjectBrowser
00550         oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
00551         if oid is None:
00552             self.tkconsole.root.bell()
00553             return
00554         item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
00555         from idlelib.TreeWidget import ScrolledCanvas, TreeNode
00556         top = Toplevel(self.tkconsole.root)
00557         theme = idleConf.GetOption('main','Theme','name')
00558         background = idleConf.GetHighlight(theme, 'normal')['background']
00559         sc = ScrolledCanvas(top, bg=background, highlightthickness=0)
00560         sc.frame.pack(expand=1, fill="both")
00561         node = TreeNode(sc.canvas, None, item)
00562         node.expand()
00563         # XXX Should GC the remote tree when closing the window

Here is the caller graph for this function:

Definition at line 407 of file PyShell.py.

00407 
00408     def restart_subprocess(self):
00409         if self.restarting:
00410             return self.rpcclt
00411         self.restarting = True
00412         # close only the subprocess debugger
00413         debug = self.getdebugger()
00414         if debug:
00415             try:
00416                 # Only close subprocess debugger, don't unregister gui_adap!
00417                 RemoteDebugger.close_subprocess_debugger(self.rpcclt)
00418             except:
00419                 pass
00420         # Kill subprocess, spawn a new one, accept connection.
00421         self.rpcclt.close()
00422         self.terminate_subprocess()
00423         console = self.tkconsole
00424         was_executing = console.executing
00425         console.executing = False
00426         self.spawn_subprocess()
00427         try:
00428             self.rpcclt.accept()
00429         except socket.timeout as err:
00430             self.display_no_subprocess_error()
00431             return None
00432         self.transfer_path()
00433         # annotate restart in shell window and mark it
00434         console.text.delete("iomark", "end-1c")
00435         if was_executing:
00436             console.write('\n')
00437             console.showprompt()
00438         halfbar = ((int(console.width) - 16) // 2) * '='
00439         console.write(halfbar + ' RESTART ' + halfbar)
00440         console.text.mark_set("restart", "end-1c")
00441         console.text.mark_gravity("restart", "left")
00442         console.showprompt()
00443         # restart subprocess debugger
00444         if debug:
00445             # Restarted debugger connects to current instance of debug GUI
00446             gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
00447             # reload remote debugger breakpoints for all PyShellEditWindows
00448             debug.load_breakpoints()
00449         self.restarting = False
00450         return self.rpcclt

Here is the call graph for this function:

Here is the caller graph for this function:

def idlelib.PyShell.ModifiedInterpreter.runcode (   self,
  code 
)
Execute a code object.

When an exception occurs, self.showtraceback() is called to
display a traceback.  All exceptions are caught except
SystemExit, which is reraised.

A note about KeyboardInterrupt: this exception may occur
elsewhere in this code, and may not always be caught.  The
caller should be prepared to deal with it.

Reimplemented from code.InteractiveInterpreter.

Definition at line 684 of file PyShell.py.

00684 
00685     def runcode(self, code):
00686         "Override base class method"
00687         if self.tkconsole.executing:
00688             self.interp.restart_subprocess()
00689         self.checklinecache()
00690         if self.save_warnings_filters is not None:
00691             warnings.filters[:] = self.save_warnings_filters
00692             self.save_warnings_filters = None
00693         debugger = self.debugger
00694         try:
00695             self.tkconsole.beginexecuting()
00696             if not debugger and self.rpcclt is not None:
00697                 self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
00698                                                         (code,), {})
00699             elif debugger:
00700                 debugger.run(code, self.locals)
00701             else:
00702                 exec(code, self.locals)
00703         except SystemExit:
00704             if not self.tkconsole.closing:
00705                 if tkMessageBox.askyesno(
00706                     "Exit?",
00707                     "Do you want to exit altogether?",
00708                     default="yes",
00709                     master=self.tkconsole.text):
00710                     raise
00711                 else:
00712                     self.showtraceback()
00713             else:
00714                 raise
00715         except:
00716             if use_subprocess:
00717                 print("IDLE internal error in runcode()",
00718                       file=self.tkconsole.stderr)
00719                 self.showtraceback()
00720                 self.tkconsole.endexecuting()
00721             else:
00722                 if self.tkconsole.canceled:
00723                     self.tkconsole.canceled = False
00724                     print("KeyboardInterrupt", file=self.tkconsole.stderr)
00725                 else:
00726                     self.showtraceback()
00727         finally:
00728             if not use_subprocess:
00729                 try:
00730                     self.tkconsole.endexecuting()
00731                 except AttributeError:  # shell may have closed
00732                     pass

Here is the call graph for this function:

Definition at line 672 of file PyShell.py.

00672 
00673     def runcommand(self, code):
00674         "Run the code without invoking the debugger"
00675         # The code better not raise an exception!
00676         if self.tkconsole.executing:
00677             self.display_executing_dialog()
00678             return 0
00679         if self.rpcclt:
00680             self.rpcclt.remotequeue("exec", "runcode", (code,), {})
00681         else:
00682             exec(code, self.locals)
00683         return 1

Here is the call graph for this function:

Here is the caller graph for this function:

def code.InteractiveInterpreter.runsource (   self,
  source,
  filename = "<input>",
  symbol = "single" 
) [inherited]
Compile and run some source in the interpreter.

Arguments are as for compile_command().

One several things can happen:

1) The input is incorrect; compile_command() raised an
exception (SyntaxError or OverflowError).  A syntax traceback
will be printed by calling the showsyntaxerror() method.

2) The input is incomplete, and more input is required;
compile_command() returned None.  Nothing happens.

3) The input is complete; compile_command() returned a code
object.  The code is executed by calling self.runcode() (which
also handles run-time exceptions, except for SystemExit).

The return value is True in case 2, False in the other cases (unless
an exception is raised).  The return value can be used to
decide whether to use sys.ps1 or sys.ps2 to prompt the next
line.

Definition at line 38 of file code.py.

00038 
00039     def runsource(self, source, filename="<input>", symbol="single"):
00040         """Compile and run some source in the interpreter.
00041 
00042         Arguments are as for compile_command().
00043 
00044         One several things can happen:
00045 
00046         1) The input is incorrect; compile_command() raised an
00047         exception (SyntaxError or OverflowError).  A syntax traceback
00048         will be printed by calling the showsyntaxerror() method.
00049 
00050         2) The input is incomplete, and more input is required;
00051         compile_command() returned None.  Nothing happens.
00052 
00053         3) The input is complete; compile_command() returned a code
00054         object.  The code is executed by calling self.runcode() (which
00055         also handles run-time exceptions, except for SystemExit).
00056 
00057         The return value is True in case 2, False in the other cases (unless
00058         an exception is raised).  The return value can be used to
00059         decide whether to use sys.ps1 or sys.ps2 to prompt the next
00060         line.
00061 
00062         """
00063         try:
00064             code = self.compile(source, filename, symbol)
00065         except (OverflowError, SyntaxError, ValueError):
00066             # Case 1
00067             self.showsyntaxerror(filename)
00068             return False
00069 
00070         if code is None:
00071             # Case 2
00072             return True
00073 
00074         # Case 3
00075         self.runcode(code)
00076         return False

Here is the call graph for this function:

Here is the caller graph for this function:

def idlelib.PyShell.ModifiedInterpreter.runsource (   self,
  source 
)

Definition at line 587 of file PyShell.py.

00587 
00588     def runsource(self, source):
00589         "Extend base class method: Stuff the source in the line cache first"
00590         filename = self.stuffsource(source)
00591         self.more = 0
00592         self.save_warnings_filters = warnings.filters[:]
00593         warnings.filterwarnings(action="error", category=SyntaxWarning)
00594         # at the moment, InteractiveInterpreter expects str
00595         assert isinstance(source, str)
00596         #if isinstance(source, str):
00597         #    from idlelib import IOBinding
00598         #    try:
00599         #        source = source.encode(IOBinding.encoding)
00600         #    except UnicodeError:
00601         #        self.tkconsole.resetoutput()
00602         #        self.write("Unsupported characters in input\n")
00603         #        return
00604         try:
00605             # InteractiveInterpreter.runsource() calls its runcode() method,
00606             # which is overridden (see below)
00607             return InteractiveInterpreter.runsource(self, source, filename)
00608         finally:
00609             if self.save_warnings_filters is not None:
00610                 warnings.filters[:] = self.save_warnings_filters
00611                 self.save_warnings_filters = None

Here is the call graph for this function:

def idlelib.PyShell.ModifiedInterpreter.setdebugger (   self,
  debugger 
)

Definition at line 528 of file PyShell.py.

00528 
00529     def setdebugger(self, debugger):
00530         self.debugger = debugger

def idlelib.PyShell.ModifiedInterpreter.showsyntaxerror (   self,
  filename = None 
)
Override Interactive Interpreter method: Use Colorizing

Color the offending position instead of printing it and pointing at it
with a caret.

Reimplemented from code.InteractiveInterpreter.

Definition at line 632 of file PyShell.py.

00632 
00633     def showsyntaxerror(self, filename=None):
00634         """Override Interactive Interpreter method: Use Colorizing
00635 
00636         Color the offending position instead of printing it and pointing at it
00637         with a caret.
00638 
00639         """
00640         tkconsole = self.tkconsole
00641         text = tkconsole.text
00642         text.tag_remove("ERROR", "1.0", "end")
00643         type, value, tb = sys.exc_info()
00644         msg = value.msg or "<no detail available>"
00645         lineno = value.lineno or 1
00646         offset = value.offset or 0
00647         if offset == 0:
00648             lineno += 1 #mark end of offending line
00649         if lineno == 1:
00650             pos = "iomark + %d chars" % (offset-1)
00651         else:
00652             pos = "iomark linestart + %d lines + %d chars" % \
00653                   (lineno-1, offset-1)
00654         tkconsole.colorize_syntax_error(text, pos)
00655         tkconsole.resetoutput()
00656         self.write("SyntaxError: %s\n" % msg)
00657         tkconsole.showprompt()

Here is the call graph for this function:

Display the exception that just occurred.

We remove the first stack item because it is our own code.

The output is written by self.write(), below.

Reimplemented from code.InteractiveInterpreter.

Definition at line 658 of file PyShell.py.

00658 
00659     def showtraceback(self):
00660         "Extend base class method to reset output properly"
00661         self.tkconsole.resetoutput()
00662         self.checklinecache()
00663         InteractiveInterpreter.showtraceback(self)
00664         if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
00665             self.tkconsole.open_stack_viewer()

Here is the call graph for this function:

Definition at line 345 of file PyShell.py.

00345 
00346     def spawn_subprocess(self):
00347         if self.subprocess_arglist is None:
00348             self.subprocess_arglist = self.build_subprocess_arglist()
00349         self.rpcsubproc = subprocess.Popen(self.subprocess_arglist)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 365 of file PyShell.py.

00365 
00366     def start_subprocess(self):
00367         addr = (HOST, self.port)
00368         # GUI makes several attempts to acquire socket, listens for connection
00369         for i in range(3):
00370             time.sleep(i)
00371             try:
00372                 self.rpcclt = MyRPCClient(addr)
00373                 break
00374             except socket.error as err:
00375                 pass
00376         else:
00377             self.display_port_binding_error()
00378             return None
00379         # if PORT was 0, system will assign an 'ephemeral' port. Find it out:
00380         self.port = self.rpcclt.listening_sock.getsockname()[1]
00381         # if PORT was not 0, probably working with a remote execution server
00382         if PORT != 0:
00383             # To allow reconnection within the 2MSL wait (cf. Stevens TCP
00384             # V1, 18.6),  set SO_REUSEADDR.  Note that this can be problematic
00385             # on Windows since the implementation allows two active sockets on
00386             # the same address!
00387             self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET,
00388                                            socket.SO_REUSEADDR, 1)
00389         self.spawn_subprocess()
00390         #time.sleep(20) # test to simulate GUI not accepting connection
00391         # Accept the connection from the Python execution server
00392         self.rpcclt.listening_sock.settimeout(10)
00393         try:
00394             self.rpcclt.accept()
00395         except socket.timeout as err:
00396             self.display_no_subprocess_error()
00397             return None
00398         self.rpcclt.register("stdin", self.tkconsole)
00399         self.rpcclt.register("stdout", self.tkconsole.stdout)
00400         self.rpcclt.register("stderr", self.tkconsole.stderr)
00401         self.rpcclt.register("flist", self.tkconsole.flist)
00402         self.rpcclt.register("linecache", linecache)
00403         self.rpcclt.register("interp", self)
00404         self.transfer_path()
00405         self.poll_subprocess()
00406         return self.rpcclt

Here is the call graph for this function:

Definition at line 612 of file PyShell.py.

00612 
00613     def stuffsource(self, source):
00614         "Stuff source in the filename cache"
00615         filename = "<pyshell#%d>" % self.gid
00616         self.gid = self.gid + 1
00617         lines = source.split("\n")
00618         linecache.cache[filename] = len(source)+1, 0, lines, filename
00619         return filename

Here is the caller graph for this function:

Definition at line 466 of file PyShell.py.

00466 
00467     def terminate_subprocess(self):
00468         "Make sure subprocess is terminated"
00469         try:
00470             self.rpcsubproc.kill()
00471         except OSError:
00472             # process already terminated
00473             return
00474         else:
00475             try:
00476                 self.rpcsubproc.wait()
00477             except OSError:
00478                 return

Here is the caller graph for this function:

Definition at line 479 of file PyShell.py.

00479 
00480     def transfer_path(self):
00481         self.runcommand("""if 1:
00482         import sys as _sys
00483         _sys.path = %r
00484         del _sys
00485         \n""" % (sys.path,))

Here is the call graph for this function:

Here is the caller graph for this function:

def idlelib.PyShell.ModifiedInterpreter.write (   self,
  data 
)
Write a string.

The base implementation writes to sys.stderr; a subclass may
replace this with a different implementation.

Reimplemented from code.InteractiveInterpreter.

Definition at line 733 of file PyShell.py.

00733 
00734     def write(self, s):
00735         "Override base class method"
00736         self.tkconsole.stderr.write(s)


Member Data Documentation

Definition at line 486 of file PyShell.py.

code.InteractiveInterpreter.compile [inherited]

Definition at line 36 of file code.py.

Definition at line 526 of file PyShell.py.

Definition at line 564 of file PyShell.py.

Definition at line 615 of file PyShell.py.

Definition at line 35 of file code.py.

Definition at line 590 of file PyShell.py.

Definition at line 340 of file PyShell.py.

Definition at line 338 of file PyShell.py.

Definition at line 342 of file PyShell.py.

Definition at line 343 of file PyShell.py.

Definition at line 337 of file PyShell.py.

Definition at line 339 of file PyShell.py.

Definition at line 334 of file PyShell.py.


The documentation for this class was generated from the following file: