Skip to content

Commit 094a417

Browse files
committed
Merge branch 'v0.12.x' of https://github.com/PythonCharmers/python-future into v0.12.x
2 parents 09ad5fb + f55437a commit 094a417

File tree

4 files changed

+60
-66
lines changed

4 files changed

+60
-66
lines changed

README.rst

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ Features
2525
- ``future.builtins`` package provides backports and remappings for 19
2626
builtins with different semantics on Py3 versus Py2
2727

28-
- ``future.standard_library`` package provides backports from the Py3.3
29-
standard library
28+
- ``future.standard_library``, in conjunction with ``future.moves``, provides
29+
support for importing standard library modules under their Python 3 names
3030

31-
- ``future.moves`` package provides support for reorganized standard library
32-
modules (renames from native packages)
31+
- ``future.backports`` package provides backports from the Py3.3
32+
standard library
3333

3434
- ``past.builtins`` package provides forward-ports of Python 2 types and
3535
resurrects some Python 2 builtins (to aid with per-module code migrations)
@@ -108,16 +108,16 @@ these imports as it does on Python 3.3+:
108108
name = input('What is your name? ')
109109
print('Hello ' + name)
110110
111+
# pow() supports fractional exponents of negative numbers like in Py3:
112+
z = pow(-1, 0.5)
113+
111114
# Compatible output from isinstance() across Py2/3:
112115
assert isinstance(2**64, int) # long integers
113116
assert isinstance(u'blah', str)
114117
assert isinstance('blah', str) # only if unicode_literals is in effect
115118
116-
# pow() supports fractional exponents of negative numbers like in Py3:
117-
z = pow(-1, 0.5)
118-
119119
# Py3-style iterators written as new-style classes (subclasses of
120-
# future.builtins.object) are backward compatibile with Py2:
120+
# future.builtins.object) are automatically backward compatible with Py2:
121121
class Upper(object):
122122
def __init__(self, iterable):
123123
self._iter = iter(iterable)
@@ -172,24 +172,38 @@ For example, running ``futurize -w mymodule.py`` turns this Python 2 code:
172172

173173
.. code-block:: python
174174
175-
import ConfigParser
175+
import Queue
176+
from urllib2 import urlopen
176177
177-
class Blah(object):
178-
pass
179-
print 'Hello',
178+
179+
def greet(name):
180+
print 'Hello',
181+
print name
182+
183+
print 'What's your name?',
184+
name = raw_input()
185+
greet(name)
180186
181187
into this code which runs on both Py2 and Py3:
182188

