◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
203 changes: 136 additions & 67 deletions Lib/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
# Inspired by similar code by Jeff Epler and Fredrik Lundh.


import sys
import traceback
from codeop import CommandCompiler, compile_command

__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact",
"compile_command"]

class InteractiveInterpreter:
"""Base class for InteractiveConsole.

Expand All @@ -24,10 +26,10 @@ class InteractiveInterpreter:
def __init__(self, locals=None):
"""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.

"""
if locals is None:
Expand Down Expand Up @@ -63,7 +65,7 @@ def runsource(self, source, filename="<input>", symbol="single"):
code = self.compile(source, filename, symbol)
except (OverflowError, SyntaxError, ValueError):
# Case 1
self.showsyntaxerror(filename)
return False

if code is None:
Expand Down Expand Up @@ -93,7 +95,7 @@ def runcode(self, code):
except:
self.showtraceback()

def showsyntaxerror(self, filename=None):
"""Display the syntax error that just occurred.

This doesn't display a stack trace because there isn't one.
Expand All @@ -105,29 +107,14 @@ def showsyntaxerror(self, filename=None):
The output is written by self.write(), below.

"""
type, value, tb = sys.exc_info()
sys.last_exc = value
sys.last_type = type
sys.last_value = value
sys.last_traceback = tb
if filename and type is SyntaxError:
# Work hard to stuff the correct filename in the exception
try:
msg, (dummy_filename, lineno, offset, line) = value.args
except ValueError:
# Not the format we expect; leave it alone
pass
else:
# Stuff in the right filename
value = SyntaxError(msg, (filename, lineno, offset, line))
sys.last_exc = sys.last_value = value
if sys.excepthook is sys.__excepthook__:
lines = traceback.format_exception_only(type, value)
self.write(''.join(lines))
else:
# If someone has set sys.excepthook, we let that take precedence
# over self.write
sys.excepthook(type, value, tb)

def showtraceback(self):
"""Display the exception that just occurred.
Expand All @@ -137,19 +124,46 @@ def showtraceback(self):
The output is written by self.write(), below.

"""
sys.last_type, sys.last_value, last_tb = ei = sys.exc_info()
sys.last_traceback = last_tb
sys.last_exc = ei[1]
try:
lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next)
if sys.excepthook is sys.__excepthook__:
self.write(''.join(lines))
else:
# If someone has set sys.excepthook, we let that take precedence
# over self.write
sys.excepthook(ei[0], ei[1], last_tb)
finally:
last_tb = ei = None

def write(self, data):
"""Write a string.
Expand All @@ -169,7 +183,7 @@ class InteractiveConsole(InteractiveInterpreter):

"""

def __init__(self, locals=None, filename="<console>"):
"""Constructor.

The optional locals argument will be passed to the
Expand All @@ -181,6 +195,7 @@ def __init__(self, locals=None, filename="<console>"):
"""
InteractiveInterpreter.__init__(self, locals)
self.filename = filename
self.resetbuffer()

def resetbuffer(self):
Expand Down Expand Up @@ -219,29 +234,66 @@ def interact(self, banner=None, exitmsg=None):
elif banner:
self.write("%s\n" % str(banner))
more = 0
while 1:
try:
if more:
prompt = sys.ps2
else:
prompt = sys.ps1
try:
line = self.raw_input(prompt)
except EOFError:
self.write("\n")
break
else:
more = self.push(line)
except KeyboardInterrupt:
self.write("\nKeyboardInterrupt\n")
self.resetbuffer()
more = 0
if exitmsg is None:
self.write('now exiting %s...\n' % self.__class__.__name__)
elif exitmsg != '':
self.write('%s\n' % exitmsg)

def push(self, line):
"""Push a line to the interpreter.

The line should not have a trailing newline; it may have
Expand All @@ -257,7 +309,9 @@ def push(self, line):
"""
self.buffer.append(line)
source = "\n".join(self.buffer)
more = self.runsource(source, self.filename)
if not more:
self.resetbuffer()
return more
Expand All @@ -276,8 +330,22 @@ def raw_input(self, prompt=""):
return input(prompt)



def interact(banner=None, readfunc=None, local=None, exitmsg=None):
"""Closely emulate the interactive Python interpreter.

This is a backwards compatible interface to the InteractiveConsole
Expand All @@ -290,9 +358,10 @@ def interact(banner=None, readfunc=None, local=None, exitmsg=None):
readfunc -- if not None, replaces InteractiveConsole.raw_input()
local -- passed to InteractiveInterpreter.__init__()
exitmsg -- passed to InteractiveConsole.interact()

"""
console = InteractiveConsole(local)
if readfunc is not None:
console.raw_input = readfunc
else:
@@ -308,7 +377,7 @@ def interact(banner=None, readfunc=None, local=None, exitmsg=None):

parser = argparse.ArgumentParser()
parser.add_argument('-q', action='store_true',
help="don't print version and copyright messages")
args = parser.parse_args()
if args.q or sys.flags.quiet:
banner = ''
Loading
Loading
Toggle all file notes Toggle all file annotations