PEP 3114: rename .next() to .__next__() and add next() builtin.

This commit is contained in:
Georg Brandl 2007-04-21 15:47:16 +00:00
parent 4d2adcca52
commit a18af4e7a2
83 changed files with 495 additions and 425 deletions

View file

@ -1071,7 +1071,7 @@ The next two fields only exist if the
iterator, or raises \exception{StopIteration} when the iterator is iterator, or raises \exception{StopIteration} when the iterator is
exhausted. Its presence normally signals that the instances of this exhausted. Its presence normally signals that the instances of this
type are iterators (although classic instances always have this type are iterators (although classic instances always have this
function, even if they don't define a \method{next()} method). function, even if they don't define a \method{__next__()} method).
Iterator types should also define the \member{tp_iter} function, and Iterator types should also define the \member{tp_iter} function, and
that function should return the iterator instance itself (not a new that function should return the iterator instance itself (not a new

View file

@ -199,11 +199,13 @@ foundation for writing functional-style programs: iterators.
An iterator is an object representing a stream of data; this object An iterator is an object representing a stream of data; this object
returns the data one element at a time. A Python iterator must returns the data one element at a time. A Python iterator must
support a method called ``next()`` that takes no arguments and always support a method called ``__next__()`` that takes no arguments and always
returns the next element of the stream. If there are no more elements returns the next element of the stream. If there are no more elements
in the stream, ``next()`` must raise the ``StopIteration`` exception. in the stream, ``__next__()`` must raise the ``StopIteration`` exception.
Iterators don't have to be finite, though; it's perfectly reasonable Iterators don't have to be finite, though; it's perfectly reasonable
to write an iterator that produces an infinite stream of data. to write an iterator that produces an infinite stream of data.
The built-in ``next()`` function is normally used to call the iterator's
``__next__()`` method.
The built-in ``iter()`` function takes an arbitrary object and tries The built-in ``iter()`` function takes an arbitrary object and tries
to return an iterator that will return the object's contents or to return an iterator that will return the object's contents or
@ -218,13 +220,13 @@ You can experiment with the iteration interface manually::
>>> it = iter(L) >>> it = iter(L)
>>> print it >>> print it
<iterator object at 0x8116870> <iterator object at 0x8116870>
>>> it.next() >>> next(it)
1 1
>>> it.next() >>> next(it)
2 2
>>> it.next() >>> next(it)
3 3
>>> it.next() >>> next(it)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
StopIteration StopIteration
@ -271,7 +273,7 @@ won't return either.
Note that you can only go forward in an iterator; there's no way to Note that you can only go forward in an iterator; there's no way to
get the previous element, reset the iterator, or make a copy of it. get the previous element, reset the iterator, or make a copy of it.
Iterator objects can optionally provide these additional capabilities, Iterator objects can optionally provide these additional capabilities,
but the iterator protocol only specifies the ``next()`` method. but the iterator protocol only specifies the ``__next__()`` method.
Functions may therefore consume all of the iterator's output, and if Functions may therefore consume all of the iterator's output, and if
you need to do something different with the same stream, you'll have you need to do something different with the same stream, you'll have
to create a new iterator. to create a new iterator.
@ -485,7 +487,7 @@ outputs the value of ``i``, similar to a ``return``
statement. The big difference between ``yield`` and a statement. The big difference between ``yield`` and a
``return`` statement is that on reaching a ``yield`` the ``return`` statement is that on reaching a ``yield`` the
generator's state of execution is suspended and local variables are generator's state of execution is suspended and local variables are
preserved. On the next call to the generator's ``.next()`` method, preserved. On the next call ``next(generator)``,
the function will resume executing. the function will resume executing.
Here's a sample usage of the ``generate_ints()`` generator:: Here's a sample usage of the ``generate_ints()`` generator::
@ -493,13 +495,13 @@ Here's a sample usage of the ``generate_ints()`` generator::
>>> gen = generate_ints(3) >>> gen = generate_ints(3)
>>> gen >>> gen
<generator object at 0x8117f90> <generator object at 0x8117f90>
>>> gen.next() >>> next(gen)
0 0
>>> gen.next() >>> next(gen)
1 1
>>> gen.next() >>> next(gen)
2 2
>>> gen.next() >>> next(gen)
Traceback (most recent call last): Traceback (most recent call last):
File "stdin", line 1, in ? File "stdin", line 1, in ?
File "stdin", line 2, in generate_ints File "stdin", line 2, in generate_ints
@ -521,7 +523,7 @@ You could achieve the effect of generators manually by writing your
own class and storing all the local variables of the generator as own class and storing all the local variables of the generator as
instance variables. For example, returning a list of integers could instance variables. For example, returning a list of integers could
be done by setting ``self.count`` to 0, and having the be done by setting ``self.count`` to 0, and having the
``next()`` method increment ``self.count`` and return it. ``__next__()`` method increment ``self.count`` and return it.
However, for a moderately complicated generator, writing a However, for a moderately complicated generator, writing a
corresponding class can be much messier. corresponding class can be much messier.
@ -583,7 +585,7 @@ use parentheses when there's an operation, as in ``val = (yield i)
Values are sent into a generator by calling its Values are sent into a generator by calling its
``send(value)`` method. This method resumes the ``send(value)`` method. This method resumes the
generator's code and the ``yield`` expression returns the specified generator's code and the ``yield`` expression returns the specified
value. If the regular ``next()`` method is called, the value. If the regular ``__next__()`` method is called, the
``yield`` returns ``None``. ``yield`` returns ``None``.
Here's a simple counter that increments by 1 and allows changing the Here's a simple counter that increments by 1 and allows changing the
@ -604,18 +606,18 @@ value of the internal counter.
And here's an example of changing the counter: And here's an example of changing the counter:
>>> it = counter(10) >>> it = counter(10)
>>> print it.next() >>> print next(it)
0 0
>>> print it.next() >>> print next(it)
1 1
>>> print it.send(8) >>> print it.send(8)
8 8
>>> print it.next() >>> print next(it)
9 9
>>> print it.next() >>> print next(it)
Traceback (most recent call last): Traceback (most recent call last):
File ``t.py'', line 15, in ? File ``t.py'', line 15, in ?
print it.next() print next(it)
StopIteration StopIteration
Because ``yield`` will often be returning ``None``, you Because ``yield`` will often be returning ``None``, you

View file

@ -174,7 +174,7 @@ def roundrobin(*iterables):
while pending: while pending:
task = pending.popleft() task = pending.popleft()
try: try:
yield task.next() yield next(task)
except StopIteration: except StopIteration:
continue continue
pending.append(task) pending.append(task)
@ -315,12 +315,12 @@ letter.
The function \function{int()} which always returns zero is just a special The function \function{int()} which always returns zero is just a special
case of constant functions. A faster and more flexible way to create case of constant functions. A faster and more flexible way to create
constant functions is to use \function{itertools.repeat()} which can supply constant functions is to use a lambda function which can supply
any constant value (not just zero): any constant value (not just zero):
\begin{verbatim} \begin{verbatim}
>>> def constant_factory(value): >>> def constant_factory(value):
... return itertools.repeat(value).next ... return lambda: value
>>> d = defaultdict(constant_factory('<missing>')) >>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran') >>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d >>> '%(name)s %(action)s to %(object)s' % d

View file

@ -487,8 +487,8 @@ class UTF8Recoder:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
return self.reader.next().encode("utf-8") return next(self.reader).encode("utf-8")
class UnicodeReader: class UnicodeReader:
""" """
@ -500,8 +500,8 @@ class UnicodeReader:
f = UTF8Recoder(f, encoding) f = UTF8Recoder(f, encoding)
self.reader = csv.reader(f, dialect=dialect, **kwds) self.reader = csv.reader(f, dialect=dialect, **kwds)
def next(self): def __next__(self):
row = self.reader.next() row = next(self.reader)
return [unicode(s, "utf-8") for s in row] return [unicode(s, "utf-8") for s in row]
def __iter__(self): def __iter__(self):

View file

@ -529,10 +529,10 @@ Set byte code counter to \var{target}.
\end{opcodedesc} \end{opcodedesc}
\begin{opcodedesc}{FOR_ITER}{delta} \begin{opcodedesc}{FOR_ITER}{delta}
\code{TOS} is an iterator. Call its \method{next()} method. If this \code{TOS} is an iterator. Call its \method{__next__()} method. If this
yields a new value, push it on the stack (leaving the iterator below yields a new value, push it on the stack (leaving the iterator below it). If
it). If the iterator indicates it is exhausted \code{TOS} is the iterator indicates it is exhausted \code{TOS} is popped, and the byte code
popped, and the byte code counter is incremented by \var{delta}. counter is incremented by \var{delta}.
\end{opcodedesc} \end{opcodedesc}
%\begin{opcodedesc}{FOR_LOOP}{delta} %\begin{opcodedesc}{FOR_LOOP}{delta}

View file

@ -265,8 +265,8 @@ Raised when an \keyword{assert} statement fails.
\end{excdesc} \end{excdesc}
\begin{excdesc}{StopIteration} \begin{excdesc}{StopIteration}
Raised by an iterator's \method{next()} method to signal that there Raised by builtin \function{next()} and an iterator's \method{__next__()}
are no further values. method to signal that there are no further values.
This is derived from \exception{Exception} rather than This is derived from \exception{Exception} rather than
\exception{StandardError}, since this is not considered an error in \exception{StandardError}, since this is not considered an error in
its normal application. its normal application.

View file

@ -342,14 +342,12 @@ class C:
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{enumerate}{iterable} \begin{funcdesc}{enumerate}{iterable}
Return an enumerate object. \var{iterable} must be a sequence, an Return an enumerate object. \var{iterable} must be a sequence, an iterator, or
iterator, or some other object which supports iteration. The some other object which supports iteration. The \method{__next__()} method of
\method{next()} method of the iterator returned by the iterator returned by \function{enumerate()} returns a tuple containing a
\function{enumerate()} returns a tuple containing a count (from count (from zero) and the corresponding value obtained from iterating over
zero) and the corresponding value obtained from iterating over \var{iterable}. \function{enumerate()} is useful for obtaining an indexed
\var{iterable}. \function{enumerate()} is useful for obtaining an series: \code{(0, seq[0])}, \code{(1, seq[1])}, \code{(2, seq[2])}, \ldots.
indexed series: \code{(0, seq[0])}, \code{(1, seq[1])}, \code{(2,
seq[2])}, \ldots.
\versionadded{2.3} \versionadded{2.3}
\end{funcdesc} \end{funcdesc}
@ -615,7 +613,7 @@ class C:
support either of those protocols, \exception{TypeError} is raised. support either of those protocols, \exception{TypeError} is raised.
If the second argument, \var{sentinel}, is given, then \var{o} must If the second argument, \var{sentinel}, is given, then \var{o} must
be a callable object. The iterator created in this case will call be a callable object. The iterator created in this case will call
\var{o} with no arguments for each call to its \method{next()} \var{o} with no arguments for each call to its \method{__next__()}
method; if the value returned is equal to \var{sentinel}, method; if the value returned is equal to \var{sentinel},
\exception{StopIteration} will be raised, otherwise the value will \exception{StopIteration} will be raised, otherwise the value will
be returned. be returned.
@ -695,6 +693,12 @@ class C:
\versionchanged[Added support for the optional \var{key} argument]{2.5} \versionchanged[Added support for the optional \var{key} argument]{2.5}
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{next}{iterator\optional{, default}}
Retrieve the next item from the \var{iterable} by calling its
\method{__next__()} method. If \var{default} is given, it is returned if the
iterator is exhausted, otherwise \exception{StopIteration} is raised.
\end{funcdesc}
\begin{funcdesc}{object}{} \begin{funcdesc}{object}{}
Return a new featureless object. \class{object} is a base Return a new featureless object. \class{object} is a base
for all new style classes. It has the methods that are common for all new style classes. It has the methods that are common

View file

@ -164,16 +164,16 @@ by functions or loops that truncate the stream.
self.tgtkey = self.currkey = self.currvalue = xrange(0) self.tgtkey = self.currkey = self.currvalue = xrange(0)
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
while self.currkey == self.tgtkey: while self.currkey == self.tgtkey:
self.currvalue = self.it.next() # Exit on StopIteration self.currvalue = next(self.it) # Exit on StopIteration
self.currkey = self.keyfunc(self.currvalue) self.currkey = self.keyfunc(self.currvalue)
self.tgtkey = self.currkey self.tgtkey = self.currkey
return (self.currkey, self._grouper(self.tgtkey)) return (self.currkey, self._grouper(self.tgtkey))
def _grouper(self, tgtkey): def _grouper(self, tgtkey):
while self.currkey == tgtkey: while self.currkey == tgtkey:
yield self.currvalue yield self.currvalue
self.currvalue = self.it.next() # Exit on StopIteration self.currvalue = next(self.it) # Exit on StopIteration
self.currkey = self.keyfunc(self.currvalue) self.currkey = self.keyfunc(self.currvalue)
\end{verbatim} \end{verbatim}
\versionadded{2.4} \versionadded{2.4}
@ -227,7 +227,7 @@ by functions or loops that truncate the stream.
def imap(function, *iterables): def imap(function, *iterables):
iterables = map(iter, iterables) iterables = map(iter, iterables)
while True: while True:
args = [i.next() for i in iterables] args = [next(i) for i in iterables]
if function is None: if function is None:
yield tuple(args) yield tuple(args)
else: else:
@ -253,11 +253,11 @@ by functions or loops that truncate the stream.
def islice(iterable, *args): def islice(iterable, *args):
s = slice(*args) s = slice(*args)
it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1)) it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
nexti = it.next() nexti = next(it)
for i, element in enumerate(iterable): for i, element in enumerate(iterable):
if i == nexti: if i == nexti:
yield element yield element
nexti = it.next() nexti = next(it)
\end{verbatim} \end{verbatim}
If \var{start} is \code{None}, then iteration starts at zero. If \var{start} is \code{None}, then iteration starts at zero.
@ -276,7 +276,7 @@ by functions or loops that truncate the stream.
def izip(*iterables): def izip(*iterables):
iterables = map(iter, iterables) iterables = map(iter, iterables)
while iterables: while iterables:
result = [it.next() for it in iterables] result = [next(it) for it in iterables]
yield tuple(result) yield tuple(result)
\end{verbatim} \end{verbatim}
@ -297,7 +297,7 @@ by functions or loops that truncate the stream.
from each iterator in-turn, but the process ends when one of the iterators from each iterator in-turn, but the process ends when one of the iterators
terminates. This leaves the last fetched values in limbo (they cannot be terminates. This leaves the last fetched values in limbo (they cannot be
returned in a final, incomplete tuple and they are cannot be pushed back returned in a final, incomplete tuple and they are cannot be pushed back
into the iterator for retrieval with \code{it.next()}). In general, into the iterator for retrieval with \code{next(it)}). In general,
\function{izip()} should only be used with unequal length inputs when you \function{izip()} should only be used with unequal length inputs when you
don't care about trailing, unmatched values from the longer iterables. don't care about trailing, unmatched values from the longer iterables.
\end{funcdesc} \end{funcdesc}
@ -360,7 +360,7 @@ by functions or loops that truncate the stream.
def starmap(function, iterable): def starmap(function, iterable):
iterable = iter(iterable) iterable = iter(iterable)
while True: while True:
yield function(*iterable.next()) yield function(*next(iterable))
\end{verbatim} \end{verbatim}
\end{funcdesc} \end{funcdesc}
@ -393,7 +393,7 @@ by functions or loops that truncate the stream.
item = data.pop(i) item = data.pop(i)
yield item yield item
it = iter(iterable) it = iter(iterable)
return (gen(it.next), gen(it.next)) return (gen(it.__next__), gen(it.__next__))
\end{verbatim} \end{verbatim}
Note, once \function{tee()} has made a split, the original \var{iterable} Note, once \function{tee()} has made a split, the original \var{iterable}
@ -556,10 +556,7 @@ def repeatfunc(func, times=None, *args):
def pairwise(iterable): def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..." "s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable) a, b = tee(iterable)
try: next(b, None)
b.next()
except StopIteration:
pass
return izip(a, b) return izip(a, b)
def grouper(n, iterable, padvalue=None): def grouper(n, iterable, padvalue=None):

