Files
codeql/python/ql/src/Functions/NonCls.ql
Taus Brock-Nannestad f07a7bf8cf Python: Autoformat everything using qlformat.
Will need subsequent PRs fixing up test failures (due to deprecated
methods moving around), but other than that everything should be
straight-forward.
2020-07-07 15:43:52 +02:00

51 lines
1.5 KiB
Plaintext

/**
* @name First parameter of a class method is not named 'cls'
* @description Using an alternative name for the first parameter of a class method makes code more
* difficult to read; PEP8 states that the first parameter to class methods should be 'cls'.
* @kind problem
* @tags maintainability
* readability
* convention
* @problem.severity recommendation
* @sub-severity high
* @precision high
* @id py/not-named-cls
*/
import python
predicate first_arg_cls(Function f) {
exists(string argname | argname = f.getArgName(0) |
argname = "cls"
or
/* Not PEP8, but relatively common */
argname = "mcls"
)
}
predicate is_type_method(Function f) {
exists(ClassValue c | c.getScope() = f.getScope() and c.getASuperType() = ClassValue::type())
}
predicate classmethod_decorators_only(Function f) {
forall(Expr decorator | decorator = f.getADecorator() | decorator.(Name).getId() = "classmethod")
}
from Function f, string message
where
(f.getADecorator().(Name).getId() = "classmethod" or is_type_method(f)) and
not first_arg_cls(f) and
classmethod_decorators_only(f) and
not f.getName() = "__new__" and
(
if exists(f.getArgName(0))
then
message =
"Class methods or methods of a type deriving from type should have 'cls', rather than '" +
f.getArgName(0) + "', as their first parameter."
else
message =
"Class methods or methods of a type deriving from type should have 'cls' as their first parameter."
)
select f, message