Standard library incompatibilities — Python-Future documentation

# 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.