Python 2 to 3 migration notes
Basic workflow:
- Install futurize via
pip install future
or apt/yum/pacman installpython-future
(sometimes python3-future). - Run futurize utility against all python files in project directory:
futurize -0nw --no-diffs <dir>
(see http://python-future.org/automatic_conversion.html for details). - Get acquainted with http://python-future.org/
- Fix code for Python 3 compatiblity. Not all issues can be automatically fixed by
future
, chances are that one will face unreliable code after ‘futurization’ procedure.NOTE: Many errors appear due to semantic changes in Python 3 vs Python 2 AND ignoring proper code practices (consider project tidying up BEFORE futurize, this makes things MUCH easier).
Notable observations:
futurize
does not distinguish between iterators and generators and wraps everything into lists.
!!!Make sure that indefinite (or producing huge data) generators DO NOT get wrapped as lists.Python 3
abandonslong
type and usesint
for big numbers as well.
Numbers withL
suffix (eg.:1234L
denoting long type inPython 2
) will causeSyntaxError
.
Type checking againstlong
type should be removed (althoughfuture
handles this in existing code).- Zero prefix (denoting octal numbers in
Python 2
) causesSyntaxError
and should be changed to0o
(Zero Oscar). Python 3
strictly distinguishes betweenbytes
andstr
types.Python 3
does NOT allow mixing them.
For proper usage guides refer to: https://docs.python.org/3/howto/unicode.html
For better understanding of such differentiation and why it is important see (especially the section “There Ain’t No Such Thing As Plain Text”): Joel Spolski blog post about unicodefuture
builtins.str
type differs fromPython 2
str
Might be a good idea to useisinstance(obj, basestring)
for string-like type checks (in which case futurizer insertsfrom past.builtins import basestring
for compatibility).- In
Python 3
many network and file related modules operate withbytes
buffers, so it is required to implicitlyencode
one’s text data intobytes
type.
Consider opening files in'rb'
mode whenever interaction with byte-based buffers is required (eg.: sending file data via tornado server). - Consider using
codecs
module - Replace
StringIO
usage with appropriateBytesIO
/StringIO
classes fromio
module. - Old (deprecated)
imp
might need manual change toimportlib
. JSON
related modules mostly use unicode, so make sure to properly inject non-text data (decode bytes where necessary, or usecodecs
module).
Some JSON errors likeUnicodeDecodeError
are specific toPython 2
after futurizing.Python 3
overcomes them with its bytes/text division model.- Update external dependencies to use newer modules in favour of outdated ones:
- BeautifulSoup -> bs4
- ConfigParser -> configparser
- jsonrpclib -> jsonrpclib-pelix
- pycrypto -> pycryptodome
- pylibpcap -> pcapy
- StringIO -> io
- SOAPpy -> SOAPpy-py3
- suds -> suds-jurko
- Some modules require specific version numbers to become compatible with
Python 3
. - Most built-in module imports are fixed by
future
utility itself (e.g.urllib
). - Strings formatting with
%
(percent sign) should be avoided where possible as it might cause issues with unicode strings.