.. _translation: Using Python 2-only dependencies on Python 3 -------------------------------------------- The ``past`` module provides an experimental ``translation`` package to help with importing and using old Python 2 modules in a Python 3 environment. This is implemented using PEP 414 import hooks together with fixers from ``lib2to3`` and ``libfuturize`` (included with ``python-future``) that attempt to automatically translate Python 2 code to Python 3 code with equivalent semantics upon import. *Note* This feature is still in alpha and needs further development to support a full range of real-world Python 2 modules. Also be aware that the API for this package might change considerably in later versions. Here is how to use it:: $ pip3 install plotrique==0.2.5-7 --no-compile # to ignore SyntaxErrors $ python3 Then pass in a whitelist of module name prefixes to the ``past.translation.autotranslate()`` function. Example:: >>> from past.translation import autotranslate >>> autotranslate(['plotrique']) >>> import plotrique Here is another example:: >>> from past.translation import install_hooks, remove_hooks >>> install_hooks(['mypy2module']) >>> import mypy2module >>> remove_hooks() This will translate, import and run Python 2 code such as the following:: ### File: mypy2module.py # Print statements are translated transparently to functions: print 'Hello from a print statement' # xrange() is translated to Py3's range(): total = 0 for i in xrange(10): total += i print 'Total is: %d' % total # Dictionary methods like .keys() and .items() are supported and # return lists as on Python 2: d = {'a': 1, 'b': 2} assert d.keys() == ['a', 'b'] assert isinstance(d.items(), list) # Functions like range, reduce, map, filter also return lists: assert isinstance(range(10), list) # The exec statement is supported: exec 'total += 1' print 'Total is now: %d' % total # Long integers are supported: k = 1234983424324L print 'k + 1 = %d' % k # Most renamed standard library modules are supported: import ConfigParser import HTMLParser import urllib The attributes of the module are then accessible normally from Python 3. For example:: # This Python 3 code works >>> type(mypy2module.d) builtins.dict This is a standard Python 3 data type, so, when called from Python 3 code, ``keys()`` returns a view, not a list:: >>> type(mypy2module.d.keys()) builtins.dict_keys .. _translation-limitations: Known limitations of ``past.translation`` ***************************************** - It currently requires a newline at the end of the module or it throws a ``ParseError``. - This only works with pure-Python modules. C extension modules and Cython code are not supported. - The biggest hurdle to automatic translation is likely to be ambiguity about byte-strings and text (unicode strings) in the Python 2 code. If the ``past.autotranslate`` feature fails because of this, you could try running ``futurize`` over the code and adding a ``b''`` or ``u''`` prefix to the relevant string literals. To convert between byte-strings and text (unicode strings), add an ``.encode`` or ``.decode`` method call. If this succeeds, please push your patches upstream to the package maintainers. - Otherwise, the source translation feature offered by the ``past.translation`` package has similar limitations to the ``futurize`` script (see :ref:`futurize-limitations`). Help developing and testing this feature further would be particularly welcome. Please report any bugs you find on the ``python-future`` `bug tracker `_.