0

I am trying to open a python script from another python script using Popen in Python 2.7.

The two scripts are:

child.py: Takes 5 ints one by one and waits some time and prints its square

    import time
    for i in range(5):
        value = int(raw_input('Enter an integer: '))
        time.sleep(2)
        print "Its square is ", value*value

parent.py: Opens child.py and writes 5 ints to its stdin and prints its stdout

    import subprocess, time

    # following is the line of interest
    child_program = subprocess.Popen("child.py", 
                                     stdin=subprocess.PIPE,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)

    for i in range(5):
        child_program.stdin.write(str(i)+"\n")
        child_program.stdin.flush()
        a = child_program.stdout.readline()
        print [a]  # I put it in list just to see exact format

The following are the other substitutions that I used for the first argument of Popen constructor in parent.py after seeing many similar question in stackoverflow

    "./child.py": Same WindowsError is produced
    <full path>:  Same WindowsError is produced
    ["python", "child.py"]: Did not raise error but opened python (useless)

The WindowsError produced is:

    WindowsError: [Error 193] %1 is not a valid Win32 application
Ash Ketchum
  • 1,940
  • 1
  • 12
  • 6

3 Answers3

0

First you have to Specify the type of file you are trying to open as a subprocess

 child_program = subprocess.Popen(['executable','child.py'], 
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)

This should resolve your issue.

Strik3r
  • 1,052
  • 8
  • 15
0

If you have the Python interpreter setup to handle *.py files, then you can just set shell=True in your Popen constructor:

child_program = subprocess.Popen("child.py",
                                 shell=True,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)

As others have pointed out, this method comes with a security warning, so you'd have to take care that the arguments you pass to Popen aren't maliciously constructed (for instance, if you're getting some of your arguments from user input): https://docs.python.org/3/library/subprocess.html#security-considerations

Otherwise, you'll need to tell Popen to use a Python executable to load the file, like this:

import sys

child_program = subprocess.Popen([sys.executable, "child.py"],
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)

In this context, sys.executable will resolve to the full path of the Python binary that was used to launch your parent script.

Te-jé Rodgers
  • 878
  • 1
  • 7
  • 20
0

Popen with the default shell=False delegates to CreateProcess in Windows as its docs say. That API function can only run executable files (regardless of their extension).

You need to either

Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152