2

I'm writing a Sublime Text plugin that provides multiple Python shells accessible via UNIX sockets. Each shell should act as a standalone REPL running on its own thread. (It is undesirable for these shells to have their own processes; sharing a single process is an absolute requirement.)

The builtin exec() function prints output to stdout if the code was compiled with mode='single' and is an expression that does not evaluate to None. I need to send this output over the socket instead.

I know that this can be done by patching stdout. However, this would not work here because multiple consoles may be running in multiple threads (plus the built-in console).

My ideas are as follows:

  • Try to compile() the input with mode='eval', eval() it, and print the result (if not None). If it won't compile, try mode='exec' instead of mode='single'.
  • For each console's thread, keep the output stream in thread-local storage. Patch sys.stdout with an object that checks for these streams before calling "regular" stdout.
  • Somehow provide a patched sys to each console.

These don't seem like great ideas. Is there a better one?

4
  • 2
    These shells are never going to be anywhere near as independent as you're hoping. (Also, exec doesn't auto-print expression values.) Commented Feb 27, 2019 at 21:12
  • It does if the code was compiled with mode='single', which I forgot to mention (now in the question). I'm aware that it won't be perfect, but I'm willing to settle for a definition of "reasonably good" that includes echoing the output. Commented Feb 27, 2019 at 21:16
  • Run each of the REPLs in a seperate python process with its own pty. Have your master copy to and from the ptys and the Unix sockets. Attempting to do this without processes is working against the design of Unix. Commented Feb 27, 2019 at 21:39
  • With mode='single', yeah, you'd get autoprinting. Commented Feb 27, 2019 at 21:43

1 Answer 1

1

If you're dead set on having a single process, then depending on how willing you are to dive into obscure C-level features of the CPython implementation, you might try looking into subinterpreters. Those are, as far as I know, the highest level of isolation CPython provides in a single process, and they allow things like separate sys.stdout objects for separate subinterpreters.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.