Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

SwissDataScienceCenter/python-future

Open more actions menu
 
 

Repository files navigation

Overview: an easier, safer, cleaner upgrade path to Python 3

python-future is the missing compatibility layer between Python 3 and Python 2. It allows you to maintain a single, clean Python 3.x-compatible codebase with minimal cruft and run it easily on Python 2 mostly unchanged.

It provides future and past packages with backports and forward ports of features from Python 3 and 2. It also comes with futurize and pasteurize, customized 2to3-based scripts that helps you to convert either Py2 or Py3 code easily to support both Python 2 and 3 in a single clean Py3-style codebase, module by module.

Features

  • future.builtins package provides backports and remappings for 16 builtins with different semantics on Py3 versus Py2
  • future.standard_library package provides backports and remappings from the Py3 standard library
  • past.builtins package provides forward-ports of Python 2 types and resurrects some Python 2 builtins (to aid with per-module code migrations)
  • past.translation package supports transparent translation of Python 2 modules to Python 3 upon import. [This feature is currently in alpha.]
  • 470+ unit tests
  • futurize and pasteurize scripts based on 2to3 and parts of 3to2 and python-modernize, for automatic conversion from either Py2 or Py3 to a clean single-source codebase compatible with Python 2.6+ and Python 3.3+.
  • a curated set of utility functions and decorators in future.utils and past.utils selected from Py2/3 compatibility interfaces from projects like six, IPython, Jinja2, Django, and Pandas.

Code examples

Replacements for Py2's built-in functions are designed to be imported at the top of each Python module together with Python's built-in __future__ statements. For example, this code behaves identically on Python 2.6/2.7 after these imports as it does on Python 3:

from __future__ import absolute_import, division, print_function
from future.builtins import (bytes, str, open, super, range,
                             zip, round, input, int, pow)

# Backported Py3 bytes object
b = bytes(b'ABCD')
assert list(b) == [65, 66, 67, 68]
assert repr(b) == "b'ABCD'"
# These raise TypeErrors:
# b + u'EFGH'
# bytes(b',').join([u'Fred', u'Bill'])

# Backported Py3 str object
s = str(u'ABCD')
assert s != bytes(b'ABCD')
assert isinstance(s.encode('utf-8'), bytes)
assert isinstance(b.decode('utf-8'), str)
assert repr(s) == "'ABCD'"      # consistent repr with Py3 (no u prefix)
# These raise TypeErrors:
# bytes(b'B') in s
# s.find(bytes(b'A'))

# Extra arguments for the open() function
f = open('japanese.txt', encoding='utf-8', errors='replace')

# New simpler super() function:
class VerboseList(list):
    def append(self, item):
        print('Adding an item')
        super().append(item)

# New iterable range object with slicing support
for i in range(10**15)[:10]:
    pass

# Other iterators: map, zip, filter
my_iter = zip(range(3), ['a', 'b', 'c'])
assert my_iter != list(my_iter)

# The round() function behaves as it does in Python 3, using
# "Banker's Rounding" to the nearest even last digit:
assert round(0.1250, 2) == 0.12

# input() replaces Py2's raw_input() (with no eval()):
name = input('What is your name? ')
print('Hello ' + name)

# Compatible output from isinstance() across Py2/3:
assert isinstance(2**64, int)        # long integers
assert isinstance(u'blah', str)
assert isinstance('blah', str)       # only if unicode_literals is in effect

# pow() supports fractional exponents of negative numbers like in Py3:
z = pow(-1, 0.5)

There is also support for renamed standard library modules in the form of import hooks. The context-manager form works like this:

from future import standard_library

with standard_library.hooks():
    from http.client import HttpConnection
    from itertools import filterfalse
    import html.parser
    import queue

Automatic translation

The past package can now automatically translate some simple Python 2 modules to Python 3 upon import. For example, here is how to use a Python 2-only package called plotrique on Python 3. First install it:

$ pip3 install plotrique==0.2.5-7 --no-compile   # to ignore SyntaxErrors

(or use pip if this points to your Py3 environment.)

Then pass a whitelist of module name prefixes to the autotranslate() function. Example:

$ python3

>>> from past import autotranslate
>>> autotranslate(['plotrique'])
>>> import plotrique

This transparently translates and runs the plotrique module and any submodules in the plotrique package that plotrique imports.

This is intended to help you migrate to Python 3 without the need for all your code's dependencies to support Python 3 yet. It should be used as a last resort; ideally Python 2-only dependencies should be ported properly to a Python 2/3 compatible codebase using a tool like futurize and the changes should be pushed to the upstream project.

Note: the translation feature is still in alpha and needs more testing and development to support a full range of real-world Python 2 modules.

Next steps

Check out the Quickstart Guide.

Credits and Licensing

Author:Ed Schofield
Sponsor:Python Charmers Pty Ltd, Australia, and Python Charmers Pte Ltd, Singapore. http://pythoncharmers.com
Others:See Credits.

Copyright 2013-2014 Python Charmers Pty Ltd, Australia.

The software is distributed under an MIT licence. See LICENSE.txt or Licensing.

About

Easy, clean, reliable Python 2/3 compatibility

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Python 100.0%
Morty Proxy This is a proxified and sanitized view of the page, visit original site.