mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Python: Adds preliminary modernization
This commit is contained in:
@@ -12,8 +12,8 @@
|
||||
|
||||
import python
|
||||
|
||||
Function iter_method(ClassObject t) {
|
||||
result = ((FunctionObject)t.lookupAttribute("__iter__")).getFunction()
|
||||
Function iter_method(ClassValue t) {
|
||||
result = ((FunctionValue)t.lookup("__iter__")).getScope()
|
||||
}
|
||||
|
||||
predicate is_self(Name value, Function f) {
|
||||
@@ -28,6 +28,6 @@ predicate returns_non_self(Function f) {
|
||||
exists(Return r | r.getScope() = f and not exists(r.getValue()))
|
||||
}
|
||||
|
||||
from ClassObject t, Function iter
|
||||
from ClassValue t, Function iter
|
||||
where t.isIterator() and iter = iter_method(t) and returns_non_self(iter)
|
||||
select t, "Class " + t.getName() + " is an iterator but its $@ method does not return 'self'.", iter, iter.getName()
|
||||
@@ -374,7 +374,7 @@ class CallableValue extends Value {
|
||||
|
||||
/** Class representing classes in the Python program, both Python and built-in.
|
||||
*/
|
||||
class ClassValue extends Value {
|
||||
class ClassValue extends Value {
|
||||
|
||||
ClassValue() {
|
||||
this.(ObjectInternal).isClass() = true
|
||||
@@ -413,6 +413,26 @@ class ClassValue extends Value {
|
||||
this.hasAttribute("__getitem__")
|
||||
}
|
||||
|
||||
/** Holds if this class is an iterator. */
|
||||
predicate isIterator() {
|
||||
this.hasAttribute("__iter__") and
|
||||
(major_version() = 3 and this.hasAttribute("__next__")
|
||||
or
|
||||
/* Because 'next' is a common method name we need to check that an __iter__
|
||||
* method actually returns this class. This is not needed for Py3 as the
|
||||
* '__next__' method exists to define a class as an iterator.
|
||||
*/
|
||||
major_version() = 2 and this.hasAttribute("next") and
|
||||
exists(ClassObject other, FunctionObject iter |
|
||||
other.declaredAttribute("__iter__") = iter |
|
||||
iter.getAnInferredReturnType() = this
|
||||
)
|
||||
)
|
||||
or
|
||||
/* This will be redundant when we have C class information */
|
||||
this = ClassValue::generator()
|
||||
}
|
||||
|
||||
/** Holds if this class is a descriptor. */
|
||||
predicate isDescriptorType() {
|
||||
this.hasAttribute("__get__")
|
||||
|
||||
Reference in New Issue
Block a user