1515 from __future__ import (division, absolute_import, print_function,
1616 unicode_literals)
1717 from future import *
18-
18+
1919followed by clean Python 3 code (with a few restrictions) that can run
20- unchanged on Python 2.7 or Python 3.3. For example::
20+ unchanged on Python 2.7.
21+
22+ On Python 3, the ``from future import *`` line has no effect (i.e. no
23+ namespace pollution.) On Python 2 it shadows builtins to provide the
24+ Python 3 semantics. (See below for the explicit import form.)
2125
22- # New range object with slicing support
26+ For example::
27+
28+ # New iterable range object with slicing support
2329 for i in range(10**11)[:10]:
2430 pass
2531
2632 # Other common iterators: map, reduce, zip
27- iter = zip(range(3), ['a', 'b', 'c'])
28- assert iter != list(iter )
33+ my_iter = zip(range(3), ['a', 'b', 'c'])
34+ assert my_iter != list(my_iter )
2935
3036 # New simpler super() function:
3137 class VerboseList(list):
@@ -39,25 +45,31 @@ def append(self, item):
3945 # This identity is restored. This is normally valid on Py3 and Py2, but
4046 # 'from __future__ import unicode_literals' breaks it on Py2:
4147 assert isinstance('happy', str)
42-
43- See below for more explicit forms of the import line.
44-
45- Another feature offered is support for the standard library
46- reorganization (PEP 3108)::
47-
48+
49+ # The round() function behaves as it does in Python 3, using "Banker's
50+ # Rounding" to the nearest even last digit:
51+ assert round(0.1250, 2) == 0.12
52+
53+ # input() is now safe (no eval()):
54+ name = input('What is your name?\n ')
55+ print('Hello ' + name)
56+
57+ ``future`` also supports the standard library reorganization (PEP 3108)
58+ via import hooks, allowing standard library modules to be accessed under
59+ their Python 3 names and locations::
60+
4861 from future import standard_library_renames
49-
62+
5063 import socketserver
5164 import queue
5265 import configparser
53- # etc.
66+ # and other moved modules
5467
55- and other modules renamed for Python 3.
56-
57- The above * import is equivalent to::
68+ If you prefer explicit imports, the explicit equivalent of the ``from
69+ future import *`` line above is::
5870
5971 from future.common_iterators import zip, map, filter
60- from future.features import range, super
72+ from future.modified_builtins import ( range, super, round, input)
6173 from future.disable_obsolete_builtins import (apply, cmp, coerce,
6274 execfile, file, long, raw_input, reduce, reload, unicode,
6375 xrange, StandardError)
@@ -68,7 +80,7 @@ def append(self, item):
6880
6981- future.standard_library_renames
7082- future.common_iterators
71- - future.features
83+ - future.modified_builtins
7284- future.disable_obsolete_builtins
7385- future.str_as_unicode
7486
@@ -126,9 +138,17 @@ def append(self, item):
126138
127139:Q: Why is there a need for this?
128140
129- :A: To reduce cruft in single-source codebases that support both Python 2
130- and 3.
141+ :A: "Python 2 is the next COBOL." - Alex Gaynor, at PyCon AU 2013
142+
143+ Python 3.3 is a better language and better set of standard libraries
144+ than Python 2.x in almost every way.
131145
146+ ``future`` helps you to take advantage of the cleaner syntax and
147+ semantics of Python 3 code today while still supporting Python 2.
148+
149+ The goal is to encourage writing future-proof code while still
150+ supporting the platform of today.
151+
132152
133153Other compatibility tools
134154-------------------------
@@ -174,25 +194,6 @@ def greet(name):
174194 http://www.youtube.com/watch?v=xNZ4OVO2Z_E.)
175195
176196
177- :Q: What is the relationship between this project and ``python-modernize``?
178-
179- :A: ``python-modernize`` is great, and this project is designed to
180- complement it. For a project wishing to migrate to Python 3,
181- python-modernize is useful for starting the process of cleaning up
182- legacy code idioms which would cause SyntaxErrors on Python 3. The
183- output of ``python-modernize`` should hopefully be a valid common
184- subset of Python 3 and Python 2 that should run under either
185- platform.
186-
187- However, the output of ``python-modernize`` is not clean Python 3
188- code; it requires that code contain various backward-compatibility
189- warts and a runtime dependency on the six module.
190-
191- ``future`` goes further in allowing either the output of
192- ``python-modernize`` or hand-written Python 3 code to run with less
193- work and and less backward-compatible cruft on Python 2.
194-
195-
196197:Q: What is the relationship between this project and ``six``?
197198
198199:A: ``future`` is a higher-level interface that incorporates the ``six``
@@ -201,26 +202,43 @@ def greet(name):
201202 the interface they offer, the Python versions they target, and the
202203 extent of the support they offer for new Python 3 features.
203204
204- Codebases that use ``six`` are sometimes standard Python 3 code,
205- sometimes Python 2 code, and sometimes neither (``six``-specific
206- wrapper interfaces).
205+ Although ``six`` is a remarkable achievement -- making it possible to
206+ write a single-source codebase that runs on both Python 2 and Python
207+ 3 -- codebases that use ``six`` directly tend to be mixtures of
208+ Python 2 code, Python 3 code, and ``six``-specific wrapper
209+ interfaces. In practice it often looks like this::
207210
208- Here is a simple example of code compatible with both Python 2 and
209- Python 3 using ``six``::
211+ from sklearn.externals.six.moves import (cStringIO as StringIO,
212+ xrange)
213+
214+ for i, (k, v) in enumerate(sorted(six.iteritems(params))):
215+ # ...
216+
217+ if six.PY3:
218+ exec(open('setup.py').read(), {'__name__'='__main__'})
219+ else:
220+ execfile('setup.py', {'__name__'='__main__'})
210221
211- from six.moves import xrange
212- for i in xrange(10**10): # non-standard Python 3 code
222+ for i in xrange(10**10): # non-standard Python 3
213223 pass
214224
215- Here is the corresponding example using the ``future`` module::
225+
226+ This is crufty and non-standard Python 3 code that puts a maintenance
227+ burden on the code to support Python 2 indefinitely.
228+
229+ Here is the equivalent code using the ``future`` module::
230+
231+ from future import standard_library_renames, range
232+
233+ for i, (k, v) in enumerate(sorted(params.items())):
234+ # ...
235+
236+ exec(open('setup.py').read(), {'__name__'='__main__'})
216237
217- from future.features import range
218238 for i in range(10**10): # standard Python 3
219239 pass
220240
221- Note that the former introduces the obsolete xrange() back into the
222- codebase in order to offer backward compatibility for Python 2. The
223- latter example is standard Python 3 code, with an import line that
241+ This is standard Python 3 code, with an import line that
224242 has no effect on Python 3.
225243
226244 Another difference is version support: ``future`` supports only
@@ -230,10 +248,25 @@ def greet(name):
230248 functions) are superseded by features introduced in Python 2.6 or
231249 2.7.
232250
233- The final difference is that ``future`` offers some backported features
251+ The final difference is in scope: ``future`` offers more backported features
234252 from Python 3, including the improved no-argument super() function,
235- and the new range object (with slicing support). More backported
236- features will be added in the future.
253+ the new range object (with slicing support), rounding behaviour, etc.
254+ More backported features will be added in the future. This should
255+ reduce the burden on every project to roll its own py3k compatibility
256+ wrapper module.
257+
258+ :Q: What is the relationship between this project and ``python-modernize``?
259+
260+ :A: For a project wishing to migrate to Python 3, python-modernize is
261+ very useful for starting the process of cleaning up legacy code
262+ idioms which would cause SyntaxErrors on Python 3. The output of
263+ ``python-modernize`` should hopefully be a valid common subset of
264+ Python 3 and Python 2 that should run under either platform.
265+
266+ Currently, python-modernize produces code with a run-time dependency
267+ on ``six`` (see above). We will aim to provide an alternative set of
268+ fixes for ``python-modernize`` to produce cleaner Python 3 code using
269+ ``future`` as an alternative depencency to ``six``.
237270
238271
239272:Q: How did the original need for this arise?
@@ -254,7 +287,7 @@ def greet(name):
254287 for at least the next 5 years, one of the promised benefits of Python
255288 3 -- cleaner code with fewer of Python 2's warts -- was difficult to
256289 realise before in practice in a single codebase that supported both
257- versions .
290+ platforms .
258291
259292
260293:Q: Do you support Pypy?
@@ -271,23 +304,35 @@ def greet(name):
271304
272305:A: Yes, we welcome bug reports, tests, and pull requests.
273306
307+
274308"""
275309
276310from __future__ import (division , absolute_import , print_function )
277311
278- from future .common_iterators import *
279- from future .features import *
280- from future .disable_obsolete_builtins import *
281- from future .str_is_unicode import *
312+ from future import six
313+
314+ if not six .PY3 :
315+ from future .common_iterators import (filter , map , zip )
316+ from future .disable_obsolete_builtins import (apply , cmp , coerce ,
317+ execfile , file , long , raw_input , reduce , reload , unicode ,
318+ xrange , StandardError )
319+ from future .modified_builtins import (round , input , range , super )
320+ from future .str_is_unicode import str # not python_2_unicode_compatible
321+
322+ # Only shadow builtins on Py2; no new names
323+ __all__ = ['filter' , 'map' , 'zip' , 'apply' , 'cmp' , 'coerce' , 'execfile' ,
324+ 'file' , 'long' , 'raw_input' , 'reduce' , 'reload' , 'unicode' ,
325+ 'xrange' , 'StandardError' , 'round' , 'input' , 'range' , 'super' ,
326+ 'str' ]
282327
328+ else :
329+ # No namespace pollution on Py3
330+ __all__ = []
283331
284332__ver_major__ = 0
285- __ver_minor__ = 1
333+ __ver_minor__ = 2
286334__ver_patch__ = 0
287335__ver_sub__ = ''
288336__version__ = "%d.%d.%d%s" % (__ver_major__ ,__ver_minor__ ,__ver_patch__ ,__ver_sub__ )
289- VERSION = __version__
290337
291- # __all__ = ['disable_obsolete_builtins', 'common_iterators', 'str_is_unicode',
292- # 'standard_library_renames', 'features']
293338
0 commit comments