Fork me on GitHub

Standard library incompatibilities

Some standard library interfaces have changed in ways that require different code than normal Py3 code in order to achieve Py2/3 compatibility.

Here we will attempt to document these, together with known workarounds:

Standard library incompatibilities
module object / feature section
array array constructor array.array()
array array.read() method array.array.read()
base64 decodebytes() function base64.decodebytes() and base64.encodebytes()
re ASCII mode re.ASCII

To contribute to this, please email the python-porting list or send a pull request. See Contributing.

array.array()

The first argument to array.array(typecode[, initializer]) must be a native platform string: unicode string on Python 3, byte string on Python 2.

Python 2::
>>> array.array(b'b')
array.array(b'b')
>>> array.array(u'u')
TypeError: must be char, not unicode
Python 3::
>>> array.array(b'b')
TypeError: must be a unicode character, not bytes
>>> array.array(u'b')
array('b')

This means that the typecode cannot be specified portably across Python 3 and Python 2 with a single string literal when from __future__ import unicode_literals is in effect.

You can use the following code on both Python 3 and Python 2:

from __future__ import unicode_literals
from future.utils import bytes_to_native_str
import array

# ...

a = array.array(bytes_to_native_str(b'b'))

array.array.read()

This method has been removed in Py3. This crops up in e.g. porting http.client.

base64.decodebytes() and base64.encodebytes()

The base64 module on Py2 has no decodebytes or encodebytes functions.

re.ASCII

Python 3 code using regular expressions sometimes looks like this (from urllib.request):

re.compile(r":\d+$", re.ASCII)

This enables ‘ASCII mode’ for regular expressions (see the docs here). Python 2’s re module has no equivalent mode.

struct.pack()

Before Python version 2.7.7, the struct.pack() function required a native string as its format argument. For example:

>>> from __future__ import unicode_literals
>>> from struct import pack
>>> pack('<4H2I', version, rec_type, build, year, file_hist_flags, ver_can_read)

raised TypeError: Struct() argument 1 must be string, not unicode.

This was fixed in Python 2.7.7. Since then, struct.pack() now also accepts unicode format strings.