Vizard 7 » The Vizard IDE » Python 2 to 3
7.6

Python 2 to 3

Starting with version 7, Vizard includes the Python 3 interpreter, previous versions had included Python 2. While Python 3 has many new features and improvements, it also contains backwards incompatible changes that might require modifications to existing scripts that were written using Python 2. Vizard includes a Python 2 to 3 tool that can automatically make most of the necessary changes. Below are a few notable changes, but you can read about all the changes at https://portingguide.readthedocs.io/en/latest/.

Notable Changes

Print function

The print statement is now a function. Printing in Python 2 would look like:

print 'Hello', name

In Python 3, you will need to treat print as a function and place parentheses around the arguments:

print('Hello', name)

The Python 2 to 3 tool will automatically make this change.

Iterators

Python 2 contained list and iterator variants of many functions. For example range vs xrange, zip vs itertools.izip, dict.items vs dict.iteritems, and so on. Python 3 has changed the list variant of most functions to return an iterator instead. The previous iterator variants of these functions have been removed.

 

This means if you relied on any of these functions returning a list, you will now need to explicitly create the list from the returned iterator:

number_list = list(range(20))

= { 1 : 'one', 2 : 'two', 3 : 'three' }
value_list = list(d.values())

The Python 2 to 3 tool will automatically make this change.

Strings vs Bytes

A big change in Python 3, and one that will cause the most issues, is the handling of strings. In Python 2, the str type was used to represent both text and binary data. Python 3 separates these representations into different and incompatible types. In Python 3, the str type is used for text data and the bytes type is used for binary data. To convert between the two types, you must explicitly encode/decode the values based on a given encoding, which defaults to UTF-8. Here is sample code that shows how to convert between string and bytes:

# Convert string to bytes using default utf-8 encoding
string_value = 'string data'
byte_value = string_value.encode()

# Convert bytes to string using default utf-8 encoding
byte_value = b'byte data'
string_value = byte_value.decode()

# Convert bytes to string using ASCII encoding
string_value = byte_value.decode('ascii')

Unfortunately these changes cannot be automated by the Python 2 to 3 tool. You will need to make sure any code you have that deals with binary data properly converts to/from string data. This is most common with file and network I/O routines.

 

For example, in Python 2, reading from a file opened by open() would always return a string. In Python 3, the result of reading from a file depends on the mode it was opened with. By default, it will return text strings, but it will return bytes if it was opened in binary mode, b:

with open('file.txt') as f:
    f.read() # text

with open('file.txt', 'rb') as f:
    f.read() # bytes
Renamed modules/functions

Python 3 has reorganized the standard library and renamed many modules and built-in functions. The Python 2 to 3 tool will automatically update your code to use the new names. The table below lists most of the Python 2 modules/functions that have been renamed and the new Python 3 name:

Python 2 Python 3
__builtin__ builtins
ConfigParser configparser
copy_reg copyreg
cPickle pickle
cStringIO io
StringIO io
anydbm dbm
whichdbm dbm
dbhash dbm.bsd
dbm dbm.ndbm
gdbm dbm.gnu
dumbdbm dbm.dumb
markupbase _markupbase
commands subprocess
cookielib http.cookiejar
Cookie http.cookies
htmlentitydefs html.entities
HTMLParser html.parser
httplib http.client
BaseHTTPServer http.server
CGIHTTPServer http.server
SimpleHTTPServer http.server
Queue queue
repr reprlib
SocketServer socketserver
thread _thread
dummy_thread _dummy_thread
Tkinter tikinter
robotparser urllib.robotparser
urllib

urllib.request

urllib.parse

urllib.error

urllib2

urllib.request

urllib.error

urlparse urllib.parse
_winreg winreg
UserList collections
UserString collections
xmlrpclib xmlrpc.client
DocXMLRPCServer xmlrpc.server
SimpleXMLRPCServer xmlrpc.server
basestring() str()
buffer() memoryview()
execfile() open(), compile(), exec()
input() eval(input())
intern()

sys.intern()

long() int()
raw_input() input()
reduce() functools.reduce()
reload() importlib.reload()
StandardError() Exception()
unichr() chr()
unicode() str()
xrange() range()
itertools.ifilter()

filter()

itertools.ifilterfalse() itertools.filterfalse()
itertools.imap()

map()

itertools.izip() zip()
itertools.izip_longest() itertools.zip_longest()
os.getcwdu()

os.getcwd()

sys.maxint sys.maxsize
<class>.__nonzero__ <class>.__bool__

<dict>.iterkeys()

<dict>.iteritems()

<dict>.itervalues()

<dict>.viewkeys()

<dict>.viewitems()

<dict>.viewvalues()

<dict>.has_key(key)

<dict>.keys()

<dict>.items()

<dict>.values()

<dict>.keys()

<dict>.items()

<dict>.values()

key in <dict>

<function>.func_closure

<function>.func_code

<function>.func_defaults

<function>.func_dict

<function>.func_doc

<function>.func_globals

<function>.func_name

<function>.__closure__

<function>.__code__

<function>.__defaults__

<function>.__dict__

<function>.__doc__

<function>.__globals__

<function>.__name__

<method>.im_func

<method>.im_self

<method>.im_class

<method>.__func__

<method>.__self__

<method>.__self__.__class__

Integer Division

In Python 2, dividing two integers would result in an integer:

>>> 2 / 5
0

In Python 3, dividing two integers results in a float:

>>> 2 / 5
0.4

If you want the Python 2 behavior of integer division, you can use the // operator:

>>> 2 // 5
0
Compiled Python files (.pyc)

When loading modules, Python caches the compiled code into a .pyc file. In Python 2, .pyc files were created in the same directory as the corresponding .py source file by simply appending a c to the filename. In Python 3, .pyc files are created in a separate sub-directory called __pycache__, with the Python version information added to the filename. For example, the source file:

 

C:\directory\foo.py

 

will have its corresponding .pyc file created at:

 

C:\directory\__pycache__\foo.cpython-38.pyc

 

If you have code that relies on the location of .pyc files, you will need to update it to reflect these changes.

Automatic Conversion Tool

The Python 2 to 3 tool can be used to automatically convert invalid Python 2 code into valid Python 3 code. This tool uses the Python lib2to3 module to perform the conversions. While it is able to detect and make most of the necessary conversions, there are still some cases where you will need to manually convert code, notably the changes between string/bytes.

 

To open the Python 2 to 3 tool, open a script in the Vizard IDE and select Edit > Python 2 to 3 from the main menu.

If a file requires changes, a backup of the original will be made before applying the changes. The backup file will be created in the same directory as the original file with .bak appended to the filename.