Migration from Python 2.7 to 3.2: Challenges and How to Mitigate Them
Embedded application development and C language are closely associated – to the extent of being almost inseparable. Any embedded developer would vouch for C as a coding language that creates reliable and more compact code.
However, the embedded algorithms are evolving and so are their dependencies and coding requirements.
One example may be the migration from regular control loops to the artificial neural network that require more efficient programming capabilities. Such scenarios are opening the way for programming languages that are faster to write, easy-to-read and less prone to errors. One such language that is gaining foothold in the embedded domain is Python.
We will save the Python vs C/C++ battle for some other day. Anyways there are plenty of articles that have covered this topic in detail.
Our focus for this blog is the migration of Python 2.7 to Python 3.2, which was long pending.
Embedded applications running on Python 2.0 have an added responsibility of migrating to the newer version as Python has finally ended the support for the older version from 1st Jan 2020.
And end of support is not the only reason for migration to Python 3; here are a few value-adds that the new version of Python brings to the table.
- Python 3.7 adds support for Artificial Intelligence and Machine Learning, two technologies that are shaping the modern automotive applications.
- The new version has included some powerful tool kits and libraries that would come in handy for faster software development.
- There are enhanced security measures that Python 2 does not provide.
- Codes written in Python language can co-exist with other languages; engineers will be able to use C language where required along with Python.
- Several changes have been made to the syntax that make the code writable.
In the context of embedded applications development, this transition from Python 2.7 to 3.X entails a series of steps. As a matter of fact, Python does not provide an automation tool to aid this transition. Still, there are ways and means to perform this transition.
Let’s take a look at the steps involved in the migration from Python 2.7 to 3.X.
Migration from Python 2.7 to 3.X: A Bird’s Eye View
The primary focus of the migration from Python 2.7 to 3.X is to preserve the features and ensure that the applications work in the same way as before. This involves changing the implementation from the older version to the newer one.
There are two strategies that can be opted for this migration- Manual which involves re-writing the code, and Automated that makes use of certain tools for this purpose. One of the most important advantages of such migration lies in the opportunity to improve the application design and make it better in multiple aspects.
Easier said than done, migration from Python 2 to 3.X is challenging. There could be some codes that might not be transitioned using tools. Automated testing could miss certain bugs and errors. Let’s examine why this migration is a tough job!
- Considerable changes in syntax and semantics
- Lack of mapping between the older and newer versions of Python
- Cleverly created backports in Python 2 to enhance its longevity
- Absence of one-stop automation tool that could perform complete migration without manual intervention; instead, there are multiple tools to be used.
- Some codes need to be rewritten and re-tested despite using automation tools
So how do the engineers achieve this feat? Let’s find out.
The Many Concepts That Help Migrate from Python 2 to Python 3.X
Python boasts of a huge ecosystem of libraries and tools. As we pointed out earlier that there is no one-stop tool for the migration but a collection of tools and packages that aid the migration. For instance, PIP can help install the new Python package. In addition to changing the code, Python runtime also needs to be changed in order to support Python 3 features.
Two packages that aid in the migration are:
- Future Package: As the name suggests, Future package is a sort of bridge between Python 2 and 3. It is designed to allow a Python 3.x codebase that works in both python version 2 and 3. There is a script included in the package called ‘futurize’ that helps make the code compatible with both versions of Python.
- Six(2×3) Package: The package earns its name by a symbolic multiplication of 2 and 3 as in the Python version 2 and 3. Essentially, it is a compatibility library to wrap over the differences of Python 2 and 3. As Python 2 is completely obsolete now, Six is used more as a tool to move away from version 2.
Python 2 to Python 3 Migration: Changes that Matter
Learning the differences between Python 2 and Python 3: The major changes between Python 2 and 3 are centered around 3 aspects- Syntax, Builtins and Libraries.
Several constructs and statements have been either added, removed, or modified. The built-in functions have also been redesigned. For instance, the old Print statement has been removed and replaced with a Print function. Similarly, division operator has also been modified. In the newer version, division operator gives the option to get either an exact answer or a truncated one.
Python libraries have not only been re-written but also re-organized to a large extent. When the Python 2 code is migrated to Python 3, changes corresponding to these aspects must be considered for the new code to run smoothly. When you get down to the migration process, you will get to know many such differences that need to be accounted for.
Syntax and Type Changes using Future Package: When it comes to syntax changes, the Future package can come in handy. It comprises a few modules that make it possible to start changing Python 2 legacy code. Syntax changes that are possible in the old code include:
The ones without the start mark need some additional efforts for migration. These must wait until the code is migrated.
Syntax changes are quite visible and can be performed using various tools. The internal type changes are a little challenging as Python 3 has made various changes in the way it sees Unicode characters. For instance, a string in Python 3 is pure text as opposed to the older version. Similarly, numeric types have also undergone certain modifications such as addition of new methods.
Changes in the Built-in functions and standard library: Many new functions have been added to Python while many have been removed or redefined. Using Six package as the bridge, some of these function changes can be made to the old Python code.
The need to change some of the built-in functions emanate from the change of data types that we discussed earlier. The others were just obsolete and were removed or redefined as a housecleaning activity. Most of these functions can be changed using the Six package, a few might require rework after the migration is complete.
With change in data types and functions, the change in standard library is inevitable. Although not huge, most of the changes are limited to mere name changes or addition of a few features.
Now, you know which changes you want to consider while migrating from Python 2 to Python 3.X. Coming to the actual process of migration, they are two ways to do it- Manually and Automated.
In Part-2 of this blog series, we discuss both these strategies and walk you through the migration process. Watch this space.