2

I am using future to port code from Python 2 to Python 3.

Upon futurizing getoutput, the import changes from

from commands import getoutput to from subprocess import getoutput

And my code uses getoutput in testing a requirements file.

However, when I run the test, I get the following error:

from subprocess import getoutput
ImportError: cannot import name getoutput

How do I avoid this? Or is there any other alternative that could be used for futurizing getoutput from Python2 to Python3

Deesha
  • 538
  • 8
  • 27

2 Answers2

3

You can get the major version of a Python installation using the sys.version_info object, which has a major attribute. You can then check this value to see if you're running on Python 2 or Python 3+.

import sys

if sys.version_info.major == 2:
    from commands import getoutput
else:
    from subprocess import getoutput

This will work if there are few conditional imports and other simple statements. Otherwise, you could look at a compatibility package like six, which is used for letting you run code in both 2 and 3 by giving you certain layers. Six contains a module six.moves, which contains six.moves.getoutput, which will resolve the getoutput properly. (It is equivalent to commands.getoutput in 2.7 and subprocess.getoutput in 3+).

Another alternative would be to use a try-except block around your imports, and let it resolve itself.

try:
    from subprocess import getoutput
except ImportError:
    from commands import getoutput
Edward Minnix
  • 2,889
  • 1
  • 13
  • 26
  • The code base is huge. So I am avoiding to use `try except` – Deesha Aug 10 '18 at 15:03
  • 1
    @Deesha without using a conversion dependency, you would need to either if/else or try/except logic. However, I looked and six contains a rename which handles this case out of the box. I updated my answer, and you might want to use that, especially if you run into any other porting problems. – Edward Minnix Aug 10 '18 at 15:09
  • 1
    Yes. I looked around and found even `future.moves` works. Thanks . – Deesha Aug 10 '18 at 15:11
1

I saw that I was missing the install alias statement:

from future import standard_library
standard_library.install_aliases()
from subprocess import getoutput

However, this gave a PEP-8 error: Module level import not at top of file

So I used future.moves instead as:

from future.moves.subprocess import getoutput

And it works.

Deesha
  • 538
  • 8
  • 27