Пример #1
0
    def setUp(self):
        self.filename = 'history_temp_file'
        self.encoding = getpreferredencoding()

        with io.open(self.filename, 'w', encoding=self.encoding,
                     errors='ignore') as f:
            f.write(b'#1\n#2\n'.decode())
    def __init__(self, locals=None, encoding=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.

        We include an argument for the outfile to pass to the formatter for it
        to write to.
        """
        if locals is None:
            locals = {"__name__": "__console__", "__doc__": None}
        if encoding is None:
            encoding = getpreferredencoding()
        ReplInterpreter.__init__(self, locals, encoding)

        self.locals = locals
        self.compile = CommandCompiler()

        # typically changed after being instantiated
        # but used when interpreter used corresponding REPL
        def write(err_line):
            """Default stderr handler for tracebacks

            Accepts FmtStrs so interpreters can output them"""
            sys.stderr.write(text_type(err_line))

        self.write = write
        self.outfile = self
Пример #3
0
    def setUp(self):
        self.filename = "history_temp_file"
        self.encoding = getpreferredencoding()

        with open(self.filename, "w", encoding=self.encoding,
                  errors="ignore") as f:
            f.write(b"#1\n#2\n".decode())
Пример #4
0
def run_with_tty(command):
    # based on https://stackoverflow.com/questions/52954248/capture-output-as-a-tty-in-python
    master_stdout, slave_stdout = pty.openpty()
    master_stderr, slave_stderr = pty.openpty()
    master_stdin, slave_stdin = pty.openpty()

    p = subprocess.Popen(
        command,
        stdout=slave_stdout,
        stderr=slave_stderr,
        stdin=slave_stdin,
        close_fds=True,
    )
    for fd in (slave_stdout, slave_stderr, slave_stdin):
        os.close(fd)

    readable = [master_stdout, master_stderr]
    result = {master_stdout: b"", master_stderr: b""}
    try:
        while readable:
            ready, _, _ = select.select(readable, [], [], 1)
            for fd in ready:
                try:
                    data = os.read(fd, 512)
                except OSError as e:
                    if e.errno != errno.EIO:
                        raise
                    # EIO means EOF on some systems
                    readable.remove(fd)
                else:
                    if not data:  # EOF
                        readable.remove(fd)
                    result[fd] += data
    finally:
        for fd in (master_stdout, master_stderr, master_stdin):
            os.close(fd)
        if p.poll() is None:
            p.kill()
        p.wait()

    if p.returncode:
        raise RuntimeError(f"Subprocess exited with {p.returncode}")

    return (
        result[master_stdout].decode(getpreferredencoding()),
        result[master_stderr].decode(getpreferredencoding()),
    )
Пример #5
0
 def ps1(self):
     try:
         if not py3:
             return sys.ps1.decode(getpreferredencoding())
         else:
             return sys.ps1
     except AttributeError:
         return u'>>> '
Пример #6
0
 def open_in_external_editor(self, filename):
     encoding = getpreferredencoding()
     editor_args = shlex.split(prepare_for_exec(self.config.editor,
                                                encoding))
     args = editor_args + [prepare_for_exec(filename, encoding)]
     if subprocess.call(args) == 0:
         return True
     return False
Пример #7
0
 def ps1(self):
     try:
         if not py3:
             return sys.ps1.decode(getpreferredencoding())
         else:
             return sys.ps1
     except AttributeError:
         return u'>>> '
Пример #8
0
    def __init__(self, interp, config):
        """Initialise the repl.

        interp is a Python code.InteractiveInterpreter instance

        config is a populated bpython.config.Struct.
        """

        self.config = config
        self.cut_buffer = ''
        self.buffer = []
        self.interp = interp
        self.interp.syntaxerror_callback = self.clear_current_line
        self.match = False
        self.rl_history = History(duplicates=config.hist_duplicates,
                                  hist_size=config.hist_length)
        self.s_hist = []
        self.history = []
        self.evaluating = False
        self.matches_iter = MatchesIterator()
        self.funcprops = None
        self.arg_pos = None
        self.current_func = None
        self.highlighted_paren = None
        self._C = {}
        self.prev_block_finished = 0
        self.interact = Interaction(self.config)
        # previous pastebin content to prevent duplicate pastes, filled on call
        # to repl.pastebin
        self.prev_pastebin_content = ''
        self.prev_pastebin_url = ''
        self.prev_removal_url = ''
        # Necessary to fix mercurial.ui.ui expecting sys.stderr to have this
        # attribute
        self.closed = False
        self.clipboard = get_clipboard()

        pythonhist = os.path.expanduser(self.config.hist_file)
        if os.path.exists(pythonhist):
            try:
                self.rl_history.load(pythonhist,
                                     getpreferredencoding() or "ascii")
            except EnvironmentError:
                pass

        self.completers = autocomplete.get_default_completer(
            config.autocomplete_mode)
        if self.config.pastebin_helper:
            self.paster = PasteHelper(self.config.pastebin_helper)
        else:
            self.paster = PastePinnwand(self.config.pastebin_url,
                                        self.config.pastebin_expiry,
                                        self.config.pastebin_show_url,
                                        self.config.pastebin_removal_url)
Пример #9
0
    def __init__(self, interp, config):
        """Initialise the repl.

        interp is a Python code.InteractiveInterpreter instance

        config is a populated bpython.config.Struct.
        """

        self.config = config
        self.cut_buffer = ''
        self.buffer = []
        self.interp = interp
        self.interp.syntaxerror_callback = self.clear_current_line
        self.match = False
        self.rl_history = History(duplicates=config.hist_duplicates,
                                  hist_size=config.hist_length)
        self.s_hist = []
        self.history = []
        self.evaluating = False
        self.matches_iter = MatchesIterator()
        self.funcprops = None
        self.arg_pos = None
        self.current_func = None
        self.highlighted_paren = None
        self._C = {}
        self.prev_block_finished = 0
        self.interact = Interaction(self.config)
        # previous pastebin content to prevent duplicate pastes, filled on call
        # to repl.pastebin
        self.prev_pastebin_content = ''
        self.prev_pastebin_url = ''
        self.prev_removal_url = ''
        # Necessary to fix mercurial.ui.ui expecting sys.stderr to have this
        # attribute
        self.closed = False
        self.clipboard = get_clipboard()

        pythonhist = os.path.expanduser(self.config.hist_file)
        if os.path.exists(pythonhist):
            try:
                self.rl_history.load(pythonhist,
                                     getpreferredencoding() or "ascii")
            except EnvironmentError:
                pass

        self.completers = autocomplete.get_default_completer(
            config.autocomplete_mode)
        if self.config.pastebin_helper:
            self.paster = PasteHelper(self.config.pastebin_helper)
        else:
            self.paster = PastePinnwand(self.config.pastebin_url,
                                        self.config.pastebin_expiry,
                                        self.config.pastebin_show_url,
                                        self.config.pastebin_removal_url)
Пример #10
0
    def send_to_external_editor(self, text, filename=None):
        """Returns modified text from an editor, or the oriignal text if editor
        exited with non-zero"""

        encoding = getpreferredencoding()
        editor_args = shlex.split(prepare_for_exec(self.config.editor,
                                                   encoding))
        with tempfile.NamedTemporaryFile(suffix='.py') as temp:
            temp.write(text.encode(encoding))
            temp.flush()

            args = editor_args + [prepare_for_exec(temp.name, encoding)]
            if subprocess.call(args) == 0:
                with open(temp.name) as f:
                    if py3:
                        return f.read()
                    else:
                        return f.read().decode(encoding)
            else:
                return text
Пример #11
0
    def send_to_external_editor(self, text, filename=None):
        """Returns modified text from an editor, or the oriignal text if editor
        exited with non-zero"""

        encoding = getpreferredencoding()
        editor_args = shlex.split(prepare_for_exec(self.config.editor,
                                                   encoding))
        with tempfile.NamedTemporaryFile(suffix='.py') as temp:
            temp.write(text.encode(encoding))
            temp.flush()

            args = editor_args + [prepare_for_exec(temp.name, encoding)]
            if subprocess.call(args) == 0:
                with open(temp.name) as f:
                    if py3:
                        return f.read()
                    else:
                        return f.read().decode(encoding)
            else:
                return text
Пример #12
0
    def __init__(self, locals=None, encoding=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.

        We include an argument for the outfile to pass to the formatter for it
        to write to.
        """
        if locals is None:
            locals = {"__name__": "__console__", "__doc__": None}
        if encoding is None:
            encoding = getpreferredencoding()
        ReplInterpreter.__init__(self, locals, encoding)

        self.locals = locals
        self.compile = CommandCompiler()

        # typically changed after being instantiated
        self.write = lambda stuff: sys.stderr.write(stuff)
        self.outfile = self
Пример #13
0
    def run_bpython(self, input):
        """
        Run bpython (with `backend` as backend) in a subprocess and
        enter the given input. Uses a test config that disables the
        paste detection.

        Returns bpython's output.
        """
        result = Deferred()
        encoding = getpreferredencoding()

        class Protocol(ProcessProtocol):
            STATES = (SEND_INPUT, COLLECT) = range(2)

            def __init__(self):
                self.data = ""
                self.delayed_call = None
                self.states = iter(self.STATES)
                self.state = next(self.states)

            def outReceived(self, data):
                self.data += data.decode(encoding)
                if self.delayed_call is not None:
                    self.delayed_call.cancel()
                self.delayed_call = reactor.callLater(0.5, self.next)

            def next(self):
                self.delayed_call = None
                if self.state == self.SEND_INPUT:
                    index = self.data.find(">>> ")
                    if index >= 0:
                        self.data = self.data[index + 4:]
                        self.transport.write(input.encode(encoding))
                        self.state = next(self.states)
                    elif self.data == "\x1b[6n":
                        # this is a cursor position query
                        # respond that cursor is on row 2, column 1
                        self.transport.write("\x1b[2;1R".encode(encoding))
                else:
                    self.transport.closeStdin()
                    if self.transport.pid is not None:
                        self.delayed_call = None
                        self.transport.signalProcess("TERM")

            def processExited(self, reason):
                if self.delayed_call is not None:
                    self.delayed_call.cancel()
                result.callback(self.data)

        (master, slave) = pty.openpty()
        set_win_size(slave, 25, 80)
        reactor.spawnProcess(
            Protocol(),
            sys.executable,
            (
                sys.executable,
                "-m",
                f"bpython.{self.backend}",
                "--config",
                str(TEST_CONFIG),
                "-q",  # prevents version greeting
            ),
            env={
                "TERM": "vt100",
                "LANG": os.environ.get("LANG", "C.UTF-8"),
            },
            usePTY=(master, slave, os.ttyname(slave)),
        )
        return result
Пример #14
0
 def write(self, s, *args, **kwargs):
     if not py3 and isinstance(s, str):
         s = s.decode(getpreferredencoding(), 'ignore')
     self.on_write(s, *args, **kwargs)
     return self.coderunner.request_from_main_greenlet(force_refresh=True)
Пример #15
0
 def insert_into_history(self, s):
     try:
         self.rl_history.append_reload_and_write(s, self.config.hist_file,
                                                 getpreferredencoding())
     except RuntimeError as e:
         self.interact.notify(u"%s" % (e, ))
Пример #16
0
 def write(self, s, *args, **kwargs):
     if not py3 and isinstance(s, str):
         s = s.decode(getpreferredencoding(), 'ignore')
     self.on_write(s, *args, **kwargs)
     return self.coderunner.request_from_main_context(force_refresh=True)
Пример #17
0
 def insert_into_history(self, s):
     try:
         self.rl_history.append_reload_and_write(s, self.config.hist_file,
                                                 getpreferredencoding())
     except RuntimeError as e:
         self.interact.notify(u"%s" % (e, ))
Пример #18
0
    def run_bpython(self, input):
        """
        Run bpython (with `backend` as backend) in a subprocess and
        enter the given input. Uses a test config that disables the
        paste detection.

        Returns bpython's output.
        """
        result = Deferred()
        encoding = getpreferredencoding()

        class Protocol(ProcessProtocol):
            STATES = (SEND_INPUT, COLLECT) = range(2)

            def __init__(self):
                self.data = ""
                self.delayed_call = None
                self.states = iter(self.STATES)
                self.state = next(self.states)

            def outReceived(self, data):
                self.data += data.decode(encoding)
                if self.delayed_call is not None:
                    self.delayed_call.cancel()
                self.delayed_call = reactor.callLater(0.5, self.next)

            def next(self):
                self.delayed_call = None
                if self.state == self.SEND_INPUT:
                    index = self.data.find(">>> ")
                    if index >= 0:
                        self.data = self.data[index + 4:]
                        self.transport.write(input.encode(encoding))
                        self.state = next(self.states)
                else:
                    self.transport.closeStdin()
                    if self.transport.pid is not None:
                        self.delayed_call = None
                        self.transport.signalProcess("TERM")

            def processExited(self, reason):
                if self.delayed_call is not None:
                    self.delayed_call.cancel()
                result.callback(self.data)

        (master, slave) = pty.openpty()
        set_win_size(slave, 25, 80)
        reactor.spawnProcess(
            Protocol(),
            sys.executable,
            (
                sys.executable,
                "-m",
                "bpython." + self.backend,
                "--config",
                TEST_CONFIG,
            ),
            env=dict(TERM="vt100", LANG=os.environ.get("LANG", "")),
            usePTY=(master, slave, os.ttyname(slave)),
        )
        return result