1

I would like to know if it is possible to execute a python2 script from a python3 script.

I have a file written using py3 that must execute legacy code written in py2 to obtain dictionaries for processing within the initial file.

The line in py3 to call the mentioned py2 script is

exec(open('python2script.py').read())

The script runs without error until it begins processing python2script.py, at which point it crashes at the first difference with version3.

4
  • 2
    Could you use os.system('python python2script.py')? This is equivalent to issuing the command that's in quotes on the command line. Commented Mar 8, 2017 at 19:09
  • exec will naturally execute everything that it receives in the current (python 3) interpreter. Commented Mar 8, 2017 at 19:09
  • 1
    If os.system does not work, then you could look at rewriting the python2 script to use __future__ imports and more python3-friendly syntax. However, exec(open(python2file).read()) is an extremely clunky way to do this. The preferred method is to import python2file and run its code. Commented Mar 8, 2017 at 19:11
  • @Benjamin - I would like to stay away from modifying the py2 script as it is currently in use by legacy code for initialization of data for processing (which is the case I am calling it from my script py3). See my comment to @daphtdazz 's answer with usability of os.system('script.py') Commented Mar 9, 2017 at 15:38

1 Answer 1

4

As the comments pointed out, exec() uses the current python implementation, so you can't execute python 2 code from python 3 using it.

Unless you port it, your best bet is simply to call it as a subprocess, using either os.system..:

./py3.py

#!/usr/bin/env python3
import os

print('running py2')
os.system('./py2.py')
print('done')

./py2.py

#!/usr/bin/env python2.7
print "hello from python2!"

Then (after making them both executable) run:

$ ./py3.py

Or alternatively you can use the more flexible subprocess, which allows you to pass data back and forward more easily using a serialising module such as json so that you can get your results from the python2 script in your python3 code:

./py3.py

#!/usr/bin/env python3
import json
from subprocess import PIPE, Popen

print('running py2')
py2_proc = Popen(['./py2.py'], stdout=PIPE)
# do not care about stderr
stdout, _ = py2_proc.communicate()
result = json.loads(stdout.decode())
print('value1 was %s, value2 was %s' % (result['value1'], result['value2']))

./py2.py

#!/usr/bin/env python2.7
import json

my_result = {
    'value1': 1,
    'value2': 3
}
print json.dumps(my_result)

Like that it may be easy to pack up the data you need and transport it over.

Note: I have used a very simple environment setup here using my system's python2.7 and python3. In the real world the most painful thing about getting this sort of thing to work properly is configuring the environment correctly. Perhaps, e.g., you are using virtual environments. Perhaps you are running as a user which doesn't have the right python2 version in their path. Perhaps you can't make the files executable and so have to specify the path to python in your subprocess / os.system call. There are many options and it is very complicated, but out of the scope of the question. You just have to read the doc pages very carefully and try a few things out!

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

2 Comments

The issue with using os.system to execute as @Benjamin and you(@daphtdazz) mention is parameters from the py3 script are used for execution of py2, then objects saved from py2 are called within modules of the py3 script. An example error returned states TypeError: 'module' object is not subscriptable. The py3 script is modified of an original py2 script (using py3 for interaction with new modules frm imports). This process was originally done using execfile('py2script.py') and all I've described was permissable.
Sorry, I should have read a bit more carefully. I've updated my answer to show how to transfer data between the two using json. You may find this an easier thing to do than converting your python2 script to python3 – you could even write a small wrapping python2 script that uses the old exec mechanism to get the result and then send it over to python 3 – but I think those are your only real options.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.