View file

@ -388,18 +388,17 @@ general and specific sequence types, dictionaries, and other more
specialized forms. The specific types are not important beyond their specialized forms. The specific types are not important beyond their
implementation of the iterator protocol. implementation of the iterator protocol.
The intention of the protocol is that once an iterator's The intention of the protocol is that once an iterator's \method{__next__()}
\method{next()} method raises \exception{StopIteration}, it will method raises \exception{StopIteration}, it will continue to do so on subsequent
continue to do so on subsequent calls. Implementations that calls. Implementations that do not obey this property are deemed broken. (This
do not obey this property are deemed broken. (This constraint constraint was added in Python 2.3; in Python 2.2, various iterators are broken
was added in Python 2.3; in Python 2.2, various iterators are according to this rule.)
broken according to this rule.)
Python's generators provide a convenient way to implement the Python's generators provide a convenient way to implement the iterator protocol.
iterator protocol. If a container object's \method{__iter__()} If a container object's \method{__iter__()} method is implemented as a
method is implemented as a generator, it will automatically generator, it will automatically return an iterator object (technically, a
return an iterator object (technically, a generator object) generator object) supplying the \method{__iter__()} and \method{__next__()}
supplying the \method{__iter__()} and \method{next()} methods. methods.
\section{Sequence Types --- \section{Sequence Types ---
@ -1587,17 +1586,17 @@ finally:
with a real file, this method should \emph{not} be implemented.} with a real file, this method should \emph{not} be implemented.}
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}[file]{next}{} \begin{methoddesc}[file]{__next__}{}
A file object is its own iterator, for example \code{iter(\var{f})} returns A file object is its own iterator, for example \code{iter(\var{f})} returns
\var{f} (unless \var{f} is closed). When a file is used as an \var{f} (unless \var{f} is closed). When a file is used as an
iterator, typically in a \keyword{for} loop (for example, iterator, typically in a \keyword{for} loop (for example,
\code{for line in f: print line}), the \method{next()} method is \code{for line in f: print line}), the \method{__next__()} method is
called repeatedly. This method returns the next input line, or raises called repeatedly. This method returns the next input line, or raises
\exception{StopIteration} when \EOF{} is hit. In order to make a \exception{StopIteration} when \EOF{} is hit. In order to make a
\keyword{for} loop the most efficient way of looping over the lines of \keyword{for} loop the most efficient way of looping over the lines of
a file (a very common operation), the \method{next()} method uses a a file (a very common operation), the \method{__next__()} method uses a
hidden read-ahead buffer. As a consequence of using a read-ahead hidden read-ahead buffer. As a consequence of using a read-ahead
buffer, combining \method{next()} with other file methods (like buffer, combining \method{__next__()} with other file methods (like
\method{readline()}) does not work right. However, using \method{readline()}) does not work right. However, using
\method{seek()} to reposition the file to an absolute position will \method{seek()} to reposition the file to an absolute position will
flush the read-ahead buffer. flush the read-ahead buffer.

View file

@ -7,7 +7,7 @@ class IterChars:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.count > ord('z'): if self.count > ord('z'):
raise StopIteration raise StopIteration
self.count += 1 self.count += 1

View file

@ -633,7 +633,7 @@ A function or method which uses the \keyword{yield} statement (see
section~\ref{yield}, ``The \keyword{yield} statement'') is called a section~\ref{yield}, ``The \keyword{yield} statement'') is called a
\dfn{generator function}. Such a function, when called, always \dfn{generator function}. Such a function, when called, always
returns an iterator object which can be used to execute the body of returns an iterator object which can be used to execute the body of
the function: calling the iterator's \method{next()} method will the function: calling the iterator's \method{__next__()} method will
cause the function to execute until it provides a value using the cause the function to execute until it provides a value using the
\keyword{yield} statement. When the function executes a \keyword{yield} statement. When the function executes a
\keyword{return} statement or falls off the end, a \keyword{return} statement or falls off the end, a

View file

@ -222,7 +222,7 @@ evaluating the expression to yield a value that is reached the
innermost block for each iteration. innermost block for each iteration.
Variables used in the generator expression are evaluated lazily Variables used in the generator expression are evaluated lazily
when the \method{next()} method is called for generator object when the \method{__next__()} method is called for generator object
(in the same fashion as normal generators). However, the leftmost (in the same fashion as normal generators). However, the leftmost
\keyword{for} clause is immediately evaluated so that error produced \keyword{for} clause is immediately evaluated so that error produced
by it can be seen before any other possible error in the code that by it can be seen before any other possible error in the code that

View file

@ -418,19 +418,18 @@ Using a \keyword{yield} statement in a function definition is
sufficient to cause that definition to create a generator function sufficient to cause that definition to create a generator function
instead of a normal function. instead of a normal function.
When a generator function is called, it returns an iterator known as a When a generator function is called, it returns an iterator known as a generator
generator iterator, or more commonly, a generator. The body of the iterator, or more commonly, a generator. The body of the generator function is
generator function is executed by calling the generator's executed by calling the generator's \method{__next__()} method repeatedly until
\method{next()} method repeatedly until it raises an exception. it raises an exception.
When a \keyword{yield} statement is executed, the state of the When a \keyword{yield} statement is executed, the state of the generator is
generator is frozen and the value of \grammartoken{expression_list} is frozen and the value of \grammartoken{expression_list} is returned to
returned to \method{next()}'s caller. By ``frozen'' we mean that all \method{__next__()}'s caller. By ``frozen'' we mean that all local state is
local state is retained, including the current bindings of local retained, including the current bindings of local variables, the instruction
variables, the instruction pointer, and the internal evaluation stack: pointer, and the internal evaluation stack: enough information is saved so that
enough information is saved so that the next time \method{next()} is the next time \method{__next__()} is invoked, the function can proceed exactly
invoked, the function can proceed exactly as if the \keyword{yield} as if the \keyword{yield} statement were just another external call.
statement were just another external call.
As of Python version 2.5, the \keyword{yield} statement is now As of Python version 2.5, the \keyword{yield} statement is now
allowed in the \keyword{try} clause of a \keyword{try} ...\ allowed in the \keyword{try} clause of a \keyword{try} ...\

View file

@ -117,7 +117,7 @@ contain one or more {}\keyword{for} or \keyword{while} loops that
\keyword{yield} elements back to the caller. The function execution is \keyword{yield} elements back to the caller. The function execution is
stopped at the {}\keyword{yield} keyword (returning the result) and is stopped at the {}\keyword{yield} keyword (returning the result) and is
resumed there when the next element is requested by calling the resumed there when the next element is requested by calling the
\method{next()} method of the returned iterator. \method{__next__()} method of the returned iterator.
\index{generator expression} \index{generator expression}
\item[generator expression] \item[generator expression]
@ -207,10 +207,10 @@ hold the iterator for the duration of the loop. See also
\index{iterator} \index{iterator}
\item[iterator] \item[iterator]
An object representing a stream of data. Repeated calls to the An object representing a stream of data. Repeated calls to the
iterator's \method{next()} method return successive items in the iterator's \method{__next__()} method return successive items in the
stream. When no more data is available a \exception{StopIteration} stream. When no more data is available a \exception{StopIteration}
exception is raised instead. At this point, the iterator object is exception is raised instead. At this point, the iterator object is
exhausted and any further calls to its \method{next()} method just exhausted and any further calls to its \method{__next__()} method just
raise \exception{StopIteration} again. Iterators are required to have raise \exception{StopIteration} again. Iterators are required to have
an \method{__iter__()} method that returns the iterator object an \method{__iter__()} method that returns the iterator object
itself so every iterator is also iterable and may be used in most itself so every iterator is also iterable and may be used in most

View file

@ -4488,34 +4488,35 @@ This style of access is clear, concise, and convenient. The use of iterators
pervades and unifies Python. Behind the scenes, the \keyword{for} pervades and unifies Python. Behind the scenes, the \keyword{for}
statement calls \function{iter()} on the container object. The statement calls \function{iter()} on the container object. The
function returns an iterator object that defines the method function returns an iterator object that defines the method
\method{next()} which accesses elements in the container one at a \method{__next__()} which accesses elements in the container one at a
time. When there are no more elements, \method{next()} raises a time. When there are no more elements, \method{__next__()} raises a
\exception{StopIteration} exception which tells the \keyword{for} loop \exception{StopIteration} exception which tells the \keyword{for} loop
to terminate. This example shows how it all works: to terminate. You can call the \method{__next__()} method using the
\function{next()} builtin; this example shows how it all works:
\begin{verbatim} \begin{verbatim}
>>> s = 'abc' >>> s = 'abc'
>>> it = iter(s) >>> it = iter(s)
>>> it >>> it
<iterator object at 0x00A1DB50> <iterator object at 0x00A1DB50>
>>> it.next() >>> next(it)
'a' 'a'
>>> it.next() >>> next(it)
'b' 'b'
>>> it.next() >>> next(it)
'c' 'c'
>>> it.next() >>> next(it)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
it.next() next(it)
StopIteration StopIteration
\end{verbatim} \end{verbatim}
Having seen the mechanics behind the iterator protocol, it is easy to add Having seen the mechanics behind the iterator protocol, it is easy to add
iterator behavior to your classes. Define a \method{__iter__()} method iterator behavior to your classes. Define a \method{__iter__()} method
which returns an object with a \method{next()} method. If the class defines which returns an object with a \method{__next__()} method. If the class defines
\method{next()}, then \method{__iter__()} can just return \code{self}: \method{__next__()}, then \method{__iter__()} can just return \code{self}:
\begin{verbatim} \begin{verbatim}
class Reverse: class Reverse:
@ -4525,7 +4526,7 @@ class Reverse:
self.index = len(data) self.index = len(data)
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.index == 0: if self.index == 0:
raise StopIteration raise StopIteration
self.index = self.index - 1 self.index = self.index - 1
@ -4545,7 +4546,7 @@ s
Generators are a simple and powerful tool for creating iterators. They are Generators are a simple and powerful tool for creating iterators. They are
written like regular functions but use the \keyword{yield} statement whenever written like regular functions but use the \keyword{yield} statement whenever
they want to return data. Each time \method{next()} is called, the they want to return data. Each time \function{next()} is called on it, the
generator resumes where it left-off (it remembers all the data values and generator resumes where it left-off (it remembers all the data values and
which statement was last executed). An example shows that generators can which statement was last executed). An example shows that generators can
be trivially easy to create: be trivially easy to create:
@ -4566,7 +4567,7 @@ g
Anything that can be done with generators can also be done with class based Anything that can be done with generators can also be done with class based
iterators as described in the previous section. What makes generators so iterators as described in the previous section. What makes generators so
compact is that the \method{__iter__()} and \method{next()} methods are compact is that the \method{__iter__()} and \method{__next__()} methods are
created automatically. created automatically.
Another key feature is that the local variables and execution state Another key feature is that the local variables and execution state

View file

@ -64,10 +64,10 @@ class StringIO:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
"""A file object is its own iterator, for example iter(f) returns f """A file object is its own iterator, for example iter(f) returns f
(unless f is closed). When a file is used as an iterator, typically (unless f is closed). When a file is used as an iterator, typically
in a for loop (for example, for line in f: print line), the next() in a for loop (for example, for line in f: print line), the __next__()
method is called repeatedly. This method returns the next input line, method is called repeatedly. This method returns the next input line,
or raises StopIteration when EOF is hit. or raises StopIteration when EOF is hit.
""" """

View file

@ -139,7 +139,7 @@ class DictMixin:
return value return value
def popitem(self): def popitem(self):
try: try:
k, v = self.iteritems().next() k, v = next(self.iteritems())
except StopIteration: except StopIteration:
raise KeyError, 'container is empty' raise KeyError, 'container is empty'
del self[k] del self[k]

View file

@ -600,7 +600,7 @@ class StreamReader(Codec):
self.reset() self.reset()
self.stream.seek(offset, whence) self.stream.seek(offset, whence)
def next(self): def __next__(self):
""" Return the next decoded line from the input stream.""" """ Return the next decoded line from the input stream."""
line = self.readline() line = self.readline()
@ -669,10 +669,10 @@ class StreamReaderWriter:
return self.reader.readlines(sizehint) return self.reader.readlines(sizehint)
def next(self): def __next__(self):
""" Return the next decoded line from the input stream.""" """ Return the next decoded line from the input stream."""
return self.reader.next() return next(self.reader)
def __iter__(self): def __iter__(self):
return self return self
@ -782,10 +782,10 @@ class StreamRecoder:
data, bytesencoded = self.encode(data, self.errors) data, bytesencoded = self.encode(data, self.errors)
return data.splitlines(1) return data.splitlines(1)
def next(self): def __next__(self):
""" Return the next decoded line from the input stream.""" """ Return the next decoded line from the input stream."""
data = self.reader.next() data = next(self.reader)
data, bytesencoded = self.encode(data, self.errors) data, bytesencoded = self.encode(data, self.errors)
return data return data

View file

@ -12,14 +12,14 @@ class GeneratorContextManager(object):
def __enter__(self): def __enter__(self):
try: try:
return self.gen.next() return next(self.gen)
except StopIteration: except StopIteration:
raise RuntimeError("generator didn't yield") raise RuntimeError("generator didn't yield")
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
if type is None: if type is None:
try: try:
self.gen.next() next(self.gen)
except StopIteration: except StopIteration:
return return
else: else:

View file

@ -79,17 +79,17 @@ class DictReader:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
row = self.reader.next() row = next(self.reader)
if self.fieldnames is None: if self.fieldnames is None:
self.fieldnames = row self.fieldnames = row
row = self.reader.next() row = next(self.reader)
# unlike the basic reader, we prefer not to return blanks, # unlike the basic reader, we prefer not to return blanks,
# because we will typically wind up with a dict full of None # because we will typically wind up with a dict full of None
# values # values
while row == []: while row == []:
row = self.reader.next() row = next(self.reader)
d = dict(zip(self.fieldnames, row)) d = dict(zip(self.fieldnames, row))
lf = len(self.fieldnames) lf = len(self.fieldnames)
lr = len(row) lr = len(row)
@ -351,7 +351,7 @@ class Sniffer:
rdr = reader(StringIO(sample), self.sniff(sample)) rdr = reader(StringIO(sample), self.sniff(sample))
header = rdr.next() # assume first row is header header = next(rdr) # assume first row is header
columns = len(header) columns = len(header)
columnTypes = {} columnTypes = {}

View file

