Skip to content

Commit f27057a

Browse files
Update qhelp
1 parent 7b452a1 commit f27057a

File tree

2 files changed

+13
-20
lines changed

2 files changed

+13
-20
lines changed

python/ql/src/Functions/IterReturnsNonSelf.qhelp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,27 @@
33
"qhelp.dtd">
44
<qhelp>
55
<overview>
6-
<p>The <code>__iter__</code> method of an iterator should return self.
7-
This is important so that iterators can be used as sequences in any context
8-
that expect a sequence. To do so requires that <code>__iter__</code> is
9-
idempotent on iterators.</p>
10-
11-
<p>
12-
Note that sequences and mapping should return a new iterator, it is just the returned
13-
iterator that must obey this constraint.
6+
<p>Iterator classes (classes defining a <code>__next__</code> method) should have an <code>__iter__</code> that returns the iterator itself.
7+
This ensures that the object is also an iterable; and behaves as expected when used anywhere an iterator or iterable is expected, such as in <code>for</code> loops.
148
</p>
159

10+
11+
1612
</overview>
1713
<recommendation>
18-
<p>Make the <code>__iter__</code> return self unless the class should not be an iterator,
19-
in which case rename the <code>next</code> (Python 2) or <code>__next__</code> (Python 3)
20-
to something else.</p>
14+
<p>Ensure that the <code>__iter__</code> method returns <code>self</code>, or is otherwise equivalent as an iterator to <code>self<code>.</p>
2115

2216
</recommendation>
2317
<example>
24-
<p>In this example the <code>Counter</code> class's <code>__iter__</code> method does not
25-
return self (or even an iterator). This will cause the program to fail when anyone attempts
26-
to use the iterator in a <code>for</code> loop or <code>in</code> statement.</p>
27-
<sample src="IterReturnsNonSelf.py" />
18+
<p>In the following example, the <code>MyRange</code> class's <code>__iter__</code> method does not return <code>self</code>.
19+
This would lead to unexpected results when used with a <code>for</code> loop or <code>in</code> statement.
20+
<sample src="examples/IterReturnsNonSelf.py" />
2821

2922
</example>
3023
<references>
3124

32-
<li>Python Language Reference: <a href="http://docs.python.org/2.7/reference/datamodel.html#object.__iter__">object.__iter__</a>.</li>
33-
<li>Python Standard Library: <a href="http://docs.python.org/2/library/stdtypes.html#typeiter">Iterators</a>.</li>
25+
<li>Python Language Reference: <a href="http://docs.python.org/3/reference/datamodel.html#object.__iter__">object.__iter__</a>.</li>
26+
<li>Python Standard Library: <a href="http://docs.python.org/3/library/stdtypes.html#typeiter">Iterators</a>.</li>
3427

3528

3629
</references>

python/ql/src/Functions/IterReturnsNonSelf.py renamed to python/ql/src/Functions/examples/IterReturnsNonSelf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ def __init__(self, low, high):
44
self.high = high
55

66
def __iter__(self):
7-
return self.current
7+
return (self.current, self.high) # BAD: does not return `self`.
88

9-
def next(self):
9+
def __next__(self):
1010
if self.current > self.high:
11-
raise StopIteration
11+
return None
1212
self.current += 1
1313
return self.current - 1

0 commit comments

Comments
 (0)