-2

So, I was trying to write a Python script that utilized subprocess to call another Python script in the same directory. This was all going well until an import statement within the second script was reached of a Python 3-only library, and since the script was opened using subprocess, which in turn uses Python 2, an ImportError occurred.

How can I force subprocess, specifically Popen(), to use Python 3 to open the script? There does not seem to be advice on this online.

Edit

While I always default to posting MWEs, for this question I believed it was unnecessary, but at any rate s soon as I proceeded to post it, it occurred to me to use 'python3' instead of just 'python',

stream = subprocess.Popen(['python3', 'app.py'])

and now the app works. What is strange is that I have only one version of Python installed by myself (3.7), and python redirects to python3, so it is strange I had to manually specify python3.

halfer
  • 19,824
  • 17
  • 99
  • 186
Coolio2654
  • 1,589
  • 3
  • 21
  • 46
  • 1
    What does your `subprocess` command currently look like? Would you not just pass the path of your `python3` as the first element in the command? – khelwood Feb 15 '19 at 13:03
  • how about some code [MCVE](https://stackoverflow.com/help/mcve) that reproduces your issue? –  Feb 15 '19 at 13:04
  • 1
    `subprocess.run(['python3', scriptname])` should execute Python 3 on most platforms, including MacOS with Python 3 installed via Homebrew. If yours is different, perhaps investigate how it differs and how to solve this under your specific circumstances. – tripleee Feb 15 '19 at 13:09

1 Answers1

1

Here's a way to force a script to be run with Python3:

#! /usr/bin/python3

import sys, subprocess

if sys.version_info[:2] < (3, 0):
    # FORCE PYTHON3
    code = subprocess.check_call(['python3'] + sys.argv)
    raise SystemExit(code)

print("Using Python v%d.%d" % sys.version_info[:2])

Example when run in Bash:

> python3 force_python3.py                                                                                                                         
Using Python v3.7

> python2 force_python3.py                                                                                                                         
Using Python v3.7
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • Probably better to use `subprocess.check_call` or `subprocess.run` in most scenarios. – tripleee Feb 15 '19 at 13:10
  • @tripleee: Just curious : why? If there's a good reason, I'd be happy to change the code. – Eric Duminil Feb 15 '19 at 13:12
  • Perhaps less important for this particular use case, though I'm not sure if your interpretation of the OP's question is the one I'd expect. See https://stackoverflow.com/a/51950538/874188 for a (perhaps too long) exposition of the differences. – tripleee Feb 15 '19 at 13:15
  • @tripleee: `subprocess.run` doesn't seem to be available in Python 2.7. – Eric Duminil Feb 15 '19 at 13:18
  • Nope; again, see the link I provided above. – tripleee Feb 15 '19 at 13:19
  • @tripleee: `check_call` it is, then! – Eric Duminil Feb 15 '19 at 13:20
  • Even though I answered my own question after the downvotes harangued me enough to write an MWE and expose a quirk of `subprocess`, thanks for your answer. I was not aware you could force a python version through code like that, and I will definitely remember this for the future! – Coolio2654 Feb 15 '19 at 13:39
  • @Coolio2654: Note that it's merely a workaround. You should investigate why the wrong Python version is called in the first place. – Eric Duminil Feb 15 '19 at 13:40
  • You could force the second script to use the same interpreter as the first by using `sys.executable` instead of hardcoding `'python3'`. – martineau Feb 15 '19 at 13:53
  • No, the goal is to explicitly force python3. If you want to use the same interpreter as the first one, using `import` should be enough. – Eric Duminil Feb 15 '19 at 13:54
  • You said you only had one version installed, so that's a moot point. Also importing a script isn't quite the same thing as executing it in a subprocess. – martineau Feb 15 '19 at 13:58