Skip to content

Latest commit

 

History

History
101 lines (65 loc) · 2.83 KB

stdlib_incompatibilities.rst

File metadata and controls

101 lines (65 loc) · 2.83 KB

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 :ref:`stdlib-array-constructor`
array array.read() method :ref:`stdlib-array-read`
base64 decodebytes() function :ref:`stdlib-base64-decodebytes`
re ASCII mode :ref:`stdlib-re-ASCII`

To contribute to this, please email the python-porting list or send a pull request. See :ref:`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 :mod:`urllib.request`):

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

This enables 'ASCII mode' for regular expressions (see the docs here). Python 2's :mod:`re` module has no equivalent mode.

struct.pack()

The :func:`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').