@ -1430,7 +1430,7 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None,
# so we can do some very readable comparisons. # so we can do some very readable comparisons.
while len(lines) < 4: while len(lines) < 4:
try: try:
lines.append(diff_lines_iterator.next()) lines.append(next(diff_lines_iterator))
except StopIteration: except StopIteration:
lines.append('X') lines.append('X')
s = ''.join([line[0] for line in lines]) s = ''.join([line[0] for line in lines])
@ -1517,7 +1517,7 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None,
while True: while True:
# Collecting lines of text until we have a from/to pair # Collecting lines of text until we have a from/to pair
while (len(fromlines)==0 or len(tolines)==0): while (len(fromlines)==0 or len(tolines)==0):
from_line, to_line, found_diff =line_iterator.next() from_line, to_line, found_diff = next(line_iterator)
if from_line is not None: if from_line is not None:
fromlines.append((from_line,found_diff)) fromlines.append((from_line,found_diff))
if to_line is not None: if to_line is not None:
@ -1532,7 +1532,7 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None,
line_pair_iterator = _line_pair_iterator() line_pair_iterator = _line_pair_iterator()
if context is None: if context is None:
while True: while True:
yield line_pair_iterator.next() yield next(line_pair_iterator)
# Handle case where user wants context differencing. We must do some # Handle case where user wants context differencing. We must do some
# storage of lines until we know for sure that they are to be yielded. # storage of lines until we know for sure that they are to be yielded.
else: else:
@ -1545,7 +1545,7 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None,
index, contextLines = 0, [None]*(context) index, contextLines = 0, [None]*(context)
found_diff = False found_diff = False
while(found_diff is False): while(found_diff is False):
from_line, to_line, found_diff = line_pair_iterator.next() from_line, to_line, found_diff = next(line_pair_iterator)
i = index % context i = index % context
contextLines[i] = (from_line, to_line, found_diff) contextLines[i] = (from_line, to_line, found_diff)
index += 1 index += 1
@ -1565,7 +1565,7 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None,
# Now yield the context lines after the change # Now yield the context lines after the change
lines_to_write = context-1 lines_to_write = context-1
while(lines_to_write): while(lines_to_write):
from_line, to_line, found_diff = line_pair_iterator.next() from_line, to_line, found_diff = next(line_pair_iterator)
# If another change within the context, extend the context # If another change within the context, extend the context
if found_diff: if found_diff:
lines_to_write = context-1 lines_to_write = context-1

View file

