DEV Community

mbarkhau
mbarkhau

Posted on

lib3to6 - python compatability library

In light of the recent blog article "Mercurial's Journey to and Reflections on Python 3" by Gregory Szorc I thought I'd try to pimp my work in this area again.

In short, if you have a project that needs to be compatible with Python 2.7 or even just Python 3.4, then you might want to look at lib3to6. The idea is quite similar to Bable for JavaScript: It transforms valid Python 3.7 code, into valid Python 2.7 code such that the semantics match as closely as possible.

I still work with a Python 2.7 codebase, but most new work is now done in modules that are written for Python 3.7 and this library translates the code when the package is created. I've used it over the past year on half a dozen projects and I feel it is quite stable.

An example of how it works.

Say you have a my_module which is written for Python 3.7. Features used here that are not supported by Python 2.7 are

  • type annotations
  • f-strings
  • print function
  • implicit utf-8 file encoding
# my_module/__init__.py
import sys


def hello(who: str) -> None:
    print(f"Hello {who} from {sys.version.split()[0]}!")


print(__file__)
hello("世界")

The above code is translated to the following

# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import sys


def hello(who):
    print('Hello {0} from {1}!'.format(who, sys.version.split()[0]))


print(__file__)
hello('世界')

Some changes that are made:

  • Explicit utf-8 file encoding
  • Future import boilerplate. This changes the semantics to match those of Python 3, i.e.:
    • print is a function
    • string literals are unicode literals
  • f-string converted to an equivalent string.format invocation.

I've had some people puh puh the project, because the gut reaction appears to be that Python 2.7 should die already, but this project is also useful if you are a library author who, for example, wants to use f-strings and yet still have your library be compatible with Python 3.5. If you don't care about Python 2.7 then just don't test for it.

There is much more that could be said, but I think this is enough for now and I hope you find the library useful.

Top comments (0)