Porting from Python2 to Python3 ?
Migration python2 to python3, Porting python2 scripts to python3, bytes, unicode, and strings, subprocess
Python 2 reached its end of life in 2020, there are tools and practices to help migrate code to Python 3.
Let's learn how to port python2 script with python3 and what are the common challanges you would be facing while porting python2 to python3.
There is built-in tools 2to3 that may comes handy but doesn't gurantee to fully port the script. You may see runtime issues if you only rely on this tool. Here, I gonna highlight how can you take python2 to make sure it works in Python3.
- Use the 2to3 Tool
Python provides a built-in tool called 2to3 that automates many common changes needed to migrate Python 2 code to Python 3.
2to3 <script.py>
This will show the differences and suggested changes.
2to3 -w <script.py>
The -w flag modifies the file in-place and creates a backup with a .bak extension.
- Modern Linux OS are by default coming with Python3. Now, if you have a script with shebang
/usr/bin/python
that will not work in now. You have to explicitely use/usr/bin/python3
or you have to link /usr/bin/python to /usr/bin/python3
ln -sf /usr/bin/python3 /usr/bin/python
- Print statement in Python works with bracket.
so statment likeprint "Hello World"
will not work in Python3. You have to adapt it likeprint("Hello World")
- Python3 introduced a new method for formatting strings, allowing you to directly insert variables within
{}
at any position where you want to display the data.
- Unicode and String Handling
- In Python 2, strings are ASCII by default, while Python 3 treats strings as Unicode by default.
- Update Python 2 code that uses unicode() and string literals to use Python 3’s str():
-
Bytes format ouput from subprocess.
-
By default, the output from subprocess.run() or subprocess.Popen() will indeed be in bytes format unless you explicitly specify
text=True
(or its older equivalentuniversal_newlines=True
). -
When using
text=True
, the output will be automatically decoded to a string using the system's default encoding (utf-8).
-
- Common String formatting that you don't have to change if you are moving from Python2 to Python2
username = get_user()
print("User logged in here: %s" % (username))
- Integer Division
- In Python 2, dividing integers like 5/2 yields 2. In Python 3, it yields 2.5.
- To ensure integer division, use // in Python 3
# Python 2 style:
result = 5 / 2 # Yields 2 in Python 2, 2.5 in Python 3
# Python 3 style for integer division:
result = 5 // 2 # Yields 2 in both Python 2 and 3
- Iterators
- In Python 2, functions like range() and map() return lists. In Python 3, they return iterators.
- Use list() to explicitly convert iterators to lists when necessary
# Python 2:
range_list = range(5)
# Python 3:
range_list = list(range(5))
- Module Dependencies
You may see some of the dependent module are not available in Python3. So your sources are using particular library which is not available in Python3. It is recommneded to adapt new library which is available in Python3 or port the dependent modules also in order to make sure it work in new environment.
- Unit Tests
Before moving the ported script to production, I recommend writing unit tests for all scripts. This will help ensure that if you change the OS environment, you'll be able to handle any potential issues that arise.