summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1999-04-22 20:49:35 (GMT)
committerGuido van Rossum <guido@python.org>1999-04-22 20:49:35 (GMT)
commiteeb88076e7f4a89ce76d271379ca0aced0c2d6c7 (patch)
treeb999f4d5f33b92d5155b22ce3407f6ce699c7e3c
parentc4a623ebdc47a6da343837bf274070b5820933e4 (diff)
downloadcpython-eeb88076e7f4a89ce76d271379ca0aced0c2d6c7.zip
cpython-eeb88076e7f4a89ce76d271379ca0aced0c2d6c7.tar.gz
cpython-eeb88076e7f4a89ce76d271379ca0aced0c2d6c7.tar.bz2
A lot of changes to make the command line more useful. You can now do:
idle.py -e file ... -- to edit files idle.py script arg ... -- to run a script idle.py -c cmd arg ... -- to run a command Other options, see also the usage message (also new!) for more details: -d -- enable debugger -s -- run $IDLESTARTUP or $PYTHONSTARTUP -t title -- set Python Shell window's title sys.argv is set accordingly, unless -e is used. sys.path is absolutized, and all relevant paths are inserted into it. Other changes: - the environment in which commands are executed is now the __main__ module - explicitly save sys.stdout etc., don't restore from sys.__stdout__ - new interpreter methods execsource(), execfile(), stuffsource() - a few small nits
-rw-r--r--Tools/idle/PyShell.py141
1 files changed, 115 insertions, 26 deletions
diff --git a/Tools/idle/PyShell.py b/Tools/idle/PyShell.py
index f83ee0c..73def14 100644
--- a/Tools/idle/PyShell.py
+++ b/Tools/idle/PyShell.py
@@ -135,18 +135,41 @@ class ModifiedInterpreter(InteractiveInterpreter):
def __init__(self, tkconsole):
self.tkconsole = tkconsole
- InteractiveInterpreter.__init__(self)
+ locals = sys.modules['__main__'].__dict__
+ InteractiveInterpreter.__init__(self, locals=locals)
gid = 0
+ def execsource(self, source):
+ # Like runsource() but assumes complete exec source
+ filename = self.stuffsource(source)
+ self.execfile(filename, source)
+
+ def execfile(self, filename, source=None):
+ # Execute an existing file
+ if source is None:
+ source = open(filename, "r").read()
+ try:
+ code = compile(source, filename, "exec")
+ except (OverflowError, SyntaxError):
+ self.tkconsole.resetoutput()
+ InteractiveInterpreter.showsyntaxerror(self, filename)
+ else:
+ self.runcode(code)
+
def runsource(self, source):
- # Extend base class to stuff the source in the line cache
+ # Extend base class to stuff the source in the line cache first
+ filename = self.stuffsource(source)
+ self.more = 0
+ return InteractiveInterpreter.runsource(self, source, filename)
+
+ def stuffsource(self, source):
+ # Stuff source in the filename cache
filename = "<pyshell#%d>" % self.gid
self.gid = self.gid + 1
lines = string.split(source, "\n")
linecache.cache[filename] = len(source)+1, 0, lines, filename
- self.more = 0
- return InteractiveInterpreter.runsource(self, source, filename)
+ return filename
def showsyntaxerror(self, filename=None):
# Extend base class to color the offending position
@@ -166,14 +189,14 @@ class ModifiedInterpreter(InteractiveInterpreter):
text.tag_add("ERROR", pos)
text.see(pos)
char = text.get(pos)
- if char in string.letters + string.digits + "_":
+ if char and char in string.letters + string.digits + "_":
text.tag_add("ERROR", pos + " wordstart", pos)
self.tkconsole.resetoutput()
self.write("SyntaxError: %s\n" % str(msg))
def unpackerror(self):
type, value, tb = sys.exc_info()
- ok = type == SyntaxError
+ ok = type is SyntaxError
if ok:
try:
msg, (dummy_filename, lineno, offset, line) = value
@@ -241,6 +264,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
class PyShell(OutputWindow):
+ shell_title = "Python Shell"
+
# Override classes
ColorDelegator = ModifiedColorDelegator
@@ -279,6 +304,9 @@ class PyShell(OutputWindow):
text.bind("<<open-python-shell>>", self.flist.open_shell)
text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
+ self.save_stdout = sys.stdout
+ self.save_stderr = sys.stderr
+ self.save_stdin = sys.stdin
sys.stdout = PseudoFile(self, "stdout")
sys.stderr = PseudoFile(self, "stderr")
sys.stdin = self
@@ -304,10 +332,11 @@ class PyShell(OutputWindow):
self.close_debugger()
else:
self.open_debugger()
-
+
def set_debugger_indicator(self):
db = self.interp.getdebugger()
self.setvar("<<toggle-debugger>>", not not db)
+
def toggle_jit_stack_viewer( self, event=None):
pass # All we need is the variable
@@ -360,9 +389,9 @@ class PyShell(OutputWindow):
if reply != "cancel":
self.flist.pyshell = None
# Restore std streams
- sys.stdout = sys.__stdout__
- sys.stderr = sys.__stderr__
- sys.stdin = sys.__stdin__
+ sys.stdout = self.save_stdout
+ sys.stderr = self.save_stderr
+ sys.stdin = self.save_stdin
# Break cycles
self.interp = None
self.console = None
@@ -373,7 +402,7 @@ class PyShell(OutputWindow):
return 1
def short_title(self):
- return "Python Shell"
+ return self.shell_title
def begin(self):
self.resetoutput()
@@ -604,37 +633,97 @@ class PseudoFile:
pass
+usage_msg = """\
+usage: idle.py [-c command] [-d] [-e] [-s] [-t title] [arg] ...
+
+-c command run this command
+-d enable debugger
+-e edit mode; arguments are files to be edited
+-s run $PYTHONSTARTUP before anything else
+-t title set title of shell window
+
+When neither -c nor -e is used, and there are arguments, and the first
+argument is not '-', the first argument is run as a script. Remaining
+arguments are arguments to the script or to the command run by -c.
+"""
+
def main():
+ cmd = None
+ edit = 0
debug = 0
+ startup = 0
+
try:
- opts, args = getopt.getopt(sys.argv[1:], "d")
+ opts, args = getopt.getopt(sys.argv[1:], "c:deist:")
except getopt.error, msg:
sys.stderr.write("Error: %s\n" % str(msg))
+ sys.stderr.write(usage_msg)
sys.exit(2)
+
for o, a in opts:
- if o == "-d":
+ if o == '-c':
+ cmd = a
+ if o == '-d':
debug = 1
+ if o == '-e':
+ edit = 1
+ if o == '-s':
+ startup = 1
+ if o == '-t':
+ PyShell.shell_title = a
+
+ if not edit:
+ if cmd:
+ sys.argv = ["-c"] + args
+ else:
+ sys.argv = args or [""]
+
+ for i in range(len(sys.path)):
+ sys.path[i] = os.path.abspath(sys.path[i])
+
+ pathx = []
+ if edit:
+ for filename in args:
+ pathx.append(os.path.dirname(filename))
+ elif args and args[0] != "-":
+ pathx.append(os.path.dirname(args[0]))
+ else:
+ pathx.append(os.curdir)
+ for dir in pathx:
+ dir = os.path.abspath(dir)
+ if not dir in sys.path:
+ sys.path.insert(0, dir)
+
global flist, root
root = Tk()
fixwordbreaks(root)
root.withdraw()
flist = PyShellFileList(root)
- if args:
- for filename in sys.argv[1:]:
+
+ if edit:
+ for filename in args:
flist.open(filename)
- aPath = os.path.abspath(os.path.dirname(filename))
- if not aPath in sys.path:
- sys.path.insert(0, aPath)
- else:
- aPath = os.getcwd()
- if not aPath in sys.path:
- sys.path.insert(0, aPath)
- t = PyShell(flist)
- flist.pyshell = t
- t.begin()
+
+ shell = PyShell(flist)
+ interp = shell.interp
+ flist.pyshell = shell
+
+ if startup:
+ filename = os.environ.get("IDLESTARTUP") or \
+ os.environ.get("PYTHONSTARTUP")
+ if filename and os.path.isfile(filename):
+ interp.execfile(filename)
+
if debug:
- t.open_debugger()
+ shell.open_debugger()
+ if cmd:
+ interp.execsource(cmd)
+ elif not edit and args and args[0] != "-":
+ interp.execfile(args[0])
+
+ shell.begin()
root.mainloop()
+
if __name__ == "__main__":
main()