mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Exclude 'methods' used in initialisation, and allow self for metaclass methods
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import python
|
||||
import semmle.python.ApiGraphs
|
||||
import DataFlow
|
||||
|
||||
/** Holds if `f` is a method of the class `c`. */
|
||||
private predicate methodOfClass(Function f, Class c) { f.getScope() = c }
|
||||
@@ -34,13 +35,29 @@ private predicate isZopeInterface(Class c) {
|
||||
.asExpr()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `f` is used in the initialisation of `c`.
|
||||
* This means `f` isn't being used as a normal method.
|
||||
* Ideally it should be a `@staticmethod`; however this wasn't possible prior to Python 3.10.
|
||||
* We exclude this case from the `not-named-self` query.
|
||||
* However there is potential for a new query that specifically covers and alerts for this case.
|
||||
*/
|
||||
private predicate usedInInit(Function f, Class c) {
|
||||
methodOfClass(f, c) and
|
||||
exists(Call call |
|
||||
call.getScope() = c and
|
||||
DataFlow::localFlow(DataFlow::exprNode(f.getDefinition()), DataFlow::exprNode(call.getFunc()))
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the first parameter of `f` should be named `self`. */
|
||||
predicate shouldBeSelf(Function f, Class c) {
|
||||
methodOfClass(f, c) and
|
||||
not isStaticMethod(f) and
|
||||
not isClassMethod(f) and
|
||||
not isMetaclass(c) and
|
||||
not isZopeInterface(c)
|
||||
not isZopeInterface(c) and
|
||||
not usedInInit(f, c)
|
||||
}
|
||||
|
||||
/** Holds if the first parameter of `f` should be named `cls`. */
|
||||
@@ -73,8 +90,17 @@ predicate firstArgShouldBeNamedSelfAndIsnt(Function f) {
|
||||
not firstArgNamedSelf(f)
|
||||
}
|
||||
|
||||
/** Holds if `f` is a regular method of a metaclass, and its first argument is named `self`. */
|
||||
private predicate metaclassNamedSelf(Function f, Class c) {
|
||||
methodOfClass(f, c) and
|
||||
firstArgNamedSelf(f) and
|
||||
isMetaclass(c) and
|
||||
not isClassMethod(f)
|
||||
}
|
||||
|
||||
/** Holds if the first parameter of `f` should be named `cls`, but isn't. */
|
||||
predicate firstArgShouldBeNamedClsAndIsnt(Function f) {
|
||||
shouldBeCls(f, _) and
|
||||
not firstArgNamedCls(f)
|
||||
not firstArgNamedCls(f) and
|
||||
not metaclassNamedSelf(f, _)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user