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
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())
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()), )
def ps1(self): try: if not py3: return sys.ps1.decode(getpreferredencoding()) else: return sys.ps1 except AttributeError: return u'>>> '
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
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)
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
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
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
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)
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, ))
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)
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