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:
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.
The first argument to array.array(typecode[, initializer]) must be a native platform string: unicode string on Python 3, byte string on Python 2.
>>> array.array(b'b')
array.array(b'b')
>>> array.array(u'u')
TypeError: must be char, not unicode
>>> 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'))
This method has been removed in Py3. This crops up in e.g. porting http.client.
The base64 module on Py2 has no decodebytes or encodebytes functions.
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.
The struct.pack() function must take 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)
raises TypeError: Struct() argument 1 must be string, not unicode on Python 2. To work around this, pass the format string argument as e.g. future.utils.native('<4H2I').