183189
.. code-block:: python
184190
185191
from __future__ import print_function
192+
from future.builtins import input
186193
from future import standard_library
194+
standard_library.install_hooks()
195+
import queue
196+
from urllib.request import urlopen
187197
188-
import configparser
189198
190-
class Blah(object):
191-
pass
192-
print('Hello', end=' ')
199+
def greet(name):
200+
print('Hello', end=' ')
201+
print(name)
202+
203+
print('What's your name?', end=' ')
204+
name = input()
205+
greet(name)
206+
193207
194208
For complex projects, it may be better to divide the porting into two stages.
195209
``futurize`` supports a ``--stage1`` flag for safe changes that modernize the

docs/custom_iterators.rst

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
Custom iterators
44
----------------
55

6-
If you define your own iterators, there is an incompatibility in the special method name
7-
across Py3 and Py2. On Python 3 it is ``__next__``, whereas on Python 2 it is
8-
``next``.
6+
If you define your own iterators, there is an incompatibility in the method name
7+
to retrieve the next item across Py3 and Py2. On Python 3 it is ``__next__``,
8+
whereas on Python 2 it is ``next``.
99

1010
The most elegant solution to this is to derive your custom iterator class from
11-
``future.builtins.object``. This provides a special fallback ``next`` method
12-
that maps to ``__next__``. Use it as follows::
11+
``future.builtins.object`` and define a ``__next__`` method as you normally
12+
would on Python 3. On Python 2, ``object`` then refers to the
13+
``future.types.newobject`` base class, which provides a fallback ``next``
14+
method that calls your ``__next__``. Use it as follows::
1315

1416
from future.builtins import object
1517
@@ -27,11 +29,12 @@ that maps to ``__next__``. Use it as follows::
2729
assert list(itr) == list('LLO')
2830

2931

30-
This works unless you are defining a subclass of a base class defined elsewhere
31-
that does not derive from ``future.builtins.object``.
32+
You can use this approach unless you are defining a custom iterator as a
33+
subclass of a base class defined elsewhere that does not derive from
34+
``future.builtins.object``. In that case, you can provide compatibility across
35+
Python 2 and Python 3 using the ``next`` function from ``future.builtins``::
3236

33-
In this case, you can provide compatibility across Python 2 and Python 3 using the ``next``
34-
function in ``future.builtins``::
37+
from future.builtins import next
3538

3639
from some_module import some_base_class
3740

@@ -43,8 +46,6 @@ function in ``future.builtins``::
4346
def __iter__(self):
4447
return self
4548

46-
from future.builtins import next
47-
4849
itr2 = Upper2('hello')
4950
assert next(itr2) == 'H'
5051
assert next(itr2) == 'E'
@@ -55,17 +56,17 @@ function in ``future.builtins``::
5556
assert 'next' in dir(itr3)
5657
assert next(itr3) == 'one'
5758

58-
This works whenever your code calls the ``next()`` function explicitly. If you
59-
consume the iterator implicitly in a ``for`` loop or ``list()`` call or by some
60-
other method, the ``future.builtins.next`` function will not help; the third
61-
assertion below would fail on Python 2::
59+
This approach is feasible whenever your code calls the ``next()`` function
60+
explicitly. If you consume the iterator implicitly in a ``for`` loop or
61+
``list()`` call or by some other means, the ``future.builtins.next`` function
62+
will not help; the third assertion below would fail on Python 2::
6263

6364
itr2 = Upper2('hello')
6465

6566
assert next(itr2) == 'H'
6667
assert next(itr2) == 'E'
6768
assert list(itr2) == list('LLO') # fails because Py2 implicitly looks
68-
# for a ``__next__`` method.
69+
# for a ``next`` method.
6970

7071
Instead, you can use a decorator called ``implements_iterator`` from
7172
``future.utils`` to allow Py3-style iterators to work identically on Py2, even

docs/quickstart.rst

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ See :ref:`backwards-conversion` for more details.
6565
To convert existing Python 2 code
6666
---------------------------------
6767

68-
Start with the :ref:`automatic-conversion` page.
68+
Start with this page: :ref:`automatic-conversion`.
6969

7070
.. If you already know Python 3, start with the :ref:`automatic-conversion` page.
7171
.. If you don't know Python 3 yet, start with :ref:`python3-essentials`.
@@ -77,7 +77,7 @@ Standard library reorganization
7777
-------------------------------
7878

7979
:mod:`future` supports the standard library reorganization (PEP 3108)
80-
via import hooks, allowing almost all moved standard library modules to
80+
via import hooks, allowing most moved standard library modules to
8181
be accessed under their Python 3 names and locations in Python 2::
8282
8383
from future import standard_library
@@ -107,28 +107,6 @@ be accessed under their Python 3 names and locations in Python 2::
107107
import xmlrpc.client
108108
import xmlrpc.server
109109

110-
.. ``urllib`` currently requires an explicit import because the name clashes with
111-
.. that on Python 2 and because Python's syntax does not allow imports of this
112-
.. form with a dotted module name after ``as``::
113-
..
114-
.. import future.moves.urllib.parse as urllib.parse
115-
..
116-
.. For submodules of ``urllib`` and other packages (like ``http``), this
117-
.. alternative form is available::
118-
..
119-
.. from future.standard_library import import_
120-
..
121-
.. urllib = import_('urllib')
122-
.. import_('urllib.parse')
123-
.. import_('urllib.request')
124-
.. import_('urllib.error')
125-
..
126-
.. response = urllib.request.urlopen('http://mywebsite.com')
127-
.. # etc.
128-
..
129-
.. For an explanation of these and other forms of imports from the standard
130-
.. library, see :ref:`standard-library-imports`.
131-
132110

133111
.. _py2-dependencies:
134112

docs/whatsnew.rst

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ The major new feature in this version is improvements in the support for the
1010
reorganized standard library (PEP 3108) and compatibility of the import
1111
mechanism with 3rd-party modules.
1212

13-
Standard-library import hooks now require explicit installation
14-
---------------------------------------------------------------
13+
More robust standard-library import hooks
14+
-----------------------------------------
1515

1616
**Note: backwards-incompatible change:** As previously announced (see
1717
:ref:`deprecated-auto-import-hooks`), the import hooks must now be enabled
@@ -40,7 +40,7 @@ backwards compatibility::
4040
...
4141
standard_library.remove_hooks()
4242

43-
Requiring explicit installation of import hooks allows finer-grained control
43+
Explicit installation of import hooks allows finer-grained control
4444
over whether they are enabled for other imported modules that provide their own
4545
Python 2/3 compatibility layer. This also improves compatibility of ``future``
4646
with tools like ``py2exe``.
@@ -49,11 +49,12 @@ with tools like ``py2exe``.
4949
``newobject`` base object defines fallback Py2-compatible special methods
5050
-------------------------------------------------------------------------
5151

52-
There is a new ``future.builtins.object`` base class that can streamline Py3/2
53-
compatible code by providing fallback Py2-compatible special methods for its
54-
subclasses. It currently provides ``next()`` and ``__nonzero__()`` as fallback
55-
methods on Py2 when its subclasses define the corresponding Py3-style
56-
``__next__()`` and ``__bool__()`` methods.
52+
There is a new ``future.types.newobject`` base class (available as
53+
``future.builtins.object``) that can streamline Py3/2 compatible code by
54+
providing fallback Py2-compatible special methods for its subclasses. It
55+
currently provides ``next()`` and ``__nonzero__()`` as fallback methods on Py2
56+
when its subclasses define the corresponding Py3-style ``__next__()`` and
57+
``__bool__()`` methods.
5758

5859
This obviates the need to add certain compatibility hacks or decorators to the
5960
code such as the ``@implements_iterator`` decorator for classes that define a
@@ -75,15 +76,15 @@ to ``__next__``::
7576

7677
assert list(Upper('hello')) == list('HELLO')
7778

78-
``future.builtins.object`` defines other Py2-compatible special methods similarly:
79+
``newobject`` defines other Py2-compatible special methods similarly:
7980
currently these include ``__nonzero__`` (mapped to ``__bool__``) and
8081
``__long__`` (mapped to ``__int__``).
8182

8283
Inheriting from ``newobject`` on Python 2 is safe even if your class defines
8384
its own Python 2-style ``__nonzero__`` and ``next`` and ``__long__`` methods.
8485
Your custom methods will simply override those on the base class.
8586

86-
On Python 3, as usual, ``object`` simply refers to ``builtins.object``.
87+
On Python 3, as usual, ``future.builtins.object`` simply refers to ``builtins.object``.
8788

8889

8990
``past.builtins`` module improved

0 commit comments

Comments
 (0)