Last active
July 21, 2025 21:06
-
-
Save rduplain/899f6a5e583a85668822 to your computer and use it in GitHub Desktop.
Revisions
-
rduplain revised this gist
Jul 15, 2014 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -94,6 +94,7 @@ Selected real-world use cases of `code.InteractiveConsole`: 1. interactive step interpreter for [Cucumber-style][7] steps, with [behave][8] 2. send bytes interactively to test a network protocol driver 3. command REPL for an instrument controller [1]: https://docs.python.org/3.4/library/code.html -
rduplain revised this gist
Jul 15, 2014 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,10 +1,10 @@ ### `import code` This is a demonstration of the Python [code][1] module, which allows for an interactive interpreter to be embedded into a Python program. ##### `code.interact(banner=None, readfunc=None, local=None)` Convenience function to run a read-eval-print loop. This creates a new instance of [`InteractiveConsole`][2] and sets readfunc to be used as the @@ -15,7 +15,7 @@ instance is then run with banner passed as the banner to use, if provided. The console object is discarded after use. ##### python interact.py `code.interact` is useful for: @@ -37,14 +37,14 @@ Example: $ ##### `class code.InteractiveConsole(locals=None, filename="<console>")` Closely emulate the behavior of the interactive Python interpreter. This class builds on [`InteractiveInterpreter`][6] and adds prompting using the familiar `sys.ps1` and `sys.ps2`, and input buffering. ##### python console.py `code.InteractiveConsole` is useful when you want to customize the REPL: -
rduplain created this gist
Jul 15, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,106 @@ ## `import code` This is a demonstration of the Python [code][1] module, which allows for an interactive interpreter to be embedded into a Python program. ### `code.interact(banner=None, readfunc=None, local=None)` Convenience function to run a read-eval-print loop. This creates a new instance of [`InteractiveConsole`][2] and sets readfunc to be used as the [`InteractiveConsole.raw_input()`][3] method, if provided. If local is provided, it is passed to the [`InteractiveConsole`][2] constructor for use as the default namespace for the interpreter loop. The interact() method of the instance is then run with banner passed as the banner to use, if provided. The console object is discarded after use. ### python interact.py `code.interact` is useful for: 1. Pre-loading `python` interactive interpreter. ([flask-script][4] does this.) 2. Embedding an interactive interpreter in a program, with an *internal* DSL. 3. Quick interactive debugging (you probably want [`pdb.set_trace()`][5]). Example: $ python interact.py >>> foo 'this is foo' >>> bar 'this is bar' >>> 6 * 7 42 >>> $ ### `class code.InteractiveConsole(locals=None, filename="<console>")` Closely emulate the behavior of the interactive Python interpreter. This class builds on [`InteractiveInterpreter`][6] and adds prompting using the familiar `sys.ps1` and `sys.ps2`, and input buffering. ### python console.py `code.InteractiveConsole` is useful when you want to customize the REPL: 1. Changing the REPL behavior of the `python` interactive interpreter. 2. Embedding an interactive interpreter in a program, with an *external* DSL. 3. Provide a scripting interface for an external DSL. Example: $ python console.py > room No one is in the room. > enter John Mary Joseph John enters the room. Mary enters the room. Joseph enters the room. > exit Joseph Joseph leaves the room. > room In the room: John, Mary > $ Non-interactive usage: $ echo 'room' | python console.py No one is in the room. $ Non-interactive scripting (could update code to take files on sys.argv): python console.py <<EOF enter John Mary Joseph exit Joseph room EOF ... produces output: John enters the room. Mary enters the room. Joseph enters the room. Joseph leaves the room. In the room: John, Mary Selected real-world use cases of `code.InteractiveConsole`: 1. interactive step interpreter for [Cucumber-style][7] steps, with [behave][8] 2. send bytes interactively to test a network protocol driver [1]: https://docs.python.org/3.4/library/code.html [2]: https://docs.python.org/3.4/library/code.html#code.InteractiveConsole [3]: https://docs.python.org/3.4/library/code.html#code.InteractiveConsole.raw_input [4]: http://flask-script.readthedocs.org/ [5]: https://docs.python.org/3.4/library/pdb.html [6]: https://docs.python.org/3.4/library/code.html#code.InteractiveInterpreter [7]: http://cukes.info/ [8]: http://pythonhosted.org/behave/ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,117 @@ import code import shlex import sys from sys import stderr class CommandRunner(object): "Simple demo." def __init__(self): self.commands = {} def command(self, name, fn): self.commands[name] = fn def run(self, line): tokens = shlex.split(line, comments=True) command, args = tokens[0], tokens[1:] if command not in self.commands: print('{}: no such command'.format(command), file=stderr) return result = self.commands[command](*args) if result is not None: print(result) class Console(object): ps1 = '> ' ps2 = '. ' def __init__(self, runner): self.runner = runner def run(self, fd): for line in fd: self.runner.run(line) def interact(self, locals=None): class LambdaConsole(code.InteractiveConsole): def runsource(code_console, source, filename=None, symbol=None): # Return True if more input needed, else False. try: self.runner.run(source) except SystemExit: raise except: code_console.showtraceback() return False # import readline to support line editing within console session. try: import readline; readline except ImportError: pass # Patch ps1 & ps2 for interaction. Note sys.psX may be unset. ps1, ps2 = getattr(sys, 'ps1', None), getattr(sys, 'ps2', None) try: sys.ps1, sys.ps2 = self.ps1, self.ps2 LambdaConsole(locals=locals, filename="<demo>").interact(banner='') finally: sys.ps1, sys.ps2 = ps1, ps2 def run_in_main(self, fd=None, interact=False): if fd is None: fd = sys.stdin if fd.isatty(): self.interact() else: try: self.run(fd=fd) except Exception as err: print(err, file=stderr) return 1 return 0 class Room(object): "Simple demo." def __init__(self): self.people = set() def enter(self, *people): for person in people: if person in self.people: print('{} is already in the room.'.format(person), file=stderr) else: print('{} enters the room.'.format(person)) self.people.add(person) def exit(self, *people): for person in people: if person in self.people: print('{} leaves the room.'.format(person)) self.people.remove(person) else: print('{} is not in the room.'.format(person), file=stderr) def room(self): if self.people: print('In the room: {}'.format(', '.join(self.people))) else: print('No one is in the room.') def main(fd=None): room = Room() runner = CommandRunner() runner.command('enter', room.enter) runner.command('exit', room.exit) runner.command('room', room.room) return Console(runner).run_in_main(fd) if __name__ == '__main__': sys.exit(main()) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,11 @@ import code def interact(): foo = 'this is foo' bar = 'this is bar' code.interact(banner='', local=locals()) if __name__ == '__main__': interact()