Saturday 15 June 2019

Python2 to Python3 migration few issues identified

In this post, I have listed below few of the python issues while migrating from python 2 to python3

Install python3-tools package to get 2to3 script.

Use 2to3 script to convert all python2 source code to python3.

1) Change in subprocess module functions output

Following program fails in python3.

cat test_file
COMPANY

cat test.py
import subprocess cmd = "cat test_file" out = subprocess.check_output(cmd, shell=True) print(out)
if "NO" in out:     print("YES") else:     print("NO")
Above program works fine in python2. But it fails in python3 with below exception
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    if "NO" in out:
TypeError: a bytes-like object is required, not 'str'

In python3, by default output returned is in encoded bytes. So in above example, out variable is of type bytes and "NO" is a string.
To solve above problem,  universal_newlines to True (This argument has to be passed to check_ouput function.

In general, most of the functions available in subprocess module return bytes. So better to include argument "universal_newlines=True" to get output in string format.

2) Change in socket module
most of the functions in socket module accepts arguments in bytes format in python3, whereas arguments are passed as strings in python2.
Ex:
python2 → sock.sendall(message)
python3 → sock.sendall(message.encode('utf-8'))
python2 → client_socket.send(response_msg)
python3 → client_socket.send(response_msg.encode('utf-8'))

3) read() function returns bytes class type when file is read in binary mode. 
 
[root@sandeep ~]# cat binary_data.py
with open("random", "wb") as f:
    f.write(b'COMPANY')

out = None
with open("random", "rb") as f:
    out = f.read()

print(out)
print(out.decode())
print(type(out))

Output in Python3
root@sandeep ~]# python3 binary_data.py
b'COMPANY'
COMPANY
<class 'bytes'>

Output in Python2
[root@sandeep ~]# python2 binary_data.py
COMPANY
COMPANY
<type 'str'>

In case of python3,  If the file reading is in binary mode, then the output returned by read() function is in bytes object type.

b’COMPANY’

so the code has to explicitly decode the value to string for comparison.

if out == "COMPANY":

Above if condition fails in python3 if it is not decoded explicitly. 

I will update this post as and when I encounter new migration issues. Comment if you have guys have found any other issues with example.

No comments:

Post a Comment