Source code for cli_demo.sandbox

# -*- coding: utf-8 -*-

"""This module contains SandboxDemo, a CodeDemo subclass that provides a shell for experimenting with the functions used in code commands."""

# For py2.7 compatibility
from __future__ import print_function
import sys
if sys.version_info < (3,3):
    input = raw_input

from .code import CodeDemo


[docs]class SandboxDemo(CodeDemo): """SandboxDemo extends CodeDemo by providing :meth:`~cli_demo.sandbox.SandboxDemo.sandbox`, a Python shell in which users can experiment with the context that has been set up.""" help_text = """SandboxDemo extends CodeDemo by providing a shell in which users can experiment with the context that has been set up.""" options = CodeDemo.options.copy()
[docs] @options("c", "o", "s", "r", "q", key="commands") def get_commands(self): """Prompt the user to select a command from :attr:`~cli_demo.code.CodeDemo.commands`. Note: * :meth:`~cli_demo.sandbox.SandboxDemo.get_commands` is decorated with:: @options("c", "o", "s", "r", "q", key="commands") def get_commands(self): ... For more information, refer to :meth:`options <cli_demo.options.DemoOptions.__call__>`. * ``"s"``, for :meth:`"Sandbox mode." <cli_demo.sandbox.SandboxDemo.sandbox>`, has been added to the available options. """ return input(self.command_prompt)
[docs] @options.register("s", "Sandbox mode.", retry=True, lock=True) def sandbox(self, key): """Set up an interactive shell to experiment with. Prompt the user for input, :meth:`~cli_demo.code.CodeDemo.execute` the entered command or code block, and then repeat. If the input is ``"quit()"``, print the previous options using :meth:`~cli_demo.demo.Demo.print_options` and return. Args: key (str): The key of the input function which triggered sandbox mode. Note: :meth:`~cli_demo.sandbox.SandboxDemo.sandbox` is decorated with:: @options.register("s", "Sandbox mode.", retry=True, lock=True) def sandbox(self, key): ... For more information, refer to :meth:`options.register <cli_demo.options.DemoOptions.register>`. """ print("Switched to sandbox mode.") print("Use quit() to leave sandbox mode.") print() while True: nestings = [] keywords = ["def", "class", "for", "while"] nested_list = 0 nested_tuple = 0 nested_dict = 0 prefix = ">>> " command = [input(prefix).expandtabs(4)] i = 0 if command[i] == "quit()": break while True: decorating = command[i].lstrip().startswith("@") newline = command[i].rstrip().endswith("\\") while True: expected_ws = len(nestings) * " " if command[i].startswith(expected_ws): for keyword in keywords: if command[i].lstrip().startswith(keyword): nestings.append(keyword) break break elif nestings: nestings.pop() else: break nested_tuple += command[i].count("(") if nested_tuple: nested_tuple -= command[i].count(")") nested_list += command[i].count("[") if nested_list: nested_list -= command[i].count("]") nested_dict += command[i].count("{") if nested_dict: nested_dict - command[i].count("}") nested = (nestings or nested_tuple or nested_list or nested_dict) if nested or newline: prefix = "... " elif decorating: prefix = ">>> " next_line = ( (newline or decorating or nested) and input(prefix).expandtabs(4)) if not next_line: break elif newline: command[i] = command[i][:-1] + next_line else: command.append(next_line) i += 1 if any(command): self.execute(["\n".join(command)], print_in=False) print("Leaving sandbox mode.") print() self.print_options(key=key)