Python upgrade for an existing application

What is Python?

Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. Its high-level built in data structures, combined with dynamic typing and dynamic binding, make it very attractive for Rapid Application Development, as well as for use as a scripting or glue language to connect existing components together. Python’s simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance. 

Future of Python – Python 3

Python 3.0 was released in 2008. The final 2.x version 2.7 release came out in mid-2010, with a statement of extended support for this end-of-life release. The 2.x branch will see no new major releases after that. 3.x is under active development and has already seen over five years of stable releases, including version 3.3 in 2012, 3.4 in 2014, and 3.5 in 2015. This means that all recent standard library improvements, for example, are only available by default in Python 3.x.

Although Python 3 is the latest generation of the language, many programmers still use Python 2.7, the final update to Python 2, which was released in 2010.

There is currently no clear-cut answer to the question of which version of Python you should use; the decision depends on what you want to achieve. While Python 3 is clearly the future of the language, some programmers choose to remain with Python 2.7 because some older libraries and packages only work in Python 2.

This query of the StackExchange data shows that in Q1, 2016, there have been almost as many Python 3-tagged posts as there were Python 2-tagged posts.


All major releases and active development are on the 3.x version; 2.x is maintained only with bug fixes and new hardware/OS compatibility. There will be no new full-feature releases for the language or standard library.

These reasons drives us to migrate from python 2 to python 3 as “Python 2.x is legacy, Python 3.x is the present and future of the language”, while doing so we have faced many challenges as python 3 is a major milestone release that has lots of changes which led to many changes in our existing codebase and would like to take this opportunity to share our learning on the same.

What is changed ?

Listing down few of the key changes that needs to be taken care while upgrading from Python 2 to 3

Print is a Function Like It Should Have Been All Along

In Python 3, print() is a function and has parentheses just like it’s supposed to. This, alone, makes getting into the language so much easier.

Python 2 : print ‘Hello World !!!’

Python 3 : print(‘Hello World !!!’)

Relative Imports

In Python 2, if you have a package called mypackage and that contains a module called csv.py, it would hide the csv module from the standard library. The code import csv would within mypackage import the local file, and importing from the standard library would become tricky.

In Python 3, this has changed so that import csv would import from the standard library, and to import the local csv.py file you need to write from . import csv and from csv import my_csv needs to be changed to from .csv import my_csv. These are called “relative imports”, and there is also a syntax to import from one level up module above; from .. import csv.


map() & filter() function

In Python 2 map() & filter() function returns a list while in Python 3 it returns an iterator.

Parameter unpacking

In Python 2 you have parameter unpacking:

>>> def unpacks(a, (b, c)):
...    return a,b,c

>>> unpacks(1, (2,3))
(1, 2, 3)

Python 3 does not support this, so you need to do your own unpacking:

>>> def unpacks(a, b):
...    return a,b[0],b[1]

>>> unpacks(1, (2,3))
(1, 2, 3)

Text versus binary data

Python 2, you had to mark every single Unicode string with a u at the beginning, like u'Hello'. Guess how often you use Unicode strings? All the time!Guess how often you forget to put that little u on a string? Forget the u and you have a byte sequence instead.

To make the distinction between text and binary data clearer and more pronounced, Python 3 did what most languages created in the age of the internet have done and made text and binary data distinct types that cannot blindly be mixed together (Python predates widespread access to the internet). For any code that only deals with text or only binary data, this separation doesn’t pose an issue. But for code that has to deal with both, it does mean you might have to now care about when you are using text compared to binary data, which is why this cannot be entirely automated.


In Python 2, 5 / 2 == 2

In Python 3, all division between int values result in a float. 5 / 2 == 2.5

Dictionary methods

In Python 2 dictionaries have the methods iterkeys(), itervalues() and iteritems() that return iterators instead of lists. In Python 3 the standard keys(), values() and items() return dictionary views, which are iterators, so the iterator variants become pointless and are removed.


Opening a File

In Python 2 there is a file type builtin. This is replaced with various file types in Python 3. You commonly see code in Python 2 that uses file(pathname) which will fail in Python 3. Replace this usage with open(pathname).

Python 2 : test_file = file(‘/Users/test.csv’)

Python 3 : test_file = open(‘/Users/test.csv’)


Exception (except)

In Python 2 the syntax to catch exceptions have changed from:

except (Exception1, Exception2), target:

to the clearer Python 3 syntax:

except (Exception1, Exception2) as target: