- Notifications
You must be signed in to change notification settings - Fork293
Easy, clean, reliable Python 2/3 compatibility
License
PythonCharmers/python-future
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
python-future
is the missing compatibility layer between Python 2 andPython 3. It allows you to use a single, clean Python 3.x-compatiblecodebase to support both Python 2 and Python 3 with minimal overhead.
It providesfuture
andpast
packages with backports and forwardports of features from Python 3 and 2. It also comes withfuturize
andpasteurize
, customized 2to3-based scripts that helps you to converteither Py2 or Py3 code easily to support both Python 2 and 3 in a singleclean Py3-style codebase, module by module.
Thepython-future
project has been downloaded over 1.7 billion times.
Thepython-future
project was created in 2013 to attempt to save Python fromthe schism of version incompatibility that was threatening to tear apart thelanguage (as Perl 6 contributed to the death of Perl).
That time is now past. Thanks to a huge porting effort across the Pythoncommunity, Python 3 eventually thrived. Python 2 reached its end of life in2020 and thepython-future
package should no longer be necessary. Use it tohelp with porting legacy code to Python 3 but don't depend on it for new code.
future.builtins
package (also available asbuiltins
on Py2) providesbackports and remappings for 20 builtins with different semantics on Py3versus Py2- support for directly importing 30 standard library modules undertheir Python 3 names on Py2
- support for importing the other 14 refactored standard library modulesunder their Py3 names relatively cleanly via
future.standard_library
andfuture.moves
past.builtins
package provides forward-ports of 19 Python 2 types andbuiltin functions. These can aid with per-module code migrations.past.translation
package supports transparent translation of Python 2modules to Python 3 upon import. [This feature is currently in alpha.]- 1000+ unit tests, including many from the Py3.3 source tree.
futurize
andpasteurize
scripts based on2to3
and parts of3to2
andpython-modernize
, for automatic conversion from either Py2or Py3 to a clean single-source codebase compatible with Python 2.6+ andPython 3.3+.- a curated set of utility functions and decorators in
future.utils
andpast.utils
selected from Py2/3 compatibility interfaces from projectslikesix
,IPython
,Jinja2
,Django
, andPandas
. - support for the
surrogateescape
error handler when encoding anddecoding the backportedstr
andbytes
objects. [This feature iscurrently in alpha.] - support for pre-commit hooks
Replacements for Py2's built-in functions and types are designed to be importedat 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 afterthese imports as it does on Python 3.3+:
from __future__importabsolute_import,division,print_functionfrombuiltinsimport (bytes,str,open,super,range,zip,round,input,int,pow,object)# Backported Py3 bytes objectb=bytes(b'ABCD')assertlist(b)== [65,66,67,68]assertrepr(b)=="b'ABCD'"# These raise TypeErrors:# b + u'EFGH'# bytes(b',').join([u'Fred', u'Bill'])# Backported Py3 str objects=str(u'ABCD')asserts!=bytes(b'ABCD')assertisinstance(s.encode('utf-8'),bytes)assertisinstance(b.decode('utf-8'),str)assertrepr(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() functionf=open('japanese.txt',encoding='utf-8',errors='replace')# New zero-argument super() function:classVerboseList(list):defappend(self,item):print('Adding an item')super().append(item)# New iterable range object with slicing supportforiinrange(10**15)[:10]:pass# Other iterators: map, zip, filtermy_iter=zip(range(3), ['a','b','c'])assertmy_iter!=list(my_iter)# The round() function behaves as it does in Python 3, using# "Banker's Rounding" to the nearest even last digit:assertround(0.1250,2)==0.12# input() replaces Py2's raw_input() (with no eval()):name=input('What is your name? ')print('Hello '+name)# pow() supports fractional exponents of negative numbers like in Py3:z=pow(-1,0.5)# Compatible output from isinstance() across Py2/3:assertisinstance(2**64,int)# long integersassertisinstance(u'blah',str)assertisinstance('blah',str)# only if unicode_literals is in effect# Py3-style iterators written as new-style classes (subclasses of# future.types.newobject) are automatically backward compatible with Py2:classUpper(object):def__init__(self,iterable):self._iter=iter(iterable)def__next__(self):# note the Py3 interfacereturnnext(self._iter).upper()def__iter__(self):returnselfassertlist(Upper('hello'))==list('HELLO')
There is also support for renamed standard library modules. The recommendedinterface works like this:
# Many Py3 module names are supported directly on both Py2.x and 3.x:fromhttp.clientimportHttpConnectionimporthtml.parserimportqueueimportxmlrpc.client# Refactored modules with clashing names on Py2 and Py3 are supported# as follows:fromfutureimportstandard_librarystandard_library.install_aliases()# Then, for example:fromitertoolsimportfilterfalse,zip_longestfromurllib.requestimporturlopenfromcollectionsimportChainMapfromcollectionsimportUserDict,UserList,UserStringfromsubprocessimportgetoutput,getstatusoutputfromcollectionsimportCounter,OrderedDict# backported to Py2.6
python-future
comes with two scripts calledfuturize
andpasteurize
to aid in making Python 2 code or Python 3 code compatible withboth platforms (Py2/3). It is based on 2to3 and uses fixers fromlib2to3
,lib3to2
, andpython-modernize
, as well as custom fixers.
futurize
passes Python 2 code through all the appropriate fixers to turn itinto valid Python 3 code, and then adds__future__
andfuture
packageimports so that it also runs under Python 2.
For conversions from Python 3 code to Py2/3, use thepasteurize
scriptinstead. This converts Py3-only constructs (e.g. new metaclass syntax) toPy2/3 compatible constructs and adds__future__
andfuture
imports tothe top of each module.
In both cases, the result should be relatively clean Py3-style code that runsmostly unchanged on both Python 2 and Python 3.
For example, runningfuturize -w mymodule.py
turns this Python 2 code:
importQueuefromurllib2importurlopendefgreet(name):print'Hello',printnameprint"What's your name?",name=raw_input()greet(name)
into this code which runs on both Py2 and Py3:
from __future__importprint_functionfromfutureimportstandard_librarystandard_library.install_aliases()frombuiltinsimportinputimportqueuefromurllib.requestimporturlopendefgreet(name):print('Hello',end=' ')print(name)print("What's your name?",end=' ')name=input()greet(name)
The first four lines have no effect under Python 3 and can be removed fromthe codebase when Python 2 compatibility is no longer required.
See:ref:`forwards-conversion` and:ref:`backwards-conversion` for more details.
Thepast
package can automatically translate some simple Python 2modules to Python 3 upon import. The goal is to support the "long tail" ofreal-world Python 2 modules (e.g. on PyPI) that have not been ported yet. Forexample, here is how to use a Python 2-only package calledplotrique
onPython 3. First install it:
$ pip3 install plotrique==0.2.5-7 --no-compile# to ignore SyntaxErrors
(or usepip
if this points to your Py3 environment.)
Then pass a whitelist of module name prefixes to theautotranslate()
function.Example:
$ python3>>> from past.translation import autotranslate>>> autotranslate(['plotrique'])>>> import plotrique
This transparently translates and runs theplotrique
module and anysubmodules in theplotrique
package thatplotrique
imports.
This is intended to help you migrate to Python 3 without the need for allyour code's dependencies to support Python 3 yet. It should be used as alast resort; ideally Python 2-only dependencies should be portedproperly to a Python 2/3 compatible codebase using a tool likefuturize
and the changes should be pushed to the upstream project.
Note: the auto-translation feature is still in alpha; it needs more testing anddevelopment, and will likely never be perfect.
Pre-commit is a framework for managing and maintainingmulti-language pre-commit hooks.
In case you need to port your project from Python 2 to Python 3, you might considerusing such hook during the transition period.
First:
$ pip install pre-commit
and then in your project's directory:
$ pre-commit install
Next, you need to add this entry to your.pre-commit-config.yaml
-repo:https://github.com/PythonCharmers/python-futurerev:masterhooks: -id:futurizeargs:[--both-stages]
Theargs
part is optional, by default only stage1 is applied.
Author: | Ed Schofield, Jordan M. Adler, et al |
---|---|
Copyright: | 2013-2024 Python Charmers, Australia. |
Sponsors: | Python Charmers:https://pythoncharmers.com Pinteresthttps://opensource.pinterest.com |
Licence: | MIT. See |
Other credits: | Seehere. |
See the docshere.
If you are new to Python-Future, check out theQuickstart Guide.
For an update on changes in the latest version, see theWhat's New page.
About
Easy, clean, reliable Python 2/3 compatibility
Resources
License
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.