@ -122,7 +122,7 @@ class BufferedSubFile(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
line = self.readline() line = self.readline()
if line == '': if line == '':
raise StopIteration raise StopIteration
@ -138,7 +138,7 @@ class FeedParser:
self._factory = _factory self._factory = _factory
self._input = BufferedSubFile() self._input = BufferedSubFile()
self._msgstack = [] self._msgstack = []
self._parse = self._parsegen().next self._parse = self._parsegen().__next__
self._cur = None self._cur = None
self._last = None self._last = None
self._headersonly = False self._headersonly = False

View file

@ -240,7 +240,7 @@ class FileInput:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
try: try:
line = self._buffer[self._bufindex] line = self._buffer[self._bufindex]
except IndexError: except IndexError:
@ -259,7 +259,7 @@ class FileInput:
if i != self._lineno: if i != self._lineno:
raise RuntimeError, "accessing lines out of order" raise RuntimeError, "accessing lines out of order"
try: try:
return self.next() return self.__next__()
except StopIteration: except StopIteration:
raise IndexError, "end of input reached" raise IndexError, "end of input reached"

View file

@ -453,7 +453,7 @@ class GzipFile:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
line = self.readline() line = self.readline()
if line: if line:
return line return line

View file

@ -325,7 +325,7 @@ def merge(*iterables):
h_append = h.append h_append = h.append
for itnum, it in enumerate(map(iter, iterables)): for itnum, it in enumerate(map(iter, iterables)):
try: try:
next = it.next next = it.__next__
h_append([next(), itnum, next]) h_append([next(), itnum, next])
except _StopIteration: except _StopIteration:
pass pass

View file

@ -29,7 +29,7 @@ class LogReader:
self._funcmap = {} self._funcmap = {}
self._reader = _hotshot.logreader(logfn) self._reader = _hotshot.logreader(logfn)
self._nextitem = self._reader.next self._nextitem = self._reader.__next__
self._info = self._reader.info self._info = self._reader.info
if 'current-directory' in self._info: if 'current-directory' in self._info:
self.cwd = self._info['current-directory'] self.cwd = self._info['current-directory']
@ -93,7 +93,7 @@ class LogReader:
# same bound method can be used as the __getitem__() method -- this # same bound method can be used as the __getitem__() method -- this
# avoids using an additional method call which kills the performance. # avoids using an additional method call which kills the performance.
def next(self, index=0): def __next__(self, index=0):
while 1: while 1:
# This call may raise StopIteration: # This call may raise StopIteration:
what, tdelta, fileno, lineno = self._nextitem() what, tdelta, fileno, lineno = self._nextitem()

View file

@ -1098,7 +1098,7 @@ class SSLFile(SharedSocketClient):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
line = self.readline() line = self.readline()
if not line: if not line:
raise StopIteration raise StopIteration

View file

@ -603,7 +603,7 @@ def getblock(lines):
"""Extract the block of code at the top of the given list of lines.""" """Extract the block of code at the top of the given list of lines."""
blockfinder = BlockFinder() blockfinder = BlockFinder()
try: try:
tokenize.tokenize(iter(lines).next, blockfinder.tokeneater) tokenize.tokenize(iter(lines).__next__, blockfinder.tokeneater)
except (EndOfBlock, IndentationError): except (EndOfBlock, IndentationError):
pass pass
return lines[:blockfinder.last] return lines[:blockfinder.last]

View file

@ -904,7 +904,7 @@ class TextIOBase(IOBase):
""" """
return self return self
def next(self) -> str: def __next__(self) -> str:
"""Same as readline() except raises StopIteration on immediate EOF.""" """Same as readline() except raises StopIteration on immediate EOF."""
line = self.readline() line = self.readline()
if not line: if not line:
@ -1125,7 +1125,7 @@ class TextIOWrapper(TextIOBase):
self._pending = res[n:] self._pending = res[n:]
return self._simplify(res[:n]) return self._simplify(res[:n])
def next(self) -> str: def __next__(self) -> str:
self._telling = False self._telling = False
line = self.readline() line = self.readline()
if not line: if not line:

View file

@ -480,7 +480,7 @@ class Maildir(Mailbox):
self._onetime_keys = iter(self.keys()) self._onetime_keys = iter(self.keys())
while True: while True:
try: try:
return self[self._onetime_keys.next()] return self[next(self._onetime_keys)]
except StopIteration: except StopIteration:
return None return None
except KeyError: except KeyError:

View file

@ -640,7 +640,7 @@ class Pickler:
tmp = [] tmp = []
for i in r: for i in r:
try: try:
x = items.next() x = next(items)
tmp.append(x) tmp.append(x)
except StopIteration: except StopIteration:
items = None items = None
@ -688,7 +688,7 @@ class Pickler:
tmp = [] tmp = []
for i in r: for i in r:
try: try:
tmp.append(items.next()) tmp.append(next(items))
except StopIteration: except StopIteration:
items = None items = None
break break

View file

@ -396,7 +396,7 @@ class Stats:
subheader = False subheader = False
for cc, nc, tt, ct, callers in self.stats.values(): for cc, nc, tt, ct, callers in self.stats.values():
if callers: if callers:
value = iter(callers.values()).next() value = next(iter(callers.values()))
subheader = isinstance(value, tuple) subheader = isinstance(value, tuple)
break break
if subheader: if subheader:

View file

@ -161,7 +161,7 @@ def _readmodule(module, path, inpackage=None):
# close previous nested classes and defs # close previous nested classes and defs
while stack and stack[-1][1] >= thisindent: while stack and stack[-1][1] >= thisindent:
del stack[-1] del stack[-1]
tokentype, meth_name, start, end, line = g.next() tokentype, meth_name, start, end, line = next(g)
if tokentype != NAME: if tokentype != NAME:
continue # Syntax error continue # Syntax error
if stack: if stack:
@ -179,11 +179,11 @@ def _readmodule(module, path, inpackage=None):
# close previous nested classes and defs # close previous nested classes and defs
while stack and stack[-1][1] >= thisindent: while stack and stack[-1][1] >= thisindent:
del stack[-1] del stack[-1]
tokentype, class_name, start, end, line = g.next() tokentype, class_name, start, end, line = next(g)
if tokentype != NAME: if tokentype != NAME:
continue # Syntax error continue # Syntax error
# parse what follows the class name # parse what follows the class name
tokentype, token, start, end, line = g.next() tokentype, token, start, end, line = next(g)
inherit = None inherit = None
if token == '(': if token == '(':
names = [] # List of superclasses names = [] # List of superclasses
@ -191,7 +191,7 @@ def _readmodule(module, path, inpackage=None):
level = 1 level = 1
super = [] # Tokens making up current superclass super = [] # Tokens making up current superclass
while True: while True:
tokentype, token, start, end, line = g.next() tokentype, token, start, end, line = next(g)
if token in (')', ',') and level == 1: if token in (')', ',') and level == 1:
n = "".join(super) n = "".join(super)
if n in dict: if n in dict:
@ -287,7 +287,7 @@ def _getnamelist(g):
name2 = None name2 = None
names.append((name, name2)) names.append((name, name2))
while token != "," and "\n" not in token: while token != "," and "\n" not in token:
tokentype, token, start, end, line = g.next() tokentype, token, start, end, line = next(g)
if token != ",": if token != ",":
break break
return names return names
@ -297,15 +297,15 @@ def _getname(g):
# name is the dotted name, or None if there was no dotted name, # name is the dotted name, or None if there was no dotted name,
# and token is the next input token. # and token is the next input token.
parts = [] parts = []
tokentype, token, start, end, line = g.next() tokentype, token, start, end, line = next(g)
if tokentype != NAME and token != '*': if tokentype != NAME and token != '*':
return (None, token) return (None, token)
parts.append(token) parts.append(token)
while True: while True:
tokentype, token, start, end, line = g.next() tokentype, token, start, end, line = next(g)
if token != '.': if token != '.':
break break
tokentype, token, start, end, line = g.next() tokentype, token, start, end, line = next(g)
if tokentype != NAME: if tokentype != NAME:
break break
parts.append(token) parts.append(token)

View file

@ -174,7 +174,7 @@ class BsdDbShelf(Shelf):
return (key, Unpickler(f).load()) return (key, Unpickler(f).load())
def next(self): def next(self):
(key, value) = self.dict.next() (key, value) = next(self.dict)
f = StringIO(value) f = StringIO(value)
return (key, Unpickler(f).load()) return (key, Unpickler(f).load())

View file

@ -265,7 +265,7 @@ class shlex:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
token = self.get_token() token = self.get_token()
if token == self.eof: if token == self.eof:
raise StopIteration raise StopIteration

View file

@ -409,7 +409,7 @@ class _fileobject(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
line = self.readline() line = self.readline()
if not line: if not line:
raise StopIteration raise StopIteration

View file

@ -286,7 +286,7 @@ class CursorTests(unittest.TestCase):
def __init__(self): def __init__(self):
self.value = 5 self.value = 5
def next(self): def __next__(self):
if self.value == 10: if self.value == 10:
raise StopIteration raise StopIteration
else: else:

View file

@ -2046,7 +2046,7 @@ class TarIter:
"""Return iterator object. """Return iterator object.
""" """
return self return self
def next(self): def __next__(self):
"""Return the next item using TarFile's next() method. """Return the next item using TarFile's next() method.
When all members have been read, set TarFile as _loaded. When all members have been read, set TarFile as _loaded.
""" """

View file

@ -124,7 +124,7 @@ class _RandomNameSequence:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
m = self.mutex m = self.mutex
c = self.characters c = self.characters
choose = self.rng.choice choose = self.rng.choice
@ -191,7 +191,7 @@ def _get_default_tempdir():
dir = _os.path.normcase(_os.path.abspath(dir)) dir = _os.path.normcase(_os.path.abspath(dir))
# Try only a few names per directory. # Try only a few names per directory.
for seq in xrange(100): for seq in xrange(100):
name = namer.next() name = next(namer)
filename = _os.path.join(dir, name) filename = _os.path.join(dir, name)
try: try:
fd = _os.open(filename, flags, 0600) fd = _os.open(filename, flags, 0600)
@ -230,7 +230,7 @@ def _mkstemp_inner(dir, pre, suf, flags):
names = _get_candidate_names() names = _get_candidate_names()
for seq in xrange(TMP_MAX): for seq in xrange(TMP_MAX):
name = names.next() name = next(names)
file = _os.path.join(dir, pre + name + suf) file = _os.path.join(dir, pre + name + suf)
try: try:
fd = _os.open(file, flags, 0600) fd = _os.open(file, flags, 0600)
@ -322,7 +322,7 @@ def mkdtemp(suffix="", prefix=template, dir=None):
names = _get_candidate_names() names = _get_candidate_names()
for seq in xrange(TMP_MAX): for seq in xrange(TMP_MAX):
name = names.next() name = next(names)
file = _os.path.join(dir, prefix + name + suffix) file = _os.path.join(dir, prefix + name + suffix)
try: try:
_os.mkdir(file, 0700) _os.mkdir(file, 0700)
@ -357,7 +357,7 @@ def mktemp(suffix="", prefix=template, dir=None):
names = _get_candidate_names() names = _get_candidate_names()
for seq in xrange(TMP_MAX): for seq in xrange(TMP_MAX):
name = names.next() name = next(names)
file = _os.path.join(dir, prefix + name + suffix) file = _os.path.join(dir, prefix + name + suffix)
if not _exists(file): if not _exists(file):
return file return file

View file

@ -77,7 +77,7 @@ class CommonTest(seq_tests.CommonTest):
a = self.type2test(range(20)) a = self.type2test(range(20))
r = reversed(a) r = reversed(a)
self.assertEqual(list(r), self.type2test(range(19, -1, -1))) self.assertEqual(list(r), self.type2test(range(19, -1, -1)))
self.assertRaises(StopIteration, r.next) self.assertRaises(StopIteration, next, r)
self.assertEqual(list(reversed(self.type2test())), self.assertEqual(list(reversed(self.type2test())),
self.type2test()) self.type2test())

View file

@ -69,7 +69,7 @@ class BasicTestMappingProtocol(unittest.TestCase):
if not d: self.fail("Full mapping must compare to True") if not d: self.fail("Full mapping must compare to True")
# keys(), items(), iterkeys() ... # keys(), items(), iterkeys() ...
def check_iterandlist(iter, lst, ref): def check_iterandlist(iter, lst, ref):
self.assert_(hasattr(iter, 'next')) self.assert_(hasattr(iter, '__next__'))
self.assert_(hasattr(iter, '__iter__')) self.assert_(hasattr(iter, '__iter__'))
x = list(iter) x = list(iter)
self.assert_(set(x)==set(lst)==set(ref)) self.assert_(set(x)==set(lst)==set(ref))
@ -81,8 +81,8 @@ class BasicTestMappingProtocol(unittest.TestCase):
check_iterandlist(iter(d.items()), list(d.items()), check_iterandlist(iter(d.items()), list(d.items()),
self.reference.items()) self.reference.items())
#get #get
key, value = iter(d.items()).next() key, value = next(iter(d.items()))
knownkey, knownvalue = iter(self.other.items()).next() knownkey, knownvalue = next(iter(self.other.items()))
self.assertEqual(d.get(key, knownvalue), value) self.assertEqual(d.get(key, knownvalue), value)
self.assertEqual(d.get(knownkey, knownvalue), knownvalue) self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
self.failIf(knownkey in d) self.failIf(knownkey in d)
@ -107,8 +107,8 @@ class BasicTestMappingProtocol(unittest.TestCase):
self.assertEqual(dict(p), self.reference) self.assertEqual(dict(p), self.reference)
d = self._full_mapping(self.reference) d = self._full_mapping(self.reference)
#setdefault #setdefault
key, value = iter(d.items()).next() key, value = next(iter(d.items()))
knownkey, knownvalue = iter(self.other.items()).next() knownkey, knownvalue = next(iter(self.other.items()))
self.assertEqual(d.setdefault(key, knownvalue), value) self.assertEqual(d.setdefault(key, knownvalue), value)
self.assertEqual(d[key], value) self.assertEqual(d[key], value)
self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue) self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)
@ -225,7 +225,7 @@ class BasicTestMappingProtocol(unittest.TestCase):
self.i = 1 self.i = 1
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i: if self.i:
self.i = 0 self.i = 0
return 'a' return 'a'
@ -242,7 +242,7 @@ class BasicTestMappingProtocol(unittest.TestCase):
self.i = ord('a') self.i = ord('a')
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i <= ord('z'): if self.i <= ord('z'):
rtn = chr(self.i) rtn = chr(self.i)
self.i += 1 self.i += 1
@ -257,7 +257,7 @@ class BasicTestMappingProtocol(unittest.TestCase):
class badseq(object): class badseq(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise Exc() raise Exc()
self.assertRaises(Exc, d.update, badseq()) self.assertRaises(Exc, d.update, badseq())
@ -456,7 +456,7 @@ class TestMappingProtocol(BasicTestMappingProtocol):
class BadSeq(object): class BadSeq(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise Exc() raise Exc()
self.assertRaises(Exc, self.type2test.fromkeys, BadSeq()) self.assertRaises(Exc, self.type2test.fromkeys, BadSeq())

View file

@ -26,7 +26,7 @@ class IterFunc:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
@ -46,14 +46,14 @@ class IterNextOnly:
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
return v return v
class IterNoNext: class IterNoNext:
'Iterator missing next()' 'Iterator missing __next__()'
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
@ -67,7 +67,7 @@ class IterGenExc:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
3 // 0 3 // 0
class IterFuncStop: class IterFuncStop:
@ -76,7 +76,7 @@ class IterFuncStop:
pass pass
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise StopIteration raise StopIteration
from itertools import chain, imap from itertools import chain, imap
@ -296,7 +296,7 @@ class CommonTest(unittest.TestCase):
class T(self.type2test): class T(self.type2test):
def __getitem__(self, key): def __getitem__(self, key):
return str(key) + '!!!' return str(key) + '!!!'
self.assertEqual(iter(T((1,2))).next(), 1) self.assertEqual(next(iter(T((1,2)))), 1)
def test_repeat(self): def test_repeat(self):
for m in xrange(4): for m in xrange(4):

View file

@ -89,14 +89,14 @@ class TestGenericStringIO(unittest.TestCase):
eq(iter(self._fp), self._fp) eq(iter(self._fp), self._fp)
# Does this object support the iteration protocol? # Does this object support the iteration protocol?
unless(hasattr(self._fp, '__iter__')) unless(hasattr(self._fp, '__iter__'))
unless(hasattr(self._fp, 'next')) unless(hasattr(self._fp, '__next__'))
i = 0 i = 0
for line in self._fp: for line in self._fp:
eq(line, self._line + '\n') eq(line, self._line + '\n')
i += 1 i += 1
eq(i, 5) eq(i, 5)
self._fp.close() self._fp.close()
self.assertRaises(ValueError, self._fp.next) self.assertRaises(ValueError, next, self._fp)
class TestStringIO(TestGenericStringIO): class TestStringIO(TestGenericStringIO):
MODULE = StringIO MODULE = StringIO

View file

@ -72,7 +72,7 @@ class TestBSDDB(unittest.TestCase):
di = iter(self.d) di = iter(self.d)
while 1: while 1:
try: try:
key = di.next() key = next(di)
self.d[key] = 'modified '+key self.d[key] = 'modified '+key
except StopIteration: except StopIteration:
break break
@ -83,7 +83,7 @@ class TestBSDDB(unittest.TestCase):
fi = iter(self.f) fi = iter(self.f)
while 1: while 1:
try: try:
key = fi.next() key = next(fi)
self.f[key] = 'modified '+key self.f[key] = 'modified '+key
except StopIteration: except StopIteration:
break break
@ -97,7 +97,7 @@ class TestBSDDB(unittest.TestCase):
di = iter(self.d.items()) di = iter(self.d.items())
while 1: while 1:
try: try:
k, v = di.next() k, v = next(di)
self.d[k] = 'modified '+v self.d[k] = 'modified '+v
except StopIteration: except StopIteration:
break break
@ -108,7 +108,7 @@ class TestBSDDB(unittest.TestCase):
fi = iter(self.f.items()) fi = iter(self.f.items())
while 1: while 1:
try: try:
k, v = fi.next() k, v = next(fi)
self.f[k] = 'modified '+v self.f[k] = 'modified '+v
except StopIteration: except StopIteration:
break break
@ -160,13 +160,13 @@ class TestBSDDB(unittest.TestCase):
if hasattr(self.f, 'iteritems'): if hasattr(self.f, 'iteritems'):
if debug: print("D") if debug: print("D")
i = iter(self.f.items()) i = iter(self.f.items())
k,v = i.next() k,v = next(i)
if debug: print("E") if debug: print("E")
self.f[k] = "please don't deadlock" self.f[k] = "please don't deadlock"
if debug: print("F") if debug: print("F")
while 1: while 1:
try: try:
k,v = i.next() k,v = next(i)
except StopIteration: except StopIteration:
break break
if debug: print("F2") if debug: print("F2")
@ -176,7 +176,7 @@ class TestBSDDB(unittest.TestCase):
while i: while i:
try: try:
if debug: print("H") if debug: print("H")
k = i.next() k = next(i)
if debug: print("I") if debug: print("I")
self.f[k] = "deadlocks-r-us" self.f[k] = "deadlocks-r-us"
if debug: print("J") if debug: print("J")
@ -201,7 +201,7 @@ class TestBSDDB(unittest.TestCase):
i = iter(self.f.iteritems()) i = iter(self.f.iteritems())
nc2 = len(self.f._cursor_refs) nc2 = len(self.f._cursor_refs)
# use the iterator (should run to the first yield, creating the cursor) # use the iterator (should run to the first yield, creating the cursor)
k, v = i.next() k, v = next(i)
nc3 = len(self.f._cursor_refs) nc3 = len(self.f._cursor_refs)
# destroy the iterator; this should cause the weakref callback # destroy the iterator; this should cause the weakref callback
# to remove the cursor object from self.f._cursor_refs # to remove the cursor object from self.f._cursor_refs

View file

@ -907,9 +907,9 @@ class BuiltinTest(unittest.TestCase):
lists.append(unicode("12")) lists.append(unicode("12"))
for l in lists: for l in lists:
i = iter(l) i = iter(l)
self.assertEqual(i.next(), '1') self.assertEqual(next(i), '1')
self.assertEqual(i.next(), '2') self.assertEqual(next(i), '2')
self.assertRaises(StopIteration, i.next) self.assertRaises(StopIteration, next, i)
def test_isinstance(self): def test_isinstance(self):
class C: class C:
@ -1305,6 +1305,33 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(min(data, key=f), self.assertEqual(min(data, key=f),
sorted(data, key=f)[0]) sorted(data, key=f)[0])
def test_next(self):
it = iter(range(2))
self.assertEqual(next(it), 0)
self.assertEqual(next(it), 1)
self.assertRaises(StopIteration, next, it)
self.assertRaises(StopIteration, next, it)
self.assertEquals(next(it, 42), 42)
class Iter(object):
def __iter__(self):
return self
def __next__(self):
raise StopIteration
it = iter(Iter())
self.assertEquals(next(it, 42), 42)
self.assertRaises(StopIteration, next, it)
def gen():
yield 1
return
it = gen()
self.assertEquals(next(it), 1)
self.assertRaises(StopIteration, next, it)
self.assertEquals(next(it, 42), 42)
def test_oct(self): def test_oct(self):
self.assertEqual(oct(100), '0144') self.assertEqual(oct(100), '0144')
self.assertEqual(oct(100), '0144') self.assertEqual(oct(100), '0144')

View file

@ -271,13 +271,13 @@ class Test_Csv(unittest.TestCase):
def test_read_linenum(self): def test_read_linenum(self):
r = csv.reader(['line,1', 'line,2', 'line,3']) r = csv.reader(['line,1', 'line,2', 'line,3'])
self.assertEqual(r.line_num, 0) self.assertEqual(r.line_num, 0)
r.next() next(r)
self.assertEqual(r.line_num, 1) self.assertEqual(r.line_num, 1)
r.next() next(r)
self.assertEqual(r.line_num, 2) self.assertEqual(r.line_num, 2)
r.next() next(r)
self.assertEqual(r.line_num, 3) self.assertEqual(r.line_num, 3)
self.assertRaises(StopIteration, r.next) self.assertRaises(StopIteration, next, r)
self.assertEqual(r.line_num, 3) self.assertEqual(r.line_num, 3)
class TestDialectRegistry(unittest.TestCase): class TestDialectRegistry(unittest.TestCase):
@ -338,9 +338,9 @@ class TestDialectRegistry(unittest.TestCase):
try: try:
fileobj.write("abc def\nc1ccccc1 benzene\n") fileobj.write("abc def\nc1ccccc1 benzene\n")
fileobj.seek(0) fileobj.seek(0)
rdr = csv.reader(fileobj, dialect=space()) reader = csv.reader(fileobj, dialect=space())
self.assertEqual(rdr.next(), ["abc", "def"]) self.assertEqual(next(reader), ["abc", "def"])
self.assertEqual(rdr.next(), ["c1ccccc1", "benzene"]) self.assertEqual(next(reader), ["c1ccccc1", "benzene"])
finally: finally:
fileobj.close() fileobj.close()
os.unlink(name) os.unlink(name)
@ -593,7 +593,7 @@ class TestDictFields(unittest.TestCase):
fileobj.seek(0) fileobj.seek(0)
reader = csv.DictReader(fileobj, reader = csv.DictReader(fileobj,
fieldnames=["f1", "f2", "f3"]) fieldnames=["f1", "f2", "f3"])
self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "f3": 'abc'}) self.assertEqual(next(reader), {"f1": '1', "f2": '2', "f3": 'abc'})
finally: finally:
fileobj.close() fileobj.close()
os.unlink(name) os.unlink(name)
@ -605,7 +605,7 @@ class TestDictFields(unittest.TestCase):
fileobj.write("f1,f2,f3\r\n1,2,abc\r\n") fileobj.write("f1,f2,f3\r\n1,2,abc\r\n")
fileobj.seek(0) fileobj.seek(0)
reader = csv.DictReader(fileobj) reader = csv.DictReader(fileobj)
self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "f3": 'abc'}) self.assertEqual(next(reader), {"f1": '1', "f2": '2', "f3": 'abc'})
finally: finally:
fileobj.close() fileobj.close()
os.unlink(name) os.unlink(name)
@ -618,7 +618,7 @@ class TestDictFields(unittest.TestCase):
fileobj.seek(0) fileobj.seek(0)
reader = csv.DictReader(fileobj, reader = csv.DictReader(fileobj,
fieldnames=["f1", "f2"]) fieldnames=["f1", "f2"])
self.assertEqual(reader.next(), {"f1": '1', "f2": '2', self.assertEqual(next(reader), {"f1": '1', "f2": '2',
None: ["abc", "4", "5", "6"]}) None: ["abc", "4", "5", "6"]})
finally: finally:
fileobj.close() fileobj.close()
@ -632,7 +632,7 @@ class TestDictFields(unittest.TestCase):
fileobj.seek(0) fileobj.seek(0)
reader = csv.DictReader(fileobj, reader = csv.DictReader(fileobj,
fieldnames=["f1", "f2"], restkey="_rest") fieldnames=["f1", "f2"], restkey="_rest")
self.assertEqual(reader.next(), {"f1": '1', "f2": '2', self.assertEqual(next(reader), {"f1": '1', "f2": '2',
"_rest": ["abc", "4", "5", "6"]}) "_rest": ["abc", "4", "5", "6"]})
finally: finally:
fileobj.close() fileobj.close()
@ -645,7 +645,7 @@ class TestDictFields(unittest.TestCase):
fileobj.write("f1,f2\r\n1,2,abc,4,5,6\r\n") fileobj.write("f1,f2\r\n1,2,abc,4,5,6\r\n")
fileobj.seek(0) fileobj.seek(0)
reader = csv.DictReader(fileobj, restkey="_rest") reader = csv.DictReader(fileobj, restkey="_rest")
self.assertEqual(reader.next(), {"f1": '1', "f2": '2', self.assertEqual(next(reader), {"f1": '1', "f2": '2',
"_rest": ["abc", "4", "5", "6"]}) "_rest": ["abc", "4", "5", "6"]})
finally: finally:
fileobj.close() fileobj.close()
@ -660,9 +660,9 @@ class TestDictFields(unittest.TestCase):
reader = csv.DictReader(fileobj, reader = csv.DictReader(fileobj,
fieldnames="1 2 3 4 5 6".split(), fieldnames="1 2 3 4 5 6".split(),
restval="DEFAULT") restval="DEFAULT")
self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', self.assertEqual(next(reader), {"1": '1', "2": '2', "3": 'abc',
"4": '4', "5": '5', "6": '6'}) "4": '4', "5": '5', "6": '6'})
self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', self.assertEqual(next(reader), {"1": '1', "2": '2', "3": 'abc',
"4": 'DEFAULT', "5": 'DEFAULT', "4": 'DEFAULT', "5": 'DEFAULT',
"6": 'DEFAULT'}) "6": 'DEFAULT'})
finally: finally:
@ -678,7 +678,7 @@ class TestDictFields(unittest.TestCase):
reader = csv.DictReader(sample, reader = csv.DictReader(sample,
fieldnames="i1 float i2 s1 s2".split()) fieldnames="i1 float i2 s1 s2".split())
self.assertEqual(reader.next(), {"i1": '2147483648', self.assertEqual(next(reader), {"i1": '2147483648',
"float": '43.0e12', "float": '43.0e12',
"i2": '17', "i2": '17',
"s1": 'abc', "s1": 'abc',
@ -688,16 +688,16 @@ class TestDictFields(unittest.TestCase):
reader = csv.DictReader(["1,2,abc,4,5,6\r\n","\r\n", reader = csv.DictReader(["1,2,abc,4,5,6\r\n","\r\n",
"1,2,abc,4,5,6\r\n"], "1,2,abc,4,5,6\r\n"],
fieldnames="1 2 3 4 5 6".split()) fieldnames="1 2 3 4 5 6".split())
self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', self.assertEqual(next(reader), {"1": '1', "2": '2', "3": 'abc',
"4": '4', "5": '5', "6": '6'}) "4": '4', "5": '5', "6": '6'})
self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', self.assertEqual(next(reader), {"1": '1', "2": '2', "3": 'abc',
"4": '4', "5": '5', "6": '6'}) "4": '4', "5": '5', "6": '6'})
def test_read_semi_sep(self): def test_read_semi_sep(self):
reader = csv.DictReader(["1;2;abc;4;5;6\r\n"], reader = csv.DictReader(["1;2;abc;4;5;6\r\n"],
fieldnames="1 2 3 4 5 6".split(), fieldnames="1 2 3 4 5 6".split(),
delimiter=';') delimiter=';')
self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', self.assertEqual(next(reader), {"1": '1', "2": '2', "3": 'abc',
"4": '4', "5": '5', "6": '6'}) "4": '4', "5": '5', "6": '6'})
class TestArrayWrites(unittest.TestCase): class TestArrayWrites(unittest.TestCase):

