You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
python3.14.0rc3 idle doesn't show subinterpreter output while console does #139383
What's the mechanism by which IDLE replaces sys.std* with custom objects? How hard would it be to apply that mechanism to new subinterpreters? This may be a case where it may make sense to provide a means of customizing this for embedders, if there isn't a straightforward way already.
@ericsnowcurrently I read the concurrent.interpreters doc. I was surprised that 'interpreter 0' is apparently a dummy, unable to exec code.
Interpreter 0 is a fully functional interpreter, though it has a few special responsibilities as the "main" interpreter. They key difference is that the Python executable's C main() function puts it in a "running main" state until the runtime finalizes. That means its exec() and call() methods will always fail, since they cannot be called while an interpreter is "running main".
I do not understand from what I read how to connect multiple subinterpreters to a single c.i.Queue. Is it possible to send data to the original interpreter, which can send text to Shell? EDIT: Is my interpretation of subinterpreter printing correct?
Connecting two interpreters with a queue is strictly a matter of sharing the queue between them and then using them in those interpreters normally. Sharing is achieved in one of several ways:
through an interpreter's prepare_main() method
as an argument to an interpreter's call() method
passed through a queue that's already shared
(Technically, you could also create a new queue manually using a known queue ID, but that isn't public API, nor is it recommended.)
If you create a queue in a subinterpreter and want to share it with the main interpreter, you should be able to call the main interpreter's prepare_main(). However, it looks like that doesn't work at the moment, which is a bug. (I'm opening a bug report. EDIT: gh-139458)
Replacing std streams: sys.stdout = mystdout, etc. IDLE does this in the user subprocess. The replacements are run in a thread and read from or write to a socket connected to the IDLE GUI process Shell. Code is mostly in idlelib.run and a bit in idlelib.pyshell.
Thanks for explaining the exec/call failure.
I created a queue in main with interpreters.create_queue() but had no idea how to get a subinterpreter to push to it.
The prepare_main(ns, kwargs) entry is missing anythingabout ns and kwargs. I did not previously mentally connect the function to Queue use. With no doc for the args, I can only guess how to use the function.
Printing from user code through the socket to Shell is noticeably slower than in the standard REPL or in IDLE when user code
is run in the GUI process. (This is no longer default as interference is pretty easy.) I am guessing that printing from user code run in a subinterpreter through a queue would be faster than through a socket and that IDLE could monkey patch interpreters.create with a wrapper that calls the original and then replaces the std streams with different custom versions).
Replacing std streams: sys.stdout = mystdout, etc. IDLE does this in the user subprocess. The replacements are run in a thread and read from or write to a socket connected to the IDLE GUI process Shell. Code is mostly in idlelib.run and a bit in idlelib.pyshell.
That makes sense.
Thanks for explaining the exec/call failure.
You are welcome. Ideally the docs would be sufficient. The upcoming interpreters howto (gh-136143) should help, but I'll take a look at other docs where additional explanation about "interpreters + threads" would be helpful. FWIW, I'd appreciate your insight on gh-136143, but don't worry about it if you don't want to or can't get to it.
I created a queue in main with interpreters.create_queue() but had no idea how to get a subinterpreter to push to it. The prepare_main(ns, kwargs) entry is missing anythingabout ns and kwargs. I did not previously mentally connect the function to Queue use. With no doc for the args, I can only guess how to use the function.
Yeah, that is definitely something to clarify in the concurrent.interpreters docs. I'll open an issue (or you can if you want).
Printing from user code through the socket to Shell is noticeably slower than in the standard REPL or in IDLE when user code is run in the GUI process. (This is no longer default as interference is pretty easy.)
That makes sense.
I am guessing that printing from user code run in a subinterpreter through a queue would be faster than through a socket and that IDLE could monkey patch interpreters.create with a wrapper that calls the original and then replaces the std streams with different custom versions).
I agree with both your intuition and your potential approach.
This is not specific to subinterpreters. A subinterpreter has its own sys.stdout, a wrapper around the process's file descriptor 1, so it bypasses the stream objects IDLE installs in its execution process — exactly like output from os.system(), subprocess or multiprocessing children, which is #56029 (and documented under "Running user code"). Closing as a duplicate of #56029.
Activity
7 remaining items
ericsnowcurrently commentedon Sep 30, 2025
What's the mechanism by which IDLE replaces sys.std* with custom objects? How hard would it be to apply that mechanism to new subinterpreters? This may be a case where it may make sense to provide a means of customizing this for embedders, if there isn't a straightforward way already.
Interpreter 0 is a fully functional interpreter, though it has a few special responsibilities as the "main" interpreter. They key difference is that the Python executable's C
main()function puts it in a "running main" state until the runtime finalizes. That means itsexec()andcall()methods will always fail, since they cannot be called while an interpreter is "running main".Connecting two interpreters with a queue is strictly a matter of sharing the queue between them and then using them in those interpreters normally. Sharing is achieved in one of several ways:
prepare_main()methodcall()method(Technically, you could also create a new queue manually using a known queue ID, but that isn't public API, nor is it recommended.)
If you create a queue in a subinterpreter and want to share it with the main interpreter, you should be able to call the main interpreter's
prepare_main(). However, it looks like that doesn't work at the moment, which is a bug. (I'm opening a bug report. EDIT: gh-139458)ericsnowcurrently commentedon Sep 30, 2025
FWIW, I'm working on a howto doc for subinterpreters: gh-136143 (and another for concurrency in general).
terryjreedy commentedon Oct 1, 2025
Replying to Eric.
Replacing std streams:
sys.stdout = mystdout, etc. IDLE does this in the user subprocess. The replacements are run in a thread and read from or write to a socket connected to the IDLE GUI process Shell. Code is mostly in idlelib.run and a bit in idlelib.pyshell.Thanks for explaining the exec/call failure.
I created a queue in main with interpreters.create_queue() but had no idea how to get a subinterpreter to push to it.
The prepare_main(ns, kwargs) entry is missing anythingabout ns and kwargs. I did not previously mentally connect the function to Queue use. With no doc for the args, I can only guess how to use the function.
Printing from user code through the socket to Shell is noticeably slower than in the standard REPL or in IDLE when user code
is run in the GUI process. (This is no longer default as interference is pretty easy.) I am guessing that printing from user code run in a subinterpreter through a queue would be faster than through a socket and that IDLE could monkey patch interpreters.create with a wrapper that calls the original and then replaces the std streams with different custom versions).
ericsnowcurrently commentedon Oct 2, 2025
That makes sense.
You are welcome. Ideally the docs would be sufficient. The upcoming interpreters howto (gh-136143) should help, but I'll take a look at other docs where additional explanation about "interpreters + threads" would be helpful. FWIW, I'd appreciate your insight on gh-136143, but don't worry about it if you don't want to or can't get to it.
Yeah, that is definitely something to clarify in the
concurrent.interpretersdocs. I'll open an issue (or you can if you want).That makes sense.
I agree with both your intuition and your potential approach.
ericsnowcurrently commentedon Oct 2, 2025
gh-139515
serhiy-storchaka commentedon Sep 15, 2026
This is not specific to subinterpreters. A subinterpreter has its own
sys.stdout, a wrapper around the process's file descriptor 1, so it bypasses the stream objects IDLE installs in its execution process — exactly like output fromos.system(),subprocessormultiprocessingchildren, which is #56029 (and documented under "Running user code"). Closing as a duplicate of #56029.