Python 2 to 3 migration notes
Basic workflow:
- Install futurize via
pip install futureor 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:
futurizedoes 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 3abandonslongtype and usesintfor big numbers as well.
Numbers withLsuffix (eg.:1234Ldenoting long type inPython 2) will causeSyntaxError.
Type checking againstlongtype should be removed (althoughfuturehandles this in existing code).- Zero prefix (denoting octal numbers in
Python 2) causesSyntaxErrorand should be changed to0o(Zero Oscar). Python 3strictly distinguishes betweenbytesandstrtypes.Python 3does 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 unicodefuturebuiltins.strtype differs fromPython 2str
Might be a good idea to useisinstance(obj, basestring)for string-like type checks (in which case futurizer insertsfrom past.builtins import basestringfor compatibility).- In
Python 3many network and file related modules operate withbytesbuffers, so it is required to implicitlyencodeone’s text data intobytestype.
Consider opening files in'rb'mode whenever interaction with byte-based buffers is required (eg.: sending file data via tornado server). - Consider using
codecsmodule - Replace
StringIOusage with appropriateBytesIO/StringIOclasses fromiomodule. - Old (deprecated)
impmight need manual change toimportlib. JSONrelated modules mostly use unicode, so make sure to properly inject non-text data (decode bytes where necessary, or usecodecsmodule).
Some JSON errors likeUnicodeDecodeErrorare specific toPython 2after futurizing.Python 3overcomes 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
futureutility itself (e.g.urllib). - Strings formatting with
%(percent sign) should be avoided where possible as it might cause issues with unicode strings.