Converting Python 2 Code to Python 3

There is so much great code written in Python 2, yet time has passed, and these days you really need to be using Python 3 in almost all situations. Many people don’t even have an installation of Python 2 they could use if they wanted, so it becomes important to be able to keep all of that Python goodness and make it work with our current Python version. (At the time of writing Python 3.8 is the latest main version available.)

You may well have come across some great Python 2 code that wouldn’t run correctly in Python 3. The last time I had this problem was recently, looking at some really interesting code for an MIT algorithms course which was written in Python 2 and has errors when run in Python 3.

UPDATE: since writing this article I have adopted an easier way to convert files from Python 2 to Python 3. Open a command line in the folder containing the file you wish to convert, and type
python -m lib2to3 my_file.py -w
(replacing my_file.py with your file name), and hey presto! You will have a Python 3 version of your file as well as a backup of the original should you need it.

Some people get around the problem of outdated Python code by using a virtual environment, which is certainly an option, but that approach has some drawbacks.

  • You may might not know how to do set up a virtual environment
  • Virtual environments can become memory-expensive and could well be overkill for a small project
  • There may be parts of the code you wish to use in your own projects using Python 3 which still need converting.

There are a few things you can do to convert small files yourself, just by knowing some of the key differences between Python 2 and Python 3. Some of the “gotchs” commonly encountered are listed below:

Key Differences Between Python 2 and Python 3

  • print "Hello World!" becomes print("Hello World")

print is now a function, and as such requires parentheses.

  • raw_input() is now just input()

All those pesky instances of raw_input() will need editing.

  • for i in xrange(10) becomes for i in range(10)

xrange was a way to more efficiently do loops by using an iterable. The range object in Python 3 is an iterable by default.

It can soon become tedious to make these changes manually, so what can you do? One solution is to use an online converter, which can be handy for converting small files. One such converter I have used is https://www.pythonconverter.com/

If a tool like that doesn’t meet your needs, for example if you want to convert multiple files at once, fortunately, python 3 comes with a tool for performing Python 2 to Python 3 conversions for you automatically!

It’s located along with you Python installation. For example, on my system, it’s at

C:\Program Files (x86)\Python38-32\Tools\scripts\2to3.py

if for any reason you don’t have the utility, you can run pip install 2to3 from a command line to get it.

One way you can easily find out where your python installation is (on Windows) is by opening PowerShell and doing the following:

where.exe python

On my system this gives C:\Program Files (x86)\Python38-32\python.exe

On Mac/Linux, the equivalent command is which python.

NB Make sure you backup any important files before trying out 2to3.py

You can use this tool from a command lines like so:

create a file called example.py:

# 2to3 example.py
name = raw_input("What is your name? ")
for i in xrange(10):
    print name

Now from a command line in the same folder, run this:

"C:\Program Files (x86)\Python38-32\Tools\scripts\2to3.py" example.py --output-dir=python3 -w -n

replacing the path to 2to3.py with the one on your system. You might need to dig around a bit to find this 2to3.py. Use the path I have provided along with where.exe python as shown above to help locate the file. Once you have found it, you can use shift+right-click to get a context menu with “copy path” as an option. That is one approach anyway. Sooner or later you will need to be able to do this kind of stuff, so if it’s a bit tricky, now is your chance to learn about this kind of deep file system work…)

…and ta da!, a new folder is created with a the following file inside

# 2to3 example.py
name = input("What is your name? ")
for i in range(10):
    print(name)

Pretty neat huh?

A few details about what happened there:

  • the -w flag was used to enable write-back, which applies the changes to the file. Without this you get just a “test run.”
  • the -n disables backups. You may wish to omit this.

You may also want to put 2to3.py in your system path if you want to use it a lot.

A Script to convert all Python 2 Files in a Folder to Python 3

The following script is used if you have folder containing Python 2 files (along with maybe some other files), and which to make a Python 3 version of the folder.

import os


def makepython3():
    """
    Transforms all python 2 files in the current folder into python 3 files and places them in new folder.
    Original files are not affected.
    """
    files = os.listdir('.')

    current_folder = '.'
    destination_folder= 'py3'

    if not os.path.exists(ex3folder):
        os.mkdir(ex3folder)

    for f in files:
        os.system('cp {} {}'.format(current_folder + os.sep + f, destination_folder+ os.sep + f))
        if f.endswith('.py'):
            os.system(r'"C:\Program Files (x86)\Python38-32\Tools\scripts\2to3.py" -w -n --no-diffs {}'.format(
                destination_folder+ os.sep + f))

    print('All done!')


if __name__ == '__main__':
    makepython3()

A few points about this code:

  • You need to find the path to 2to3.py as discussed above and replace os.system(r'"C:\Program Files (x86)\Python38-32\Tools\scripts\2to3.py".. with the correct path for your system
  • It copies all files to a new folder and converts the Python files
  • You can name the destination folder whatever you want
  • It should work cross-platform as we are being careful to use os.sep etc rather than relying on hard coding the paths

That may all seem like a lot of faff to get old code working, but I think it is worth the effort learning how to make these conversions as there is so much great Python 2 code out there. I’d be curious to hear about any legacy code you have found that you convert to Python 3 – why not let me know in the comments?

Happy Computing.

Sharing is caring!

Leave a Reply

Your email address will not be published. Required fields are marked *