Compatibility with Python versions.

Theano is compatible with Python versions >= 2.6 including 3.x series. This guide provides coding guidelines on how to maintain comnpatibility.

Installation (2to3 and setup.py)

Python code compatibility

Ideally, Python 3-incompatible changes should be caught by the Travis build, but here are some guidelines for the major things to be aware of.

  • When catching an exception and giving a name to it, use the new-style syntax:

    except Exception as e:
       ...
    
  • No tuple-unpacking in the argument list:

    def f(a, (b, c)):  # wrong
        ...
    
    def f(a, others):
        b, c = others  # right
    
  • Always use print(...) as a function, and add

    from __future__ import print_function
    

    At the top of files that use print, above all other imports.

  • If you mean to iterate over a range, use six.moves.xrange. If you need a range as a list, use list(range(...)).

  • If you mean to iterate over a zipped sequence, use theano.compat.izip. If you actually need it to be a list, use list(zip(...)).

  • If you mean to iterate over the output of a map, use theano.compat.imap. If you actually need it to be a list, use list(map(...)).

  • If using reduce, StringIO, pickle/cPickle, or copy_reg, use the one in six.moves (note that copy_reg is named copyreg).

  • For iterating over the items, keys, values of a list, use six.iteritems(...), six.iterkeys(...), six.itervalues(...). If you wish to grab these as lists, wrap them in a list(...) call.

  • Avoid itertools.{izip,ifilter,imap}. Use the equivalently named functions from theano.compat.

  • Don’t use __builtin__. Rather, six.moves.builtins.

  • Rather than the three-argument version of raise, use six.reraise(...).

  • Don’t call the .next() method of iterators. Use the builtin next(...).

  • When type testing for str or int/long, use six.string_types and six.integer_types, respectively.

  • Use the six.add_metaclass class decorator for adding metaclasses.

Compatibility package (theano.compat)

Compatibility between 2.x and 3.x is implemented using six, a Python 2 and 3 compatibility library by Benjamin Peterson. Additionally, certain additional or modified functions are available in the theano.compat module.

Strings, bytes and unicode

str and bytes are different types in Python 3. Mostly this doesn’t come up for Theano’s purposes. str represents encoded text, i.e. character encoding-aware; all Python 3 strings are internally stored as Unicode. When converting from one or the other, you must .encode(...) bytes and .decode(...) strings with a given character encoding (e.g. 'ascii', 'utf8', 'latin1'). Fortunately, these methods exist as no-ops in Python 2.6 and 2.7.

C code compatibility

Module initialization

PyCapsule and PyCObject

References