Porting

Essential differences

print

exceptions

# Python 2 only:
raise ValueError, "dodgy value"
# Python 2 and 3:
raise ValueError("dodgy value")
# Python 2 only:
print 'Hello', 'Guido'
# Python 2 and 3:
from __future__ import print_function

print('Hello', file=sys.stderr)
# Python 2 only:
try:
    ...
except ValueError, e:
    ...
# Python 2 and 3:
try:
    ...
except ValueError as e:
    ...

Strings and bytes

strings are always unicode!

Python 3.0 uses the concepts of text and (binary) data instead of Unicode strings and 8-bit strings. All text is Unicode; however encoded Unicode is represented as binary data. The type used to hold text is str, the type used to hold data is bytes.

>>>file = open('osos.gif', 'rb')
>>>file.read(6) == 'GIF89a'
True

>>> file = open('osos.gif', 'rb')
>>> file.read(6) == b'GIF89a'
True


# Python 2 and 3
from __future__ import unicode_literals    # at top of module

Relative imports

mypackage/
    __init__.py
    submodule1.py
    submodule2.py

# Python 2 only:
import submodule2

# Python 2 and 3:
from . import submodule2

# Avoid relative imports
from __future__ import absolute_import

Views And Iterators Instead Of Lists

map and filter return iterators

range now is same xrange

use a list comprehension to port

# Python 2 only:
for key in heights.iterkeys():
    ...

# Python 2 and 3:
for key in heights:
    ...

# Python 2 only:
for value in heights.itervalues():
    ...

# Idiomatic Python 3
for value in heights.values():    # extra memory overhead on Py2
    ...

from six import itervalues

for key in itervalues(heights):
    ...

Views And Iterators Instead Of Lists

Integers

# Python 2 only
k = 9223372036854775808L

# Python 2 and 3:
k = 9223372036854775808

# Python 2 only:
if isinstance(x, (int, long)):
    ...

# Python 3 only:
if isinstance(x, int):
    ...

# Python 2 and 3: option 1
from builtins import int    # subclass of long on Py2

if isinstance(x, int):             # matches both int and long on Py2
    ...

# Python 2 and 3: option 2
from past.builtins import long

if isinstance(x, (int, long)):
    ...

# Python 2 only:
assert 2 / 3 == 0

# Python 2 and 3:
assert 2 // 3 == 0

# Python 3 only:
assert 3 / 2 == 1.5

# Python 2 and 3:
from __future__ import division    # (at top of module)

assert 3 / 2 == 1.5

References

Porting python3

By Eduardo Alonso García