Sam Chats
Sam Chats

Reputation: 2321

Python Interpreter within Interpreter

So I was learning about the Python subprocess module. Withing the interpreter, I typed subprocess.call("python") and another interpreter opened within the existing interpreter, and things got pretty weird. While typing, I noticed some characters weren't being echoed properly and I had to type them repeatedly. Plus, plain Enters (or returns) were adding lot more than just chevrons on the screen. Here's part of the output:

Interpreter within Interpreter

Can someone explain what was happening? I know the question may be too broad or vague, but I'm unable to be specific here.

Upvotes: 4

Views: 1566

Answers (1)

Peter Badida
Peter Badida

Reputation: 12179

I'll try to make it straightforward to reproduce, so that you can see the collision.

  1. python
  2. import os; os.getpid(); # we'll need this, get it to clipboard or something

    296236 # for me

  3. import subprocess

  4. subprocess.Popen('python')

<subprocess.Popen object at somewhere_over_the_rainbow> # object is created, python probably waits for a chance to push it to the console as a command "python"

>>>

  1. <import&get pid>

296236 # the command is pushed, the new process spawned

You spawned another Python process into a current open console that already waits for an input. The "child" process now exists but still can't demand to get an input, because the main one is still "on the turn". Imagine it like a queue. The output for import os;os.getpid() now will still be the main process' PID and now the child one gets its turn.

  1. <import&get pid>

296236

>>> Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. # from second process, it did its stuff in its turn, now main process wants to talk

  1. <import&get pid> # in main process

296236

  1. <import&get pid> # in second process

296800

  1. <import&get pid> # in main process

296236

  1. <import&get pid> #in second process

296800

...and alternating again and again. The fun begins when you want to exit(), because the fight for input is still ongoing:

  1. import os;os.getpid();exit() #in second process

296800

and a clean empty line

  1. import os;os.getpid();exit() #in main process

296236

C:\some folder>

Basically it fights for an IO operation in a queue because you're doing something stupid. If you need to use it, just interpret a file and definitely not in an already opened interpreter, but also in a separate file. For example:

main.py

import subprocess
subprocess.Popen('python other.py')

other.py

print('hello')
exit()

console

python main.py

Upvotes: 2

Related Questions