View file

@ -394,13 +394,13 @@ class TestVariousIteratorArgs(unittest.TestCase):
d = deque('abcdefg') d = deque('abcdefg')
it = iter(d) it = iter(d)
d.pop() d.pop()
self.assertRaises(RuntimeError, it.next) self.assertRaises(RuntimeError, next, it)
def test_runtime_error_on_empty_deque(self): def test_runtime_error_on_empty_deque(self):
d = deque() d = deque()
it = iter(d) it = iter(d)
d.append(10) d.append(10)
self.assertRaises(RuntimeError, it.next) self.assertRaises(RuntimeError, next, it)
class Deque(deque): class Deque(deque):
pass pass
@ -567,7 +567,7 @@ deque(['a', 'b', 'd', 'e', 'f'])
... while pending: ... while pending:
... task = pending.popleft() ... task = pending.popleft()
... try: ... try:
... yield task.next() ... yield next(task)
... except StopIteration: ... except StopIteration:
... continue ... continue
... pending.append(task) ... pending.append(task)

View file

@ -144,7 +144,7 @@ class DictTest(unittest.TestCase):
self.i = 1 self.i = 1
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i: if self.i:
self.i = 0 self.i = 0
return 'a' return 'a'
@ -161,7 +161,7 @@ class DictTest(unittest.TestCase):
self.i = ord('a') self.i = ord('a')
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i <= ord('z'): if self.i <= ord('z'):
rtn = chr(self.i) rtn = chr(self.i)
self.i += 1 self.i += 1
@ -175,7 +175,7 @@ class DictTest(unittest.TestCase):
class badseq(object): class badseq(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise Exc() raise Exc()
self.assertRaises(Exc, {}.update, badseq()) self.assertRaises(Exc, {}.update, badseq())
@ -225,7 +225,7 @@ class DictTest(unittest.TestCase):
class BadSeq(object): class BadSeq(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise Exc() raise Exc()
self.assertRaises(Exc, dict.fromkeys, BadSeq()) self.assertRaises(Exc, dict.fromkeys, BadSeq())

View file

@ -16,9 +16,9 @@ class TestSFbugs(unittest.TestCase):
def test_comparing_empty_lists(self): def test_comparing_empty_lists(self):
# Check fix for bug #979794 # Check fix for bug #979794
group_gen = difflib.SequenceMatcher(None, [], []).get_grouped_opcodes() group_gen = difflib.SequenceMatcher(None, [], []).get_grouped_opcodes()
self.assertRaises(StopIteration, group_gen.next) self.assertRaises(StopIteration, next, group_gen)
diff_gen = difflib.unified_diff([], []) diff_gen = difflib.unified_diff([], [])
self.assertRaises(StopIteration, diff_gen.next) self.assertRaises(StopIteration, next, diff_gen)
patch914575_from1 = """ patch914575_from1 = """
1. Beautiful is beTTer than ugly. 1. Beautiful is beTTer than ugly.

View file

@ -17,7 +17,7 @@ class I:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
@ -37,7 +37,7 @@ class X:
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
@ -50,11 +50,11 @@ class E:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
3 // 0 3 // 0
class N: class N:
'Iterator missing next()' 'Iterator missing __next__()'
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
@ -76,17 +76,17 @@ class EnumerateTestCase(unittest.TestCase):
def test_getitemseqn(self): def test_getitemseqn(self):
self.assertEqual(list(self.enum(G(self.seq))), self.res) self.assertEqual(list(self.enum(G(self.seq))), self.res)
e = self.enum(G('')) e = self.enum(G(''))
self.assertRaises(StopIteration, e.next) self.assertRaises(StopIteration, next, e)
def test_iteratorseqn(self): def test_iteratorseqn(self):
self.assertEqual(list(self.enum(I(self.seq))), self.res) self.assertEqual(list(self.enum(I(self.seq))), self.res)
e = self.enum(I('')) e = self.enum(I(''))
self.assertRaises(StopIteration, e.next) self.assertRaises(StopIteration, next, e)
def test_iteratorgenerator(self): def test_iteratorgenerator(self):
self.assertEqual(list(self.enum(Ig(self.seq))), self.res) self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
e = self.enum(Ig('')) e = self.enum(Ig(''))
self.assertRaises(StopIteration, e.next) self.assertRaises(StopIteration, next, e)
def test_noniterable(self): def test_noniterable(self):
self.assertRaises(TypeError, self.enum, X(self.seq)) self.assertRaises(TypeError, self.enum, X(self.seq))

View file

@ -103,7 +103,7 @@ class Nothing:
self.c = 0 self.c = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.c == 4: if self.c == 4:
raise StopIteration raise StopIteration
c = self.c c = self.c

View file

@ -95,7 +95,7 @@ class AutoFileTests(unittest.TestCase):
self.assert_(f.closed) self.assert_(f.closed)
def testMethods(self): def testMethods(self):
methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto', methods = ['fileno', 'flush', 'isatty', '__next__', 'read', 'readinto',
'readline', 'readlines', 'seek', 'tell', 'truncate', 'readline', 'readlines', 'seek', 'tell', 'truncate',
'write', '__iter__'] 'write', '__iter__']
if sys.platform.startswith('atheos'): if sys.platform.startswith('atheos'):
@ -248,7 +248,7 @@ class OtherFileTests(unittest.TestCase):
# Test for appropriate errors mixing read* and iteration # Test for appropriate errors mixing read* and iteration
for methodname, args in methods: for methodname, args in methods:
f = open(TESTFN, 'rb') f = open(TESTFN, 'rb')
if f.next() != filler: if next(f) != filler:
self.fail, "Broken testfile" self.fail, "Broken testfile"
meth = getattr(f, methodname) meth = getattr(f, methodname)
try: try:
@ -269,7 +269,7 @@ class OtherFileTests(unittest.TestCase):
# between 4 and 16384 (inclusive). # between 4 and 16384 (inclusive).
f = open(TESTFN, 'rb') f = open(TESTFN, 'rb')
for i in range(nchunks): for i in range(nchunks):
f.next() next(f)
testline = testlines.pop(0) testline = testlines.pop(0)
try: try:
line = f.readline() line = f.readline()

View file

@ -179,7 +179,7 @@ try:
t2 = writeTmp(2, ["C\nD"]) t2 = writeTmp(2, ["C\nD"])
fi = FileInput(files=(t1, t2)) fi = FileInput(files=(t1, t2))
verify(fi.fileno() == -1) verify(fi.fileno() == -1)
line = fi.next() line = next(fi)
verify(fi.fileno() != -1) verify(fi.fileno() != -1)
fi.nextfile() fi.nextfile()
verify(fi.fileno() == -1) verify(fi.fileno() == -1)

View file

