Skip to content

Commit f3a5608

Browse files
Apply review suggestions - remove methodOfClass, fix qhelp typo; additionally add some more doc comments
1 parent c070d04 commit f3a5608

File tree

2 files changed

+7
-12
lines changed

2 files changed

+7
-12
lines changed

python/ql/src/Functions/IterReturnsNonSelf.qhelp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"qhelp.dtd">
44
<qhelp>
55
<overview>
6-
<p>Iterator classes (classes defining a <code>__next__</code> method) should have an <code>__iter__</code> that returns the iterator itself.
6+
<p>Iterator classes (classes defining a <code>__next__</code> method) should have an <code>__iter__</code> method that returns the iterator itself.
77
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.
88
</p>
99

python/ql/src/Functions/IterReturnsNonSelf.ql

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,11 @@
1414
import python
1515
import semmle.python.ApiGraphs
1616

17-
/** Holds if `f` is a method of the class `c`. */
18-
private predicate methodOfClass(Function f, Class c) {
19-
exists(FunctionDef d | d.getDefinedFunction() = f and d.getScope() = c)
20-
}
21-
2217
/** Gets the __iter__ method of `c`. */
23-
Function iterMethod(Class c) { methodOfClass(result, c) and result.getName() = "__iter__" }
18+
Function iterMethod(Class c) { result = c.getAMethod() and result.getName() = "__iter__" }
2419

2520
/** Gets the `__next__` method of `c`. */
26-
Function nextMethod(Class c) { methodOfClass(result, c) and result.getName() = "__next__" }
21+
Function nextMethod(Class c) { result = c.getAMethod() and result.getName() = "__next__" }
2722

2823
/** Holds if `var` is a variable referring to the `self` parameter of `f`. */
2924
predicate isSelfVar(Function f, Name var) { var.getVariable() = f.getArg(0).(Name).getVariable() }
@@ -48,8 +43,6 @@ predicate returnsNonSelf(Function f) {
4843
exists(f.getFallthroughNode())
4944
or
5045
exists(Return r | r.getScope() = f and not isGoodReturn(f, r.getValue()))
51-
or
52-
exists(Return r | r.getScope() = f and not exists(r.getValue()))
5346
}
5447

5548
/** Holds if `iter` and `next` methods are wrappers around some field. */
@@ -70,7 +63,8 @@ predicate iterWrapperMethods(Function iter, Function next) {
7063
)
7164
}
7265

73-
DataFlow::CallCfgNode iterCall(DataFlow::Node arg) {
66+
/** Gets a call to `iter(arg)`, `arg.__iter__()`, or `arg` itself (which we assume may already be an iterator). */
67+
private DataFlow::CallCfgNode iterCall(DataFlow::Node arg) {
7468
result.(DataFlow::MethodCallNode).calls(arg, "__iter__")
7569
or
7670
result = API::builtin("iter").getACall() and
@@ -80,7 +74,8 @@ DataFlow::CallCfgNode iterCall(DataFlow::Node arg) {
8074
result = arg // assume the wrapping field is already an iterator
8175
}
8276

83-
DataFlow::CallCfgNode nextCall(DataFlow::Node arg) {
77+
/** Gets a call to `next(arg)` or `arg.__next__()`. */
78+
private DataFlow::CallCfgNode nextCall(DataFlow::Node arg) {
8479
result.(DataFlow::MethodCallNode).calls(arg, "__next__")
8580
or
8681
result = API::builtin("next").getACall() and

0 commit comments

Comments
 (0)