mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Merge pull request #1877 from taus-semmle/python-modernise-non-iterator-query
Python: Modernise the `py/non-iterable-in-for-loop` query.
This commit is contained in:
@@ -13,11 +13,11 @@
|
||||
|
||||
import python
|
||||
|
||||
from For loop, ControlFlowNode iter, ClassObject t, ControlFlowNode origin
|
||||
from For loop, ControlFlowNode iter, Value v, ClassValue t, ControlFlowNode origin
|
||||
where loop.getIter().getAFlowNode() = iter and
|
||||
iter.refersTo(_, t, origin) and
|
||||
not t.isIterable() and not t.failedInference() and
|
||||
not t = theNoneType() and
|
||||
iter.pointsTo(_, v, origin) and v.getClass() = t and
|
||||
not t.isIterable() and not t.failedInference(_) and
|
||||
not v = Value::named("None") and
|
||||
not t.isDescriptorType()
|
||||
|
||||
select loop, "$@ of class '$@' may be used in for-loop.", origin, "Non-iterator", t, t.getName()
|
||||
|
||||
@@ -346,6 +346,18 @@ class ClassValue extends Value {
|
||||
this.(ClassObjectInternal).lookup("__call__", _, _)
|
||||
}
|
||||
|
||||
/** Holds if this class is an iterable. */
|
||||
predicate isIterable() {
|
||||
this.hasAttribute("__iter__")
|
||||
or
|
||||
this.hasAttribute("__getitem__")
|
||||
}
|
||||
|
||||
/** Holds if this class is a descriptor. */
|
||||
predicate isDescriptorType() {
|
||||
this.hasAttribute("__get__")
|
||||
}
|
||||
|
||||
/** Gets the qualified name for this class.
|
||||
* Should return the same name as the `__qualname__` attribute on classes in Python 3.
|
||||
*/
|
||||
|
||||
2
python/ql/test/3/query-tests/Statements/iter/NonIteratorInForLoop.expected
Executable file → Normal file
2
python/ql/test/3/query-tests/Statements/iter/NonIteratorInForLoop.expected
Executable file → Normal file
@@ -1 +1 @@
|
||||
| statements_test.py:34:5:34:19 | For | $@ of class '$@' may be used in for-loop. | statements_test.py:34:18:34:18 | ControlFlowNode for IntegerLiteral | Non-iterator | file://:Compiled Code:0:0:0:0 | builtin-class int | int |
|
||||
| statements_test.py:34:5:34:19 | For | $@ of class '$@' may be used in for-loop. | statements_test.py:34:18:34:18 | ControlFlowNode for IntegerLiteral | Non-iterator | file://:0:0:0:0 | builtin-class int | int |
|
||||
|
||||
1
python/ql/test/query-tests/Statements/general/NonIteratorInForLoop.expected
Executable file → Normal file
1
python/ql/test/query-tests/Statements/general/NonIteratorInForLoop.expected
Executable file → Normal file
@@ -1 +1,2 @@
|
||||
| test.py:50:1:50:23 | For | $@ of class '$@' may be used in for-loop. | test.py:50:10:50:22 | ControlFlowNode for NonIterator() | Non-iterator | test.py:45:1:45:26 | class NonIterator | NonIterator |
|
||||
| test.py:170:10:170:22 | For | $@ of class '$@' may be used in for-loop. | test.py:170:10:170:22 | ControlFlowNode for .0 | Non-iterator | test.py:169:1:169:21 | class false_positive | false_positive |
|
||||
|
||||
@@ -165,4 +165,7 @@ def no_with():
|
||||
def assert_ok(seq):
|
||||
assert all(isinstance(element, (str, unicode)) for element in seq)
|
||||
|
||||
# False positive. ODASA-8042
|
||||
class false_positive:
|
||||
e = (x for x in [])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user