Changes in the most recent major version are here: What’s New.
This is a bug-fix release:
This is mostly a clean-up release. It adds some small new compatibility features and fixes several bugs.
The following unused internal modules are now deprecated. They will be removed in a future release:
(Issue #80). See here for the rationale for unbundling them.
Add “official Python 3.4 support”: Py3.4 is now listed among the PyPI Trove classifiers and the tests now run successfully on Py3.4 (issue #67).
Add backports of collections.OrderedDict and collections.Counter for Python 2.6 (issue #52).
Add --version option for futurize and pasteurize scripts (issue #57).
Fix future.utils.ensure_new_type with long input (issue #65).
Remove some false alarms on checks for ambiguous fixer names with futurize -f ....
The major new feature in this version is improvements in the support for the reorganized standard library (PEP 3108) and compatibility of the import mechanism with 3rd-party modules.
Note: backwards-incompatible change: As previously announced (see Deprecated feature: auto-installation of standard-library import hooks), the import hooks must now be enabled explicitly, as follows:
from future import standard_library
with standard_library.hooks():
import html.parser
import http.client
...
This now causes these modules to be imported from future.moves, a new package that provides wrappers over the native Python 2 standard library with the new Python 3 organization. As a consequence, the import hooks provided in future.standard_library are now fully compatible with the Requests library.
The functional interface with install_hooks() is still supported for backwards compatibility:
from future import standard_library
standard_library.install_hooks():
import html.parser
import http.client
...
standard_library.remove_hooks()
Explicit installation of import hooks allows finer-grained control over whether they are enabled for other imported modules that provide their own Python 2/3 compatibility layer. This also improves compatibility of future with tools like py2exe.
There is a new future.types.newobject base class (available as future.builtins.object) that can streamline Py2/3 compatible code by providing fallback Py2-compatible special methods for its subclasses. It currently provides next() and __nonzero__() as fallback methods on Py2 when its subclasses define the corresponding Py3-style __next__() and __bool__() methods.
This obviates the need to add certain compatibility hacks or decorators to the code such as the @implements_iterator decorator for classes that define a Py3-style __next__ method.
In this example, the code defines a Py3-style iterator with a __next__ method. The object class defines a next method for Python 2 that maps to __next__:
from future.builtins import object
class Upper(object):
def __init__(self, iterable):
self._iter = iter(iterable)
def __next__(self): # note the Py3 interface
return next(self._iter).upper()
def __iter__(self):
return self
assert list(Upper('hello')) == list('HELLO')
newobject defines other Py2-compatible special methods similarly: currently these include __nonzero__ (mapped to __bool__) and __long__ (mapped to __int__).
Inheriting from newobject on Python 2 is safe even if your class defines its own Python 2-style __nonzero__ and next and __long__ methods. Your custom methods will simply override those on the base class.
On Python 3, as usual, future.builtins.object simply refers to builtins.object.
The past.builtins module is much more compatible with the corresponding builtins on Python 2; many more of the Py2 unit tests pass on Py3. For example, functions like map() and filter() now behave as they do on Py2 with with None as the first argument.
The past.builtins module has also been extended to add Py3 support for additional Py2 constructs that are not adequately handled by lib2to3 (see issue #37). This includes new execfile() and cmp() functions. futurize now invokes imports of these functions from past.builtins.
The newstr type (future.builtins.str) now supports a backport of the Py3.x 'surrogateescape' error handler for preserving high-bit characters when encoding and decoding strings with unknown encodings.
There is a new list type in future.builtins that offers .copy() and .clear() methods like the list type in Python 3.
future.utils now contains helper functions listvalues and listitems, which provide Python 2-style list snapshotting semantics for dictionaries in both Python 2 and Python 3.
These came out of the discussion around Nick Coghlan’s now-withdrawn PEP 469.
There is no corresponding listkeys(d) function. Use list(d) for this case.
The number of unit tests has increased from 600 to over 800. Most of the new tests come from Python 3.3’s test suite.
The backported standard library modules have been moved to future.backports to make the distinction clearer between these and the new future.moves package.
Alpha versions of backports of the http.server and urllib module from Python 3.3’s standard library are now provided in future.backports.
Use them like this:
from future.backports.urllib.request import Request # etc.
from future.backports.http import server as http_server
or with this new interface:
from future.standard_library import import_, from_import
Request = from_import('urllib.request', 'Request', backport=True)
http = import_('http.server', backport=True)
The future.builtins.types module has been moved to future.types. Likewise, past.builtins.types has been moved to past.types. The only user-visible effect of this is to change repr(type(obj)) for instances of these types. For example:
>>> from future.builtins import bytes
>>> bytes(b'abc')
>>> type(b)
future.types.newbytes.newbytes
instead of:
>>> type(b) # prior to v0.12
future.builtins.types.newbytes.newbytes
Many small improvements and fixes have been made across the project. Some highlights are:
This release contains various small improvements and fixes:
This release has improvements in the standard library import hooks mechanism and its compatibility with 3rd-party modules:
The __exit__ function of the hooks context manager and the remove_hooks function both now remove submodules of future.standard_library from the sys.modules cache. Therefore this code is now possible on Python 2 and 3:
from future import standard_library
standard_library.install_hooks()
import http.client
standard_library.remove_hooks()
import requests
data = requests.get('http://www.google.com')
Previously, this required manually removing http and http.client from sys.modules before importing requests on Python 2.x. (Issue #19).
This change should also improve the compatibility of the standard library hooks with any other module that provides its own Python 2/3 compatibility code.
Note that the situation will improve further in version 0.12; import hooks will require an explicit function call or the hooks context manager.
The futurize and pasteurize scripts now add an explicit call to install_hooks() to install the standard library import hooks. These scripts now add these two lines:
from future import standard_library
standard_library.install_hooks()
instead of just the first one. The next major version of future (0.12) will require the explicit call or use of the hooks context manager. This will allow finer-grained control over whether import hooks are enabled for other imported modules, such as requests, which provide their own Python 2/3 compatibility code.
There is a new --unicode-literals flag to futurize that adds the import:
from __future__ import unicode_literals
to the top of each converted module. Without this flag, futurize now no longer adds this import. (Issue #22).
The pasteurize script for converting from Py3 to Py2/3 still adds unicode_literals. (See the comments in issue #22 for an explanation.)
There are several major new features in version 0.11.
The python-future project now provides a past package in addition to the future package. Whereas future provides improved compatibility with Python 3 code to Python 2, past provides support for using and interacting with Python 2 code from Python 3. The structure reflects that of future, with past.builtins and past.utils. There is also a new past.translation package that provides transparent translation of Python 2 code to Python 3. (See below.)
One purpose of past is to ease module-by-module upgrades to codebases from Python 2. Another is to help with enabling Python 2 libraries to support Python 3 without breaking the API they currently provide. (For example, user code may expect these libraries to pass them Python 2’s 8-bit strings, rather than Python 3’s bytes object.) A third purpose is to help migrate projects to Python 3 even if one or more dependencies are still on Python 2.
Currently past.builtins provides forward-ports of Python 2’s str and dict objects, basestring, and list-producing iterator functions. In later releases, past.builtins will be used internally by the past.translation package to help with importing and using old Python 2 modules in a Python 3 environment.
past provides an experimental translation package to help with importing and using old Python 2 modules in a Python 3 environment.
This is implemented using import hooks that attempt to automatically translate Python 2 modules to Python 3 syntax and semantics upon import. Use it like this:
$ 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.autotranslate() function. Example:
>>> from past import autotranslate
>>> autotranslate(['plotrique'])
>>> import plotrique
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.
For more information, see Using Python 2-only dependencies on Python 3.
The functionality from futurize --from3 is now in a separate script called pasteurize. Use pasteurize when converting from Python 3 code to Python 2/3 compatible source. For more information, see pasteurize: Py3 to Py2/3.
There is now a pow() function in future.builtins.misc that behaves like the Python 3 pow() function when raising a negative number to a fractional power (returning a complex number).
Previous versions of future deleted the input() function from __builtin__ on Python 2 as a security measure. This was because Python 2’s input() function allows arbitrary code execution and could present a security vulnerability on Python 2 if someone expects Python 3 semantics but forgets to import input from future.builtins. This behaviour has been reverted, in the interests of broadening the compatibility of future with other Python 2 modules.
Please remember to import input from future.builtins if you use input() in a Python 2/3 compatible codebase.
Previous versions of python-future installed import hooks automatically upon importing the standard_library module from future. This has been deprecated in order to improve robustness and compatibility with modules like requests that already perform their own single-source Python 2/3 compatibility.
As of v0.12 of python-future, importing future.standard_library will no longer install import hooks by default. Instead, please install the import hooks explicitly as follows:
from future import standard_library
standard_library.install_hooks()
and uninstall them after your import statements using:
standard_library.remove_hooks()
Note: this will be a backward-incompatible change.
The internal future.builtins.backports module has been renamed to future.builtins.types. This will change the repr of future types but not their use.
There is a new context manager future.standard_library.hooks. Use it like this:
from future import standard_library
with standard_library.hooks():
import queue
import configserver
from http.client import HTTPConnection
# etc.
If not using this context manager, it is now encouraged to add an explicit call to standard_library.install_hooks() as follows:
from future import standard_library
standard_library.install_hooks()
import queue
import html
import http.client
# etc.
and to remove the hooks afterwards with:
standard_library.remove_hooks()
The functions install_hooks() and remove_hooks() were previously called enable_hooks() and disable_hooks(). The old names are still available as aliases, but are deprecated.
As usual, this feature has no effect on Python 3.
future.builtins now provides a Python 2 dict subclass whose keys(), values(), and items() methods produce memory-efficient iterators. On Python 2.7, these also have the same set-like view behaviour as on Python 3. This can streamline code needing to iterate over large dictionaries. For example:
from __future__ import print_function
from future.builtins import dict, range
squares = dict({i: i**2 for i in range(10**7)})
assert not isinstance(d.items(), list)
# Because items() is memory-efficient, so is this:
square_roots = dict((i_squared, i) for (i, i_squared) in squares.items())
For more information, see dict.
The functions raise_with_traceback() and raise_() were added to future.utils to offer either the Python 3.x or Python 2.x behaviour for raising exceptions. Thanks to Joel Tratner for the contribution of these. future.utils.reraise() is now deprecated.
A portable exec_() function has been added to future.utils from six.
The isinstance function is no longer redefined in future.builtins to operate with the backported int, bytes and str. isinstance checks with the backported types now work correctly by default; we achieve this through overriding the __instancecheck__ method of metaclasses of the backported types.
For more information, see isinstance.
By default, the futurize script now only adds the minimal set of imports deemed necessary.
There is now an --all-imports option to the futurize script which gives the previous behaviour, which is to add all __future__ imports and from future.builtins import * imports to every module. (This even applies to an empty __init__.py file.)
Now the future.builtins.str object behaves more like the Python 2 unicode object with regard to type-checking. This is to work around some bugs / sloppiness in the Python 2 standard library involving mixing of byte-strings and unicode strings, such as os.path.join in posixpath.py.
future.builtins.str still raises the expected TypeError exceptions from Python 3 when attempting to mix it with future.builtins.bytes.
Pychecker (as of v0.6.1)’s checker.py attempts to import the builtins module as a way of determining whether Python 3 is running. Since this succeeds when from future import standard_library is in effect, this check does not work and pychecker sets the wrong value for its internal PY2 flag is set.
To work around this, future now provides a context manager called suspend_hooks that can be used as follows:
from future import standard_library
...
with standard_library.suspend_hooks():
from pychecker.checker import Checker
future now includes support for Python 2.6.
To run the future test suite on Python 2.6, this additional package is needed:
pip install unittest2
http.server also requires the argparse package:
pip install argparse
The future.six module has been removed. future doesn’t require six (and hasn’t since version 0.3). If you need support for Python versions before 2.6, six is the best option. future and six can be installed alongside each other easily if needed.
The unused hacks module has also been removed from the source tree.
It is now possible to use isinstance() calls normally after importing isinstance from future.builtins. On Python 2, this is specially defined to be compatible with future‘s backported int, str, and bytes types, as well as handling Python 2’s int/long distinction.
The result is that code that uses isinstance to perform type-checking of ints, strings, and bytes should now work identically on Python 2 as on Python 3.
The utility functions isint, istext, and isbytes provided before for compatible type-checking across Python 2 and 3 in future.utils are now deprecated.
Features module renamed to modified_builtins
No more namespace pollution as a policy:
from future import *
should have no effect on Python 3. On Python 2, it only shadows the builtins; it doesn’t introduce any new names.
End-to-end tests with Python 2 code and 2to3 now work