Index: third_party/twisted_8_1/twisted/conch/manhole.py |
diff --git a/third_party/twisted_8_1/twisted/conch/manhole.py b/third_party/twisted_8_1/twisted/conch/manhole.py |
deleted file mode 100644 |
index 50c52d5da6ead73d2652991ba62929a867981e9b..0000000000000000000000000000000000000000 |
--- a/third_party/twisted_8_1/twisted/conch/manhole.py |
+++ /dev/null |
@@ -1,336 +0,0 @@ |
-# -*- test-case-name: twisted.conch.test.test_manhole -*- |
-# Copyright (c) 2001-2007 Twisted Matrix Laboratories. |
-# See LICENSE for details. |
- |
-""" |
-Line-input oriented interactive interpreter loop. |
- |
-Provides classes for handling Python source input and arbitrary output |
-interactively from a Twisted application. Also included is syntax coloring |
-code with support for VT102 terminals, control code handling (^C, ^D, ^Q), |
-and reasonable handling of Deferreds. |
- |
-@author: U{Jp Calderone<mailto:exarkun@twistedmatrix.com>} |
-""" |
- |
-import code, sys, StringIO, tokenize |
- |
-from twisted.conch import recvline |
- |
-from twisted.internet import defer |
-from twisted.python.htmlizer import TokenPrinter |
- |
-class FileWrapper: |
- """Minimal write-file-like object. |
- |
- Writes are translated into addOutput calls on an object passed to |
- __init__. Newlines are also converted from network to local style. |
- """ |
- |
- softspace = 0 |
- state = 'normal' |
- |
- def __init__(self, o): |
- self.o = o |
- |
- def flush(self): |
- pass |
- |
- def write(self, data): |
- self.o.addOutput(data.replace('\r\n', '\n')) |
- |
- def writelines(self, lines): |
- self.write(''.join(lines)) |
- |
-class ManholeInterpreter(code.InteractiveInterpreter): |
- """Interactive Interpreter with special output and Deferred support. |
- |
- Aside from the features provided by L{code.InteractiveInterpreter}, this |
- class captures sys.stdout output and redirects it to the appropriate |
- location (the Manhole protocol instance). It also treats Deferreds |
- which reach the top-level specially: each is formatted to the user with |
- a unique identifier and a new callback and errback added to it, each of |
- which will format the unique identifier and the result with which the |
- Deferred fires and then pass it on to the next participant in the |
- callback chain. |
- """ |
- |
- numDeferreds = 0 |
- def __init__(self, handler, locals=None, filename="<console>"): |
- code.InteractiveInterpreter.__init__(self, locals) |
- self._pendingDeferreds = {} |
- self.handler = handler |
- self.filename = filename |
- self.resetBuffer() |
- |
- def resetBuffer(self): |
- """Reset the input buffer.""" |
- self.buffer = [] |
- |
- def push(self, line): |
- """Push a line to the interpreter. |
- |
- The line should not have a trailing newline; it may have |
- internal newlines. The line is appended to a buffer and the |
- interpreter's runsource() method is called with the |
- concatenated contents of the buffer as source. If this |
- indicates that the command was executed or invalid, the buffer |
- is reset; otherwise, the command is incomplete, and the buffer |
- is left as it was after the line was appended. The return |
- value is 1 if more input is required, 0 if the line was dealt |
- with in some way (this is the same as runsource()). |
- |
- """ |
- self.buffer.append(line) |
- source = "\n".join(self.buffer) |
- more = self.runsource(source, self.filename) |
- if not more: |
- self.resetBuffer() |
- return more |
- |
- def runcode(self, *a, **kw): |
- orighook, sys.displayhook = sys.displayhook, self.displayhook |
- try: |
- origout, sys.stdout = sys.stdout, FileWrapper(self.handler) |
- try: |
- code.InteractiveInterpreter.runcode(self, *a, **kw) |
- finally: |
- sys.stdout = origout |
- finally: |
- sys.displayhook = orighook |
- |
- def displayhook(self, obj): |
- self.locals['_'] = obj |
- if isinstance(obj, defer.Deferred): |
- # XXX Ick, where is my "hasFired()" interface? |
- if hasattr(obj, "result"): |
- self.write(repr(obj)) |
- elif id(obj) in self._pendingDeferreds: |
- self.write("<Deferred #%d>" % (self._pendingDeferreds[id(obj)][0],)) |
- else: |
- d = self._pendingDeferreds |
- k = self.numDeferreds |
- d[id(obj)] = (k, obj) |
- self.numDeferreds += 1 |
- obj.addCallbacks(self._cbDisplayDeferred, self._ebDisplayDeferred, |
- callbackArgs=(k, obj), errbackArgs=(k, obj)) |
- self.write("<Deferred #%d>" % (k,)) |
- elif obj is not None: |
- self.write(repr(obj)) |
- |
- def _cbDisplayDeferred(self, result, k, obj): |
- self.write("Deferred #%d called back: %r" % (k, result), True) |
- del self._pendingDeferreds[id(obj)] |
- return result |
- |
- def _ebDisplayDeferred(self, failure, k, obj): |
- self.write("Deferred #%d failed: %r" % (k, failure.getErrorMessage()), True) |
- del self._pendingDeferreds[id(obj)] |
- return failure |
- |
- def write(self, data, async=False): |
- self.handler.addOutput(data, async) |
- |
-CTRL_C = '\x03' |
-CTRL_D = '\x04' |
-CTRL_BACKSLASH = '\x1c' |
-CTRL_L = '\x0c' |
- |
-class Manhole(recvline.HistoricRecvLine): |
- """Mediator between a fancy line source and an interactive interpreter. |
- |
- This accepts lines from its transport and passes them on to a |
- L{ManholeInterpreter}. Control commands (^C, ^D, ^\) are also handled |
- with something approximating their normal terminal-mode behavior. It |
- can optionally be constructed with a dict which will be used as the |
- local namespace for any code executed. |
- """ |
- |
- namespace = None |
- |
- def __init__(self, namespace=None): |
- recvline.HistoricRecvLine.__init__(self) |
- if namespace is not None: |
- self.namespace = namespace.copy() |
- |
- def connectionMade(self): |
- recvline.HistoricRecvLine.connectionMade(self) |
- self.interpreter = ManholeInterpreter(self, self.namespace) |
- self.keyHandlers[CTRL_C] = self.handle_INT |
- self.keyHandlers[CTRL_D] = self.handle_EOF |
- self.keyHandlers[CTRL_L] = self.handle_FF |
- self.keyHandlers[CTRL_BACKSLASH] = self.handle_QUIT |
- |
- |
- def handle_INT(self): |
- """ |
- Handle ^C as an interrupt keystroke by resetting the current input |
- variables to their initial state. |
- """ |
- self.pn = 0 |
- self.lineBuffer = [] |
- self.lineBufferIndex = 0 |
- self.interpreter.resetBuffer() |
- |
- self.terminal.nextLine() |
- self.terminal.write("KeyboardInterrupt") |
- self.terminal.nextLine() |
- self.terminal.write(self.ps[self.pn]) |
- |
- |
- def handle_EOF(self): |
- if self.lineBuffer: |
- self.terminal.write('\a') |
- else: |
- self.handle_QUIT() |
- |
- |
- def handle_FF(self): |
- """ |
- Handle a 'form feed' byte - generally used to request a screen |
- refresh/redraw. |
- """ |
- self.terminal.eraseDisplay() |
- self.terminal.cursorHome() |
- self.drawInputLine() |
- |
- |
- def handle_QUIT(self): |
- self.terminal.loseConnection() |
- |
- |
- def _needsNewline(self): |
- w = self.terminal.lastWrite |
- return not w.endswith('\n') and not w.endswith('\x1bE') |
- |
- def addOutput(self, bytes, async=False): |
- if async: |
- self.terminal.eraseLine() |
- self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn])) |
- |
- self.terminal.write(bytes) |
- |
- if async: |
- if self._needsNewline(): |
- self.terminal.nextLine() |
- |
- self.terminal.write(self.ps[self.pn]) |
- |
- if self.lineBuffer: |
- oldBuffer = self.lineBuffer |
- self.lineBuffer = [] |
- self.lineBufferIndex = 0 |
- |
- self._deliverBuffer(oldBuffer) |
- |
- def lineReceived(self, line): |
- more = self.interpreter.push(line) |
- self.pn = bool(more) |
- if self._needsNewline(): |
- self.terminal.nextLine() |
- self.terminal.write(self.ps[self.pn]) |
- |
-class VT102Writer: |
- """Colorizer for Python tokens. |
- |
- A series of tokens are written to instances of this object. Each is |
- colored in a particular way. The final line of the result of this is |
- generally added to the output. |
- """ |
- |
- typeToColor = { |
- 'identifier': '\x1b[31m', |
- 'keyword': '\x1b[32m', |
- 'parameter': '\x1b[33m', |
- 'variable': '\x1b[1;33m', |
- 'string': '\x1b[35m', |
- 'number': '\x1b[36m', |
- 'op': '\x1b[37m'} |
- |
- normalColor = '\x1b[0m' |
- |
- def __init__(self): |
- self.written = [] |
- |
- def color(self, type): |
- r = self.typeToColor.get(type, '') |
- return r |
- |
- def write(self, token, type=None): |
- if token and token != '\r': |
- c = self.color(type) |
- if c: |
- self.written.append(c) |
- self.written.append(token) |
- if c: |
- self.written.append(self.normalColor) |
- |
- def __str__(self): |
- s = ''.join(self.written) |
- return s.strip('\n').splitlines()[-1] |
- |
-def lastColorizedLine(source): |
- """Tokenize and colorize the given Python source. |
- |
- Returns a VT102-format colorized version of the last line of C{source}. |
- """ |
- w = VT102Writer() |
- p = TokenPrinter(w.write).printtoken |
- s = StringIO.StringIO(source) |
- |
- tokenize.tokenize(s.readline, p) |
- |
- return str(w) |
- |
-class ColoredManhole(Manhole): |
- """A REPL which syntax colors input as users type it. |
- """ |
- |
- def getSource(self): |
- """Return a string containing the currently entered source. |
- |
- This is only the code which will be considered for execution |
- next. |
- """ |
- return ('\n'.join(self.interpreter.buffer) + |
- '\n' + |
- ''.join(self.lineBuffer)) |
- |
- |
- def characterReceived(self, ch, moreCharactersComing): |
- if self.mode == 'insert': |
- self.lineBuffer.insert(self.lineBufferIndex, ch) |
- else: |
- self.lineBuffer[self.lineBufferIndex:self.lineBufferIndex+1] = [ch] |
- self.lineBufferIndex += 1 |
- |
- if moreCharactersComing: |
- # Skip it all, we'll get called with another character in |
- # like 2 femtoseconds. |
- return |
- |
- if ch == ' ': |
- # Don't bother to try to color whitespace |
- self.terminal.write(ch) |
- return |
- |
- source = self.getSource() |
- |
- # Try to write some junk |
- try: |
- coloredLine = lastColorizedLine(source) |
- except tokenize.TokenError: |
- # We couldn't do it. Strange. Oh well, just add the character. |
- self.terminal.write(ch) |
- else: |
- # Success! Clear the source on this line. |
- self.terminal.eraseLine() |
- self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn]) - 1) |
- |
- # And write a new, colorized one. |
- self.terminal.write(self.ps[self.pn] + coloredLine) |
- |
- # And move the cursor to where it belongs |
- n = len(self.lineBuffer) - self.lineBufferIndex |
- if n: |
- self.terminal.cursorBackward(n) |