@ -10,14 +10,14 @@ Let's try a simple generator:
1 1
2 2
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
1 1
>>> g.next() >>> next(g)
2 2
"Falling off the end" stops the generator: "Falling off the end" stops the generator:
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
File "<stdin>", line 2, in g File "<stdin>", line 2, in g
@ -31,14 +31,14 @@ Let's try a simple generator:
... yield 2 # never reached ... yield 2 # never reached
... ...
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
1 1
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
File "<stdin>", line 3, in f File "<stdin>", line 3, in f
StopIteration StopIteration
>>> g.next() # once stopped, can't be resumed >>> next(g) # once stopped, can't be resumed
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
StopIteration StopIteration
@ -51,13 +51,13 @@ Let's try a simple generator:
... yield 2 # never reached ... yield 2 # never reached
... ...
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
1 1
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
StopIteration StopIteration
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
StopIteration StopIteration
@ -105,7 +105,7 @@ Generators always return to the most recent caller:
>>> def creator(): >>> def creator():
... r = yrange(5) ... r = yrange(5)
... print("creator", r.next()) ... print("creator", next(r))
... return r ... return r
... ...
>>> def caller(): >>> def caller():
@ -141,10 +141,10 @@ Specification: Yield
running: running:
>>> def g(): >>> def g():
... i = me.next() ... i = next(me)
... yield i ... yield i
>>> me = g() >>> me = g()
>>> me.next() >>> next(me)
Traceback (most recent call last): Traceback (most recent call last):
... ...
File "<string>", line 2, in g File "<string>", line 2, in g
@ -185,13 +185,13 @@ Specification: Generators and Exception Propagation
... yield f() # the zero division exception propagates ... yield f() # the zero division exception propagates
... yield 42 # and we'll never get here ... yield 42 # and we'll never get here
>>> k = g() >>> k = g()
>>> k.next() >>> next(k)
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
File "<stdin>", line 2, in g File "<stdin>", line 2, in g
File "<stdin>", line 2, in f File "<stdin>", line 2, in f
ZeroDivisionError: integer division or modulo by zero ZeroDivisionError: integer division or modulo by zero
>>> k.next() # and the generator cannot be resumed >>> next(k) # and the generator cannot be resumed
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in ? File "<stdin>", line 1, in ?
StopIteration StopIteration
@ -382,9 +382,9 @@ From the Iterators list, about the types of these things.
>>> type(i) >>> type(i)
<type 'generator'> <type 'generator'>
>>> [s for s in dir(i) if not s.startswith('_')] >>> [s for s in dir(i) if not s.startswith('_')]
['close', 'gi_frame', 'gi_running', 'next', 'send', 'throw'] ['close', 'gi_frame', 'gi_running', 'send', 'throw']
>>> print(i.next.__doc__) >>> print(i.__next__.__doc__)
x.next() -> the next value, or raise StopIteration x.__next__() <==> next(x)
>>> iter(i) is i >>> iter(i) is i
True True
>>> import types >>> import types
@ -406,7 +406,7 @@ AttributeError: readonly attribute
>>> me = g() >>> me = g()
>>> me.gi_running >>> me.gi_running
0 0
>>> me.next() >>> next(me)
1 1
>>> me.gi_running >>> me.gi_running
0 0
@ -429,7 +429,7 @@ Subject: Re: PEP 255: Simple Generators
... yield x ... yield x
... ...
... def find(self): ... def find(self):
... return self.generator.next() ... return next(self.generator)
... ...
... def union(self, parent): ... def union(self, parent):
... if self.parent: ... if self.parent:
@ -493,7 +493,7 @@ fun_tests = """
Build up to a recursive Sieve of Eratosthenes generator. Build up to a recursive Sieve of Eratosthenes generator.
>>> def firstn(g, n): >>> def firstn(g, n):
... return [g.next() for i in range(n)] ... return [next(g) for i in range(n)]
>>> def intsfrom(i): >>> def intsfrom(i):
... while 1: ... while 1:
@ -512,7 +512,7 @@ Build up to a recursive Sieve of Eratosthenes generator.
[1, 2, 4, 5, 7, 8] [1, 2, 4, 5, 7, 8]
>>> def sieve(ints): >>> def sieve(ints):
... prime = ints.next() ... prime = next(ints)
... yield prime ... yield prime
... not_divisible_by_prime = exclude_multiples(prime, ints) ... not_divisible_by_prime = exclude_multiples(prime, ints)
... for p in sieve(not_divisible_by_prime): ... for p in sieve(not_divisible_by_prime):
@ -536,19 +536,19 @@ Try writing it without generators, and correctly, and without generating
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100] [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
>>> def merge(g, h): >>> def merge(g, h):
... ng = g.next() ... ng = next(g)
... nh = h.next() ... nh = next(h)
... while 1: ... while 1:
... if ng < nh: ... if ng < nh:
... yield ng ... yield ng
... ng = g.next() ... ng = next(g)
... elif ng > nh: ... elif ng > nh:
... yield nh ... yield nh
... nh = h.next() ... nh = next(h)
... else: ... else:
... yield ng ... yield ng
... ng = g.next() ... ng = next(g)
... nh = h.next() ... nh = next(h)
The following works, but is doing a whale of a lot of redundant work -- The following works, but is doing a whale of a lot of redundant work --
it's not clear how to get the internal uses of m235 to share a single it's not clear how to get the internal uses of m235 to share a single
@ -589,7 +589,7 @@ arguments are iterable -- a LazyList is the same as a generator to times().
>>> class LazyList: >>> class LazyList:
... def __init__(self, g): ... def __init__(self, g):
... self.sofar = [] ... self.sofar = []
... self.fetch = g.next ... self.fetch = g.__next__
... ...
... def __getitem__(self, i): ... def __getitem__(self, i):
... sofar, fetch = self.sofar, self.fetch ... sofar, fetch = self.sofar, self.fetch
@ -626,10 +626,10 @@ Ye olde Fibonacci generator, LazyList style.
... ...
... def sum(g, h): ... def sum(g, h):
... while 1: ... while 1:
... yield g.next() + h.next() ... yield next(g) + next(h)
... ...
... def tail(g): ... def tail(g):
... g.next() # throw first away ... next(g) # throw first away
... for x in g: ... for x in g:
... yield x ... yield x
... ...
@ -705,12 +705,12 @@ Ye olde Fibonacci generator, tee style.
... ...
... def _isum(g, h): ... def _isum(g, h):
... while 1: ... while 1:
... yield g.next() + h.next() ... yield next(g) + next(h)
... ...
... def _fib(): ... def _fib():
... yield 1 ... yield 1
... yield 2 ... yield 2
... fibTail.next() # throw first away ... next(fibTail) # throw first away
... for res in _isum(fibHead, fibTail): ... for res in _isum(fibHead, fibTail):
... yield res ... yield res
... ...
@ -890,13 +890,13 @@ This one caused a crash (see SF bug 567538):
... yield i ... yield i
... ...
>>> g = f() >>> g = f()
>>> print(g.next()) >>> print(next(g))
0 0
>>> print(g.next()) >>> print(next(g))
1 1
>>> print(g.next()) >>> print(next(g))
2 2
>>> print(g.next()) >>> print(next(g))
Traceback (most recent call last): Traceback (most recent call last):
StopIteration StopIteration
""" """
@ -1013,7 +1013,7 @@ def flat_conjoin(gs): # rename to conjoin to run tests with this instead
# Descend. # Descend.
try: try:
while i < n: while i < n:
it = iters[i] = gs[i]().next it = iters[i] = gs[i]().__next__
values[i] = it() values[i] = it()
i += 1 i += 1
except _StopIteration: except _StopIteration:
@ -1463,7 +1463,7 @@ Sending a value into a started generator:
... print((yield 1)) ... print((yield 1))
... yield 2 ... yield 2
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
1 1
>>> g.send(42) >>> g.send(42)
42 42
@ -1506,7 +1506,7 @@ A yield expression with augmented assignment.
... seq.append(count) ... seq.append(count)
>>> seq = [] >>> seq = []
>>> c = coroutine(seq) >>> c = coroutine(seq)
>>> c.next() >>> next(c)
>>> print(seq) >>> print(seq)
[] []
>>> c.send(10) >>> c.send(10)
@ -1558,7 +1558,7 @@ Now check some throw() conditions:
... print("caught ValueError (%s)" % (v)) ... print("caught ValueError (%s)" % (v))
>>> import sys >>> import sys
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
>>> g.throw(ValueError) # type only >>> g.throw(ValueError) # type only
caught ValueError () caught ValueError ()
@ -1642,7 +1642,7 @@ Now let's try closing a generator:
... print("exiting") ... print("exiting")
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
>>> g.close() >>> g.close()
exiting exiting
>>> g.close() # should be no-op now >>> g.close() # should be no-op now
@ -1652,7 +1652,7 @@ exiting
>>> def f(): yield # an even simpler generator >>> def f(): yield # an even simpler generator
>>> f().close() # close before opening >>> f().close() # close before opening
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
>>> g.close() # close normally >>> g.close() # close normally
And finalization: And finalization:
@ -1663,7 +1663,7 @@ And finalization:
... print("exiting") ... print("exiting")
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
>>> del g >>> del g
exiting exiting
@ -1675,7 +1675,7 @@ Now let's try some ill-behaved generators:
... except GeneratorExit: ... except GeneratorExit:
... yield "foo!" ... yield "foo!"
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
>>> g.close() >>> g.close()
Traceback (most recent call last): Traceback (most recent call last):
... ...
@ -1688,7 +1688,7 @@ Our ill-behaved code should be invoked during GC:
>>> import sys, StringIO >>> import sys, StringIO
>>> old, sys.stderr = sys.stderr, StringIO.StringIO() >>> old, sys.stderr = sys.stderr, StringIO.StringIO()
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
>>> del g >>> del g
>>> sys.stderr.getvalue().startswith( >>> sys.stderr.getvalue().startswith(
... "Exception RuntimeError: 'generator ignored GeneratorExit' in " ... "Exception RuntimeError: 'generator ignored GeneratorExit' in "
@ -1704,7 +1704,7 @@ And errors thrown during closing should propagate:
... except GeneratorExit: ... except GeneratorExit:
... raise TypeError("fie!") ... raise TypeError("fie!")
>>> g = f() >>> g = f()
>>> g.next() >>> next(g)
>>> g.close() >>> g.close()
Traceback (most recent call last): Traceback (most recent call last):
... ...
@ -1760,7 +1760,7 @@ would trigger if it starts being uncleanable again.
... class gen: ... class gen:
... def __iter__(self): ... def __iter__(self):
... return self ... return self
... def next(self): ... def __next__(self):
... return self.item ... return self.item
... g = gen() ... g = gen()
... head, tail = itertools.tee(g) ... head, tail = itertools.tee(g)
@ -1771,7 +1771,7 @@ would trigger if it starts being uncleanable again.
Make sure to also test the involvement of the tee-internal teedataobject, Make sure to also test the involvement of the tee-internal teedataobject,
which stores returned items. which stores returned items.
>>> item = it.next() >>> item = next(it)

View file

@ -34,24 +34,24 @@ Test first class
Test direct calls to next() Test direct calls to next()
>>> g = (i*i for i in range(3)) >>> g = (i*i for i in range(3))
>>> g.next() >>> next(g)
0 0
>>> g.next() >>> next(g)
1 1
>>> g.next() >>> next(g)
4 4
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<pyshell#21>", line 1, in -toplevel- File "<pyshell#21>", line 1, in -toplevel-
g.next() next(g)
StopIteration StopIteration
Does it stay stopped? Does it stay stopped?
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<pyshell#21>", line 1, in -toplevel- File "<pyshell#21>", line 1, in -toplevel-
g.next() next(g)
StopIteration StopIteration
>>> list(g) >>> list(g)
[] []
@ -157,7 +157,7 @@ Generators always return to the most recent caller:
>>> def creator(): >>> def creator():
... r = yrange(5) ... r = yrange(5)
... print("creator", r.next()) ... print("creator", next(r))
... return r ... return r
>>> def caller(): >>> def caller():
... r = creator() ... r = creator()
@ -181,32 +181,32 @@ Generators can call other generators:
Verify that a gen exp cannot be resumed while it is actively running: Verify that a gen exp cannot be resumed while it is actively running:
>>> g = (me.next() for i in xrange(10)) >>> g = (next(me) for i in xrange(10))
>>> me = g >>> me = g
>>> me.next() >>> next(me)
Traceback (most recent call last): Traceback (most recent call last):
File "<pyshell#30>", line 1, in -toplevel- File "<pyshell#30>", line 1, in -toplevel-
me.next() next(me)
File "<pyshell#28>", line 1, in <generator expression> File "<pyshell#28>", line 1, in <generator expression>
g = (me.next() for i in xrange(10)) g = (next(me) for i in xrange(10))
ValueError: generator already executing ValueError: generator already executing
Verify exception propagation Verify exception propagation
>>> g = (10 // i for i in (5, 0, 2)) >>> g = (10 // i for i in (5, 0, 2))
>>> g.next() >>> next(g)
2 2
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<pyshell#37>", line 1, in -toplevel- File "<pyshell#37>", line 1, in -toplevel-
g.next() next(g)
File "<pyshell#35>", line 1, in <generator expression> File "<pyshell#35>", line 1, in <generator expression>
g = (10 // i for i in (5, 0, 2)) g = (10 // i for i in (5, 0, 2))
ZeroDivisionError: integer division or modulo by zero ZeroDivisionError: integer division or modulo by zero
>>> g.next() >>> next(g)
Traceback (most recent call last): Traceback (most recent call last):
File "<pyshell#38>", line 1, in -toplevel- File "<pyshell#38>", line 1, in -toplevel-
g.next() next(g)
StopIteration StopIteration
Make sure that None is a valid return value Make sure that None is a valid return value
@ -217,12 +217,12 @@ Make sure that None is a valid return value
Check that generator attributes are present Check that generator attributes are present
>>> g = (i*i for i in range(3)) >>> g = (i*i for i in range(3))
>>> expected = set(['gi_frame', 'gi_running', 'next']) >>> expected = set(['gi_frame', 'gi_running'])
>>> set(attr for attr in dir(g) if not attr.startswith('__')) >= expected >>> set(attr for attr in dir(g) if not attr.startswith('__')) >= expected
True True
>>> print(g.next.__doc__) >>> print(g.__next__.__doc__)
x.next() -> the next value, or raise StopIteration x.__next__() <==> next(x)
>>> import types >>> import types
>>> isinstance(g, types.GeneratorType) >>> isinstance(g, types.GeneratorType)
True True
@ -238,7 +238,7 @@ Verify that the running flag is set properly
>>> me = g >>> me = g
>>> me.gi_running >>> me.gi_running
0 0
>>> me.next() >>> next(me)
1 1
>>> me.gi_running >>> me.gi_running
0 0

View file

@ -785,9 +785,9 @@ class GrammarTests(unittest.TestCase):
def testGenexps(self): def testGenexps(self):
# generator expression tests # generator expression tests
g = ([x for x in range(10)] for x in range(1)) g = ([x for x in range(10)] for x in range(1))
self.assertEqual(g.next(), [x for x in range(10)]) self.assertEqual(next(g), [x for x in range(10)])
try: try:
g.next() next(g)
self.fail('should produce StopIteration exception') self.fail('should produce StopIteration exception')
except StopIteration: except StopIteration:
pass pass
@ -795,7 +795,7 @@ class GrammarTests(unittest.TestCase):
a = 1 a = 1
try: try:
g = (a for d in a) g = (a for d in a)
g.next() next(g)
self.fail('should produce TypeError') self.fail('should produce TypeError')
except TypeError: except TypeError:
pass pass

View file

@ -180,7 +180,7 @@ class I:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
@ -200,14 +200,14 @@ class X:
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
return v return v
class N: class N:
'Iterator missing next()' 'Iterator missing __next__()'
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
@ -221,7 +221,7 @@ class E:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
3 // 0 3 // 0
class S: class S:
@ -230,7 +230,7 @@ class S:
pass pass
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise StopIteration raise StopIteration
from itertools import chain, imap from itertools import chain, imap

View file

@ -22,7 +22,7 @@ class BasicIterClass:
def __init__(self, n): def __init__(self, n):
self.n = n self.n = n
self.i = 0 self.i = 0
def next(self): def __next__(self):
res = self.i res = self.i
if res >= self.n: if res >= self.n:
raise StopIteration raise StopIteration
@ -53,7 +53,7 @@ class TestCase(unittest.TestCase):
res = [] res = []
while 1: while 1:
try: try:
val = it.next() val = next(it)
except StopIteration: except StopIteration:
break break
res.append(val) res.append(val)
@ -342,7 +342,7 @@ class TestCase(unittest.TestCase):
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
i = self.i i = self.i
self.i = i + 1 self.i = i + 1
if i < len(self.vals): if i < len(self.vals):
@ -447,7 +447,7 @@ class TestCase(unittest.TestCase):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
i = self.i i = self.i
self.i = i+1 self.i = i+1
return i return i
@ -514,12 +514,12 @@ class TestCase(unittest.TestCase):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
i = self.i i = self.i
self.i = i+1 self.i = i+1
if i == 2: if i == 2:
return unicode("fooled you!") return unicode("fooled you!")
return self.it.next() return next(self.it)
f = open(TESTFN, "w") f = open(TESTFN, "w")
try: try:
@ -682,7 +682,7 @@ class TestCase(unittest.TestCase):
self.finish = finish self.finish = finish
self.i = self.start self.i = self.start
def next(self): def __next__(self):
if self.i >= self.finish: if self.i >= self.finish:
raise StopIteration raise StopIteration
result = str(self.i) + '\n' result = str(self.i) + '\n'

View file

@ -10,7 +10,7 @@ The desired invariant is: len(it)==len(list(it)).
A complication is that an iterable and iterator can be the same object. To A complication is that an iterable and iterator can be the same object. To
maintain the invariant, an iterator needs to dynamically update its length. maintain the invariant, an iterator needs to dynamically update its length.
For instance, an iterable such as xrange(10) always reports its length as ten, For instance, an iterable such as xrange(10) always reports its length as ten,
but it=iter(xrange(10)) starts at ten, and then goes to nine after it.next(). but it=iter(xrange(10)) starts at ten, and then goes to nine after next(it).
Having this capability means that map() can ignore the distinction between Having this capability means that map() can ignore the distinction between
map(func, iterable) and map(func, iter(iterable)). map(func, iterable) and map(func, iter(iterable)).
@ -67,9 +67,9 @@ class TestInvariantWithoutMutations(unittest.TestCase):
it = self.it it = self.it
for i in reversed(xrange(1, n+1)): for i in reversed(xrange(1, n+1)):
self.assertEqual(len(it), i) self.assertEqual(len(it), i)
it.next() next(it)
self.assertEqual(len(it), 0) self.assertEqual(len(it), 0)
self.assertRaises(StopIteration, it.next) self.assertRaises(StopIteration, next, it)
self.assertEqual(len(it), 0) self.assertEqual(len(it), 0)
class TestTemporarilyImmutable(TestInvariantWithoutMutations): class TestTemporarilyImmutable(TestInvariantWithoutMutations):
@ -80,10 +80,10 @@ class TestTemporarilyImmutable(TestInvariantWithoutMutations):
it = self.it it = self.it
self.assertEqual(len(it), n) self.assertEqual(len(it), n)
it.next() next(it)
self.assertEqual(len(it), n-1) self.assertEqual(len(it), n-1)
self.mutate() self.mutate()
self.assertRaises(RuntimeError, it.next) self.assertRaises(RuntimeError, next, it)
self.assertEqual(len(it), 0) self.assertEqual(len(it), 0)
## ------- Concrete Type Tests ------- ## ------- Concrete Type Tests -------
@ -166,8 +166,8 @@ class TestList(TestInvariantWithoutMutations):
def test_mutation(self): def test_mutation(self):
d = range(n) d = range(n)
it = iter(d) it = iter(d)
it.next() next(it)
it.next() next(it)
self.assertEqual(len(it), n-2) self.assertEqual(len(it), n-2)
d.append(n) d.append(n)
self.assertEqual(len(it), n-1) # grow with append self.assertEqual(len(it), n-1) # grow with append
@ -185,8 +185,8 @@ class TestListReversed(TestInvariantWithoutMutations):
def test_mutation(self): def test_mutation(self):
d = range(n) d = range(n)
it = reversed(d) it = reversed(d)
it.next() next(it)
it.next() next(it)
self.assertEqual(len(it), n-2) self.assertEqual(len(it), n-2)
d.append(n) d.append(n)
self.assertEqual(len(it), n-2) # ignore append self.assertEqual(len(it), n-2) # ignore append
@ -204,8 +204,8 @@ class TestSeqIter(TestInvariantWithoutMutations):
def test_mutation(self): def test_mutation(self):
d = UserList(range(n)) d = UserList(range(n))
it = iter(d) it = iter(d)
it.next() next(it)
it.next() next(it)
self.assertEqual(len(it), n-2) self.assertEqual(len(it), n-2)
d.append(n) d.append(n)
self.assertEqual(len(it), n-1) # grow with append self.assertEqual(len(it), n-1) # grow with append
@ -223,8 +223,8 @@ class TestSeqIterReversed(TestInvariantWithoutMutations):
def test_mutation(self): def test_mutation(self):
d = UserList(range(n)) d = UserList(range(n))
it = reversed(d) it = reversed(d)
it.next() next(it)
it.next() next(it)
self.assertEqual(len(it), n-2) self.assertEqual(len(it), n-2)
d.append(n) d.append(n)
self.assertEqual(len(it), n-2) # ignore append self.assertEqual(len(it), n-2) # ignore append

View file

@ -34,7 +34,7 @@ class StopNow:
'Class emulating an empty iterable.' 'Class emulating an empty iterable.'
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise StopIteration raise StopIteration
def take(n, seq): def take(n, seq):
@ -58,12 +58,12 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(OverflowError, list, islice(count(sys.maxint-5), 10)) self.assertRaises(OverflowError, list, islice(count(sys.maxint-5), 10))
c = count(3) c = count(3)
self.assertEqual(repr(c), 'count(3)') self.assertEqual(repr(c), 'count(3)')
c.next() next(c)
self.assertEqual(repr(c), 'count(4)') self.assertEqual(repr(c), 'count(4)')
c = count(-9) c = count(-9)
self.assertEqual(repr(c), 'count(-9)') self.assertEqual(repr(c), 'count(-9)')
c.next() next(c)
self.assertEqual(c.next(), -8) self.assertEqual(next(c), -8)
def test_cycle(self): def test_cycle(self):
self.assertEqual(take(10, cycle('abc')), list('abcabcabca')) self.assertEqual(take(10, cycle('abc')), list('abcabcabca'))
@ -121,7 +121,7 @@ class TestBasicOps(unittest.TestCase):
r = sorted([(len(list(g)) , k) for k, g in groupby(sorted(s))], reverse=True)[:3] r = sorted([(len(list(g)) , k) for k, g in groupby(sorted(s))], reverse=True)[:3]
self.assertEqual(r, [(5, 'a'), (2, 'r'), (2, 'b')]) self.assertEqual(r, [(5, 'a'), (2, 'r'), (2, 'b')])
# iter.next failure # iter.__next__ failure
class ExpectedError(Exception): class ExpectedError(Exception):
pass pass
def delayed_raise(n=0): def delayed_raise(n=0):
@ -131,9 +131,9 @@ class TestBasicOps(unittest.TestCase):
def gulp(iterable, keyp=None, func=list): def gulp(iterable, keyp=None, func=list):
return [func(g) for k, g in groupby(iterable, keyp)] return [func(g) for k, g in groupby(iterable, keyp)]
# iter.next failure on outer object # iter.__next__ failure on outer object
self.assertRaises(ExpectedError, gulp, delayed_raise(0)) self.assertRaises(ExpectedError, gulp, delayed_raise(0))
# iter.next failure on inner object # iter.__next__ failure on inner object
self.assertRaises(ExpectedError, gulp, delayed_raise(1)) self.assertRaises(ExpectedError, gulp, delayed_raise(1))
# __cmp__ failure # __cmp__ failure
@ -169,7 +169,7 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(TypeError, ifilter, lambda x:x) self.assertRaises(TypeError, ifilter, lambda x:x)
self.assertRaises(TypeError, ifilter, lambda x:x, range(6), 7) self.assertRaises(TypeError, ifilter, lambda x:x, range(6), 7)
self.assertRaises(TypeError, ifilter, isEven, 3) self.assertRaises(TypeError, ifilter, isEven, 3)
self.assertRaises(TypeError, ifilter(range(6), range(6)).next) self.assertRaises(TypeError, next, ifilter(range(6), range(6)))
def test_ifilterfalse(self): def test_ifilterfalse(self):
self.assertEqual(list(ifilterfalse(isEven, range(6))), [1,3,5]) self.assertEqual(list(ifilterfalse(isEven, range(6))), [1,3,5])
@ -179,7 +179,7 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(TypeError, ifilterfalse, lambda x:x) self.assertRaises(TypeError, ifilterfalse, lambda x:x)
self.assertRaises(TypeError, ifilterfalse, lambda x:x, range(6), 7) self.assertRaises(TypeError, ifilterfalse, lambda x:x, range(6), 7)
self.assertRaises(TypeError, ifilterfalse, isEven, 3) self.assertRaises(TypeError, ifilterfalse, isEven, 3)
self.assertRaises(TypeError, ifilterfalse(range(6), range(6)).next) self.assertRaises(TypeError, next, ifilterfalse(range(6), range(6)))
def test_izip(self): def test_izip(self):
# XXX This is rather silly now that builtin zip() calls izip()... # XXX This is rather silly now that builtin zip() calls izip()...
@ -276,9 +276,9 @@ class TestBasicOps(unittest.TestCase):
self.assertEqual(list(imap(operator.pow, [])), []) self.assertEqual(list(imap(operator.pow, [])), [])
self.assertRaises(TypeError, imap) self.assertRaises(TypeError, imap)
self.assertRaises(TypeError, imap, operator.neg) self.assertRaises(TypeError, imap, operator.neg)
self.assertRaises(TypeError, imap(10, range(5)).next) self.assertRaises(TypeError, next, imap(10, range(5)))
self.assertRaises(ValueError, imap(errfunc, [4], [5]).next) self.assertRaises(ValueError, next, imap(errfunc, [4], [5]))
self.assertRaises(TypeError, imap(onearg, [4], [5]).next) self.assertRaises(TypeError, next, imap(onearg, [4], [5]))
def test_starmap(self): def test_starmap(self):
self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
@ -289,9 +289,9 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(TypeError, list, starmap(operator.pow, [[4,5]])) self.assertRaises(TypeError, list, starmap(operator.pow, [[4,5]]))
self.assertRaises(TypeError, starmap) self.assertRaises(TypeError, starmap)
self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra') self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra')
self.assertRaises(TypeError, starmap(10, [(4,5)]).next) self.assertRaises(TypeError, next, starmap(10, [(4,5)]))
self.assertRaises(ValueError, starmap(errfunc, [(4,5)]).next) self.assertRaises(ValueError, next, starmap(errfunc, [(4,5)]))
self.assertRaises(TypeError, starmap(onearg, [(4,5)]).next) self.assertRaises(TypeError, next, starmap(onearg, [(4,5)]))
def test_islice(self): def test_islice(self):
for args in [ # islice(args) should agree with range(args) for args in [ # islice(args) should agree with range(args)
@ -344,11 +344,11 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(TypeError, takewhile) self.assertRaises(TypeError, takewhile)
self.assertRaises(TypeError, takewhile, operator.pow) self.assertRaises(TypeError, takewhile, operator.pow)
self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra') self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra')
self.assertRaises(TypeError, takewhile(10, [(4,5)]).next) self.assertRaises(TypeError, next, takewhile(10, [(4,5)]))
self.assertRaises(ValueError, takewhile(errfunc, [(4,5)]).next) self.assertRaises(ValueError, next, takewhile(errfunc, [(4,5)]))
t = takewhile(bool, [1, 1, 1, 0, 0, 0]) t = takewhile(bool, [1, 1, 1, 0, 0, 0])
self.assertEqual(list(t), [1, 1, 1]) self.assertEqual(list(t), [1, 1, 1])
self.assertRaises(StopIteration, t.next) self.assertRaises(StopIteration, next, t)
def test_dropwhile(self): def test_dropwhile(self):
data = [1, 3, 5, 20, 2, 4, 6, 8] data = [1, 3, 5, 20, 2, 4, 6, 8]
@ -358,8 +358,8 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(TypeError, dropwhile) self.assertRaises(TypeError, dropwhile)
self.assertRaises(TypeError, dropwhile, operator.pow) self.assertRaises(TypeError, dropwhile, operator.pow)
self.assertRaises(TypeError, dropwhile, operator.pow, [(4,5)], 'extra') self.assertRaises(TypeError, dropwhile, operator.pow, [(4,5)], 'extra')
self.assertRaises(TypeError, dropwhile(10, [(4,5)]).next) self.assertRaises(TypeError, next, dropwhile(10, [(4,5)]))
self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next) self.assertRaises(ValueError, next, dropwhile(errfunc, [(4,5)]))
def test_tee(self): def test_tee(self):
n = 200 n = 200
@ -380,13 +380,13 @@ class TestBasicOps(unittest.TestCase):
a, b = tee(irange(n)) # test dealloc of leading iterator a, b = tee(irange(n)) # test dealloc of leading iterator
for i in xrange(100): for i in xrange(100):
self.assertEqual(a.next(), i) self.assertEqual(next(a), i)
del a del a
self.assertEqual(list(b), range(n)) self.assertEqual(list(b), range(n))
a, b = tee(irange(n)) # test dealloc of trailing iterator a, b = tee(irange(n)) # test dealloc of trailing iterator
for i in xrange(100): for i in xrange(100):
self.assertEqual(a.next(), i) self.assertEqual(next(a), i)
del b del b
self.assertEqual(list(a), range(100, n)) self.assertEqual(list(a), range(100, n))
@ -396,7 +396,7 @@ class TestBasicOps(unittest.TestCase):
lists = ([], []) lists = ([], [])
its = tee(irange(n)) its = tee(irange(n))
for i in order: for i in order:
value = its[i].next() value = next(its[i])
lists[i].append(value) lists[i].append(value)
self.assertEqual(lists[0], range(n)) self.assertEqual(lists[0], range(n))
self.assertEqual(lists[1], range(n)) self.assertEqual(lists[1], range(n))
@ -415,9 +415,9 @@ class TestBasicOps(unittest.TestCase):
# test long-lagged and multi-way split # test long-lagged and multi-way split
a, b, c = tee(xrange(2000), 3) a, b, c = tee(xrange(2000), 3)
for i in xrange(100): for i in xrange(100):
self.assertEqual(a.next(), i) self.assertEqual(next(a), i)
self.assertEqual(list(b), range(2000)) self.assertEqual(list(b), range(2000))
self.assertEqual([c.next(), c.next()], range(2)) self.assertEqual([next(c), next(c)], range(2))
self.assertEqual(list(a), range(100,2000)) self.assertEqual(list(a), range(100,2000))
self.assertEqual(list(c), range(2,2000)) self.assertEqual(list(c), range(2,2000))
@ -451,33 +451,33 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(ReferenceError, getattr, p, '__class__') self.assertRaises(ReferenceError, getattr, p, '__class__')
def test_StopIteration(self): def test_StopIteration(self):
self.assertRaises(StopIteration, izip().next) self.assertRaises(StopIteration, next, izip())
for f in (chain, cycle, izip, groupby): for f in (chain, cycle, izip, groupby):
self.assertRaises(StopIteration, f([]).next) self.assertRaises(StopIteration, next, f([]))
self.assertRaises(StopIteration, f(StopNow()).next) self.assertRaises(StopIteration, next, f(StopNow()))
self.assertRaises(StopIteration, islice([], None).next) self.assertRaises(StopIteration, next, islice([], None))
self.assertRaises(StopIteration, islice(StopNow(), None).next) self.assertRaises(StopIteration, next, islice(StopNow(), None))
p, q = tee([]) p, q = tee([])
self.assertRaises(StopIteration, p.next) self.assertRaises(StopIteration, next, p)
self.assertRaises(StopIteration, q.next) self.assertRaises(StopIteration, next, q)
p, q = tee(StopNow()) p, q = tee(StopNow())
self.assertRaises(StopIteration, p.next) self.assertRaises(StopIteration, next, p)
self.assertRaises(StopIteration, q.next) self.assertRaises(StopIteration, next, q)
self.assertRaises(StopIteration, repeat(None, 0).next) self.assertRaises(StopIteration, next, repeat(None, 0))
for f in (ifilter, ifilterfalse, imap, takewhile, dropwhile, starmap): for f in (ifilter, ifilterfalse, imap, takewhile, dropwhile, starmap):
self.assertRaises(StopIteration, f(lambda x:x, []).next) self.assertRaises(StopIteration, next, f(lambda x:x, []))
self.assertRaises(StopIteration, f(lambda x:x, StopNow()).next) self.assertRaises(StopIteration, next, f(lambda x:x, StopNow()))
class TestGC(unittest.TestCase): class TestGC(unittest.TestCase):
def makecycle(self, iterator, container): def makecycle(self, iterator, container):
container.append(iterator) container.append(iterator)
iterator.next() next(iterator)
del container, iterator del container, iterator
def test_chain(self): def test_chain(self):
@ -547,7 +547,7 @@ class I:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
@ -567,14 +567,14 @@ class X:
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
return v return v
class N: class N:
'Iterator missing next()' 'Iterator missing __next__()'
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
@ -588,7 +588,7 @@ class E:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
3 // 0 3 // 0
class S: class S:
@ -597,7 +597,7 @@ class S:
pass pass
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise StopIteration raise StopIteration
def L(seqn): def L(seqn):
@ -748,13 +748,13 @@ class RegressionTests(unittest.TestCase):
def g(value, first=[1]): def g(value, first=[1]):
if first: if first:
del first[:] del first[:]
f(z.next()) f(next(z))
return value return value
items = list(tuple2) items = list(tuple2)
items[1:1] = list(tuple1) items[1:1] = list(tuple1)
gen = imap(g, items) gen = imap(g, items)
z = izip(*[gen]*len(tuple1)) z = izip(*[gen]*len(tuple1))
z.next() next(z)
def f(t): def f(t):
global T global T
@ -930,7 +930,7 @@ Samuele
... "s -> (s0,s1), (s1,s2), (s2, s3), ..." ... "s -> (s0,s1), (s1,s2), (s2, s3), ..."
... a, b = tee(iterable) ... a, b = tee(iterable)
... try: ... try:
... b.next() ... next(b)
... except StopIteration: ... except StopIteration:
... pass ... pass
... return izip(a, b) ... return izip(a, b)

View file

@ -1518,11 +1518,11 @@ class TestProxyFileBase(TestBase):
# Iterate by line # Iterate by line
proxy.seek(0) proxy.seek(0)
iterator = iter(proxy) iterator = iter(proxy)
self.assert_(iterator.next() == 'foo' + os.linesep) self.assert_(next(iterator) == 'foo' + os.linesep)
self.assert_(iterator.next() == 'bar' + os.linesep) self.assert_(next(iterator) == 'bar' + os.linesep)
self.assert_(iterator.next() == 'fred' + os.linesep) self.assert_(next(iterator) == 'fred' + os.linesep)
self.assert_(iterator.next() == 'bob') self.assert_(next(iterator) == 'bob')
self.assertRaises(StopIteration, lambda: iterator.next()) self.assertRaises(StopIteration, next, iterator)
def _test_seek_and_tell(self, proxy): def _test_seek_and_tell(self, proxy):
# Seek and use tell to check position # Seek and use tell to check position

View file

@ -586,8 +586,8 @@ class ReTests(unittest.TestCase):
def test_bug_581080(self): def test_bug_581080(self):
iter = re.finditer(r"\s", "a b") iter = re.finditer(r"\s", "a b")
self.assertEqual(iter.next().span(), (1,2)) self.assertEqual(next(iter).span(), (1,2))
self.assertRaises(StopIteration, iter.next) self.assertRaises(StopIteration, next, iter)
scanner = re.compile(r"\s").scanner("a b") scanner = re.compile(r"\s").scanner("a b")
self.assertEqual(scanner.search().span(), (1, 2)) self.assertEqual(scanner.search().span(), (1, 2))
@ -595,9 +595,9 @@ class ReTests(unittest.TestCase):
def test_bug_817234(self): def test_bug_817234(self):
iter = re.finditer(r".*", "asdf") iter = re.finditer(r".*", "asdf")
self.assertEqual(iter.next().span(), (0, 4)) self.assertEqual(next(iter).span(), (0, 4))
self.assertEqual(iter.next().span(), (4, 4)) self.assertEqual(next(iter).span(), (4, 4))
self.assertRaises(StopIteration, iter.next) self.assertRaises(StopIteration, next, iter)
def run_re_tests(): def run_re_tests():

View file

@ -1382,7 +1382,7 @@ class I:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
@ -1402,14 +1402,14 @@ class X:
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
def next(self): def __next__(self):
if self.i >= len(self.seqn): raise StopIteration if self.i >= len(self.seqn): raise StopIteration
v = self.seqn[self.i] v = self.seqn[self.i]
self.i += 1 self.i += 1
return v return v
class N: class N:
'Iterator missing next()' 'Iterator missing __next__()'
def __init__(self, seqn): def __init__(self, seqn):
self.seqn = seqn self.seqn = seqn
self.i = 0 self.i = 0
@ -1423,7 +1423,7 @@ class E:
self.i = 0 self.i = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
3 // 0 3 // 0
class S: class S:
@ -1432,7 +1432,7 @@ class S:
pass pass
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise StopIteration raise StopIteration
from itertools import chain, imap from itertools import chain, imap

View file

@ -22,10 +22,10 @@ class StrTest(
def test_iterators(self): def test_iterators(self):
# Make sure str objects have an __iter__ method # Make sure str objects have an __iter__ method
it = "abc".__iter__() it = "abc".__iter__()
self.assertEqual(it.next(), "a") self.assertEqual(next(it), "a")
self.assertEqual(it.next(), "b") self.assertEqual(next(it), "b")
self.assertEqual(it.next(), "c") self.assertEqual(next(it), "c")
self.assertRaises(StopIteration, it.next) self.assertRaises(StopIteration, next, it)
def test_conversion(self): def test_conversion(self):
# Make sure __str__() behaves properly # Make sure __str__() behaves properly

View file

@ -102,7 +102,7 @@ class test__RandomNameSequence(TC):
def test_get_six_char_str(self): def test_get_six_char_str(self):
# _RandomNameSequence returns a six-character string # _RandomNameSequence returns a six-character string
s = self.r.next() s = next(self.r)
self.nameCheck(s, '', '', '') self.nameCheck(s, '', '', '')
def test_many(self): def test_many(self):
@ -111,7 +111,7 @@ class test__RandomNameSequence(TC):
dict = {} dict = {}
r = self.r r = self.r
for i in xrange(TEST_FILES): for i in xrange(TEST_FILES):
s = r.next() s = next(r)
self.nameCheck(s, '', '', '') self.nameCheck(s, '', '', '')
self.failIf(s in dict) self.failIf(s in dict)
dict[s] = 1 dict[s] = 1

View file

@ -103,7 +103,7 @@ def test_roundtrip(f):
t1 = [tok[:2] for tok in fulltok] t1 = [tok[:2] for tok in fulltok]
newtext = untokenize(t1) newtext = untokenize(t1)
readline = iter(newtext.splitlines(1)).next readline = iter(newtext.splitlines(1)).__next__
t2 = [tok[:2] for tok in generate_tokens(readline)] t2 = [tok[:2] for tok in generate_tokens(readline)]
if t1 != t2: if t1 != t2:
raise TestFailed("untokenize() roundtrip failed for %r" % f) raise TestFailed("untokenize() roundtrip failed for %r" % f)
@ -224,7 +224,7 @@ def test_rarrow():
This function exists solely to test the tokenization of the RARROW This function exists solely to test the tokenization of the RARROW
operator. operator.
>>> tokenize(iter(['->']).next) #doctest: +NORMALIZE_WHITESPACE >>> tokenize(iter(['->']).__next__) #doctest: +NORMALIZE_WHITESPACE
1,0-1,2:\tOP\t'->' 1,0-1,2:\tOP\t'->'
2,0-2,0:\tENDMARKER\t'' 2,0-2,0:\tENDMARKER\t''
""" """

View file

@ -99,10 +99,10 @@ class UnicodeTest(
def test_iterators(self): def test_iterators(self):
# Make sure unicode objects have an __iter__ method # Make sure unicode objects have an __iter__ method
it = u"\u1111\u2222\u3333".__iter__() it = u"\u1111\u2222\u3333".__iter__()
self.assertEqual(it.next(), u"\u1111") self.assertEqual(next(it), u"\u1111")
self.assertEqual(it.next(), u"\u2222") self.assertEqual(next(it), u"\u2222")
self.assertEqual(it.next(), u"\u3333") self.assertEqual(next(it), u"\u3333")
self.assertRaises(StopIteration, it.next) self.assertRaises(StopIteration, next, it)
def test_count(self): def test_count(self):
string_tests.CommonTest.test_count(self) string_tests.CommonTest.test_count(self)

View file

@ -51,7 +51,7 @@ class UserListTest(list_tests.CommonTest):
class T(self.type2test): class T(self.type2test):
def __getitem__(self, key): def __getitem__(self, key):
return str(key) + '!!!' return str(key) + '!!!'
self.assertEqual(iter(T((1,2))).next(), "0!!!") self.assertEqual(next(iter(T((1,2)))), "0!!!")
def test_main(): def test_main():
test_support.run_unittest(UserListTest) test_support.run_unittest(UserListTest)

View file

@ -108,13 +108,13 @@ def compare_generic_iter(make_it,match):
it = make_it() it = make_it()
if not iter(it) is it: raise AssertionError if not iter(it) is it: raise AssertionError
for item in match: for item in match:
if not it.next()==item: raise AssertionError if not next(it) == item: raise AssertionError
try: try:
it.next() next(it)
except StopIteration: except StopIteration:
pass pass
else: else:
raise AssertionError("Too many items from .next()",it) raise AssertionError("Too many items from .__next__()", it)

View file

@ -228,7 +228,7 @@ def untokenize(iterable):
# Output text will tokenize the back to the input # Output text will tokenize the back to the input
t1 = [tok[:2] for tok in generate_tokens(f.readline)] t1 = [tok[:2] for tok in generate_tokens(f.readline)]
newcode = untokenize(t1) newcode = untokenize(t1)
readline = iter(newcode.splitlines(1)).next readline = iter(newcode.splitlines(1)).__next__
t2 = [tok[:2] for tokin generate_tokens(readline)] t2 = [tok[:2] for tokin generate_tokens(readline)]
assert t1 == t2 assert t1 == t2
""" """
@ -242,7 +242,7 @@ def generate_tokens(readline):
readline() method of built-in file objects. Each call to the function readline() method of built-in file objects. Each call to the function
should return one line of input as a string. Alternately, readline should return one line of input as a string. Alternately, readline
can be a callable function terminating with StopIteration: can be a callable function terminating with StopIteration:
readline = open(myfile).next # Example of alternate readline readline = open(myfile).__next__ # Example of alternate readline
The generator produces 5-tuples with these members: the token type; the The generator produces 5-tuples with these members: the token type; the
token string; a 2-tuple (srow, scol) of ints specifying the row and token string; a 2-tuple (srow, scol) of ints specifying the row and

View file

@ -7,7 +7,7 @@ import sys
# Iterators in Python aren't a matter of type but of protocol. A large # Iterators in Python aren't a matter of type but of protocol. A large
# and changing number of builtin types implement *some* flavor of # and changing number of builtin types implement *some* flavor of
# iterator. Don't check the type! Use hasattr to check for both # iterator. Don't check the type! Use hasattr to check for both
# "__iter__" and "next" attributes instead. # "__iter__" and "__next__" attributes instead.
NoneType = type(None) NoneType = type(None)
TypeType = type TypeType = type

View file

@ -902,8 +902,8 @@ class addbase:
self.fileno = lambda: None self.fileno = lambda: None
if hasattr(self.fp, "__iter__"): if hasattr(self.fp, "__iter__"):
self.__iter__ = self.fp.__iter__ self.__iter__ = self.fp.__iter__
if hasattr(self.fp, "next"): if hasattr(self.fp, "__next__"):
self.next = self.fp.next self.__next__ = self.fp.__next__
def __repr__(self): def __repr__(self):
return '<%s at %r whose fp = %r>' % (self.__class__.__name__, return '<%s at %r whose fp = %r>' % (self.__class__.__name__,

View file

@ -26,7 +26,7 @@ class FileWrapper:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
data = self.filelike.read(self.blksize) data = self.filelike.read(self.blksize)
if data: if data:
return data return data

View file

@ -98,7 +98,7 @@ Some of the things this checks:
- That it is not a string (it should be a list of a single string; a - That it is not a string (it should be a list of a single string; a
string will work, but perform horribly). string will work, but perform horribly).
- That .next() returns a string - That .__next__() returns a string
- That the iterator is not iterated over until start_response has - That the iterator is not iterated over until start_response has
been called (that can signal either a server or application been called (that can signal either a server or application
@ -265,10 +265,10 @@ class IteratorWrapper:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
assert_(not self.closed, assert_(not self.closed,
"Iterator read after closed") "Iterator read after closed")
v = self.iterator.next() v = next(self.iterator)
if self.check_start_response is not None: if self.check_start_response is not None:
assert_(self.check_start_response, assert_(self.check_start_response,
"The application returns and we started iterating over its body, but start_response has not yet been called") "The application returns and we started iterating over its body, but start_response has not yet been called")

View file

@ -228,7 +228,7 @@ class DOMEventStream:
return rc return rc
raise IndexError raise IndexError
def next(self): def __next__(self):
rc = self.getEvent() rc = self.getEvent()
if rc: if rc:
return rc return rc

View file

@ -893,7 +893,7 @@ class iterparse:
append((event, None)) append((event, None))
parser.EndNamespaceDeclHandler = handler parser.EndNamespaceDeclHandler = handler
def next(self): def __next__(self):
while 1: while 1:
try: try:
item = self._events[self._index] item = self._events[self._index]
@ -923,7 +923,7 @@ class iterparse:
return self return self
except NameError: except NameError:
def __getitem__(self, index): def __getitem__(self, index):
return self.next() return self.__next__()
## ##
# Parses an XML document from a string constant. This function can # Parses an XML document from a string constant. This function can

View file

@ -139,7 +139,7 @@ def fill_stmt(iterable, fill_len):
overflow = None overflow = None
while total_len < fill_len: while total_len < fill_len:
try: try:
new_item = it.next() new_item = next(it)
buffer_.append(new_item) buffer_.append(new_item)
total_len += len(new_item) + 1 total_len += len(new_item) + 1
except StopIteration: except StopIteration:
@ -188,7 +188,7 @@ def main(file_path):
FILL - len(prefix) - len(indent)) FILL - len(prefix) - len(indent))
try: try:
while True: while True:
print>>FILE, indent + prefix + stmt_iter.next() print>>FILE, indent + prefix + next(stmt_iter)
except StopIteration: except StopIteration:
print>>FILE, '' print>>FILE, ''
else: else:

View file

@ -721,7 +721,7 @@ File Exceptions
return [result] -- Exits from function (or method) and returns result (use a tuple to return [result] -- Exits from function (or method) and returns result (use a tuple to
return more than one value). If no result given, then returns None. return more than one value). If no result given, then returns None.
yield result -- Freezes the execution frame of a generator and returns the result yield result -- Freezes the execution frame of a generator and returns the result
to the iterator's .next() method. Upon the next call to next(), to the iterator's .__next__() method. Upon the next call to __next__(),
resumes execution at the frozen point with all of the local variables resumes execution at the frozen point with all of the local variables
still intact. still intact.
@ -1058,7 +1058,7 @@ Exception>
SystemExit SystemExit
On 'sys.exit()' On 'sys.exit()'
StopIteration StopIteration
Signal the end from iterator.next() Signal the end from iterator.__next__()
StandardError StandardError
Base class for all built-in exceptions; derived from Exception Base class for all built-in exceptions; derived from Exception
root class. root class.

View file

@ -1701,7 +1701,7 @@ chain_next(chainobject *lz)
PyDoc_STRVAR(chain_doc, PyDoc_STRVAR(chain_doc,
"chain(*iterables) --> chain object\n\ "chain(*iterables) --> chain object\n\
\n\ \n\
Return a chain object whose .next() method returns elements from the\n\ Return a chain object whose .__next__() method returns elements from the\n\
first iterable until it is exhausted, then elements from the next\n\ first iterable until it is exhausted, then elements from the next\n\
iterable, until all of the iterables are exhausted."); iterable, until all of the iterables are exhausted.");
@ -2090,7 +2090,7 @@ count_repr(countobject *lz)
PyDoc_STRVAR(count_doc, PyDoc_STRVAR(count_doc,
"count([firstval]) --> count object\n\ "count([firstval]) --> count object\n\
\n\ \n\
Return a count object whose .next() method returns consecutive\n\ Return a count object whose .__next__() method returns consecutive\n\
integers starting from zero or, if specified, from firstval."); integers starting from zero or, if specified, from firstval.");
static PyTypeObject count_type = { static PyTypeObject count_type = {
@ -2272,8 +2272,8 @@ izip_next(izipobject *lz)
PyDoc_STRVAR(izip_doc, PyDoc_STRVAR(izip_doc,
"izip(iter1 [,iter2 [...]]) --> izip object\n\ "izip(iter1 [,iter2 [...]]) --> izip object\n\
\n\ \n\
Return a izip object whose .next() method returns a tuple where\n\ Return a izip object whose .__next__() method returns a tuple where\n\
the i-th element comes from the i-th iterable argument. The .next()\n\ the i-th element comes from the i-th iterable argument. The .__next__()\n\
method continues until the shortest iterable in the argument sequence\n\ method continues until the shortest iterable in the argument sequence\n\
is exhausted and then it raises StopIteration. Works like the zip()\n\ is exhausted and then it raises StopIteration. Works like the zip()\n\
function but consumes less memory by returning an iterator instead of\n\ function but consumes less memory by returning an iterator instead of\n\
@ -2648,8 +2648,8 @@ izip_longest_next(iziplongestobject *lz)
PyDoc_STRVAR(izip_longest_doc, PyDoc_STRVAR(izip_longest_doc,
"izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> izip_longest object\n\ "izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> izip_longest object\n\
\n\ \n\
Return an izip_longest object whose .next() method returns a tuple where\n\ Return an izip_longest object whose .__next__() method returns a tuple where\n\
the i-th element comes from the i-th iterable argument. The .next()\n\ the i-th element comes from the i-th iterable argument. The .__next__()\n\
method continues until the longest iterable in the argument sequence\n\ method continues until the longest iterable in the argument sequence\n\
is exhausted and then it raises StopIteration. When the shorter iterables\n\ is exhausted and then it raises StopIteration. When the shorter iterables\n\
are exhausted, the fillvalue is substituted in their place. The fillvalue\n\ are exhausted, the fillvalue is substituted in their place. The fillvalue\n\

View file

@ -369,7 +369,7 @@ SimpleExtendsException(PyExc_StandardError, TypeError,
* StopIteration extends Exception * StopIteration extends Exception
*/ */
SimpleExtendsException(PyExc_Exception, StopIteration, SimpleExtendsException(PyExc_Exception, StopIteration,
"Signal the end from iterator.next()."); "Signal the end from iterator.__next__().");
/* /*

View file

@ -4636,7 +4636,7 @@ static PyObject *
slot_tp_iternext(PyObject *self) slot_tp_iternext(PyObject *self)
{ {
static PyObject *next_str; static PyObject *next_str;
return call_method(self, "next", &next_str, "()"); return call_method(self, "__next__", &next_str, "()");
} }
static PyObject * static PyObject *
@ -5031,8 +5031,8 @@ static slotdef slotdefs[] = {
"x.__ge__(y) <==> x>=y"), "x.__ge__(y) <==> x>=y"),
TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
"x.__iter__() <==> iter(x)"), "x.__iter__() <==> iter(x)"),
TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next, TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next,
"x.next() -> the next value, or raise StopIteration"), "x.__next__() <==> next(x)"),
TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
"descr.__get__(obj[, type]) -> value"), "descr.__get__(obj[, type]) -> value"),
TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,

View file

@ -1136,6 +1136,46 @@ sequences have the same length. If the function is None, return a list of\n\
the items of the sequence (or a list of tuples if more than one sequence)."); the items of the sequence (or a list of tuples if more than one sequence).");
static PyObject *
builtin_next(PyObject *self, PyObject *args)
{
PyObject *it, *res;
PyObject *def = NULL;
if (!PyArg_UnpackTuple(args, "next", 1, 2, &it, &def))
return NULL;
if (!PyIter_Check(it)) {
PyErr_Format(PyExc_TypeError,
"%.200s object is not an iterator", it->ob_type->tp_name);
return NULL;
}
res = (*it->ob_type->tp_iternext)(it);
if (res == NULL) {
if (def) {
if (PyErr_Occurred() &&
!PyErr_ExceptionMatches(PyExc_StopIteration))
return NULL;
PyErr_Clear();
Py_INCREF(def);
return def;
} else if (PyErr_Occurred()) {
return NULL;
} else {
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
}
return res;
}
PyDoc_STRVAR(next_doc,
"next(iterator[, default])\n\
\n\
Return the next item from the iterator. If default is given and the iterator\n\
is exhausted, it is returned instead of raising StopIteration.");
static PyObject * static PyObject *
builtin_setattr(PyObject *self, PyObject *args) builtin_setattr(PyObject *self, PyObject *args)
{ {
@ -2252,6 +2292,7 @@ static PyMethodDef builtin_methods[] = {
{"map", builtin_map, METH_VARARGS, map_doc}, {"map", builtin_map, METH_VARARGS, map_doc},
{"max", (PyCFunction)builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, {"max", (PyCFunction)builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc},
{"min", (PyCFunction)builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, {"min", (PyCFunction)builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc},
{"next", (PyCFunction)builtin_next, METH_VARARGS, next_doc},
{"oct", builtin_oct, METH_O, oct_doc}, {"oct", builtin_oct, METH_O, oct_doc},
{"open", (PyCFunction)builtin_open, METH_VARARGS | METH_KEYWORDS, open_doc}, {"open", (PyCFunction)builtin_open, METH_VARARGS | METH_KEYWORDS, open_doc},
{"ord", builtin_ord, METH_O, ord_doc}, {"ord", builtin_ord, METH_O, ord_doc},

View file

@ -162,7 +162,7 @@ class FutureFinder:
OP = tokenize.OP OP = tokenize.OP
changed = self.changed changed = self.changed
get = tokenize.generate_tokens(self.getline).next get = tokenize.generate_tokens(self.getline).__next__
type, token, (srow, scol), (erow, ecol), line = get() type, token, (srow, scol), (erow, ecol), line = get()
# Chew up initial comments and blank lines (if any). # Chew up initial comments and blank lines (if any).