Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5d5060b
Python: Use API graphs instead of points-to for simple built-ins
tausbn Feb 18, 2026
452e189
Python: Port `py/print-during-import`
tausbn Feb 19, 2026
62d5cac
Python: Introduce `DuckTyping` module
tausbn Feb 20, 2026
1159d20
Python: Port ContainsNonContainer.ql
tausbn Feb 20, 2026
485e949
Python: Port NonIteratorInForLoop.ql
tausbn Feb 20, 2026
918e5e2
Python: Port ShouldUseWithStatement.ql
tausbn Feb 20, 2026
8ffcdfe
Python: Port UnusedExceptionObject.ql
tausbn Feb 20, 2026
793ecb6
Python: Add `DuckTyping::isNewStyle`
tausbn Feb 20, 2026
c1beca8
Python: Add declares/getAttribute API
tausbn Feb 20, 2026
f4f217c
Python: Port SlotsInOldStyleClass.ql
tausbn Feb 20, 2026
8f154f6
Python: Port SuperInOldStyleClass.ql
tausbn Feb 20, 2026
8fe680c
Python: Port PropertyInOldStyleClass.ql
tausbn Feb 20, 2026
e2dcfae
Python: Port InconsistentMRO.ql
tausbn Feb 20, 2026
c4a4e20
Python: Port HashedButNoHash.ql
tausbn Feb 20, 2026
7ceb6a5
Python: Port UselessClass.ql
tausbn Feb 20, 2026
6c56882
Python: Port ShouldBeContextManager.ql
tausbn Feb 20, 2026
0094271
Python: Port WrongNameForArgumentInClassInstantiation.ql
tausbn Feb 23, 2026
0509ec6
Python: Port WrongNumberArgumentsInClassInstantiation.ql
tausbn Feb 23, 2026
d9693e7
Python: Remove missing results
tausbn Feb 23, 2026
c837e14
Python: Extend DuckTyping module
tausbn Feb 23, 2026
5954287
Python: Port DeprecatedSliceMethod.ql
tausbn Feb 23, 2026
f6cd63f
Python: Port DocStrings.ql
tausbn Feb 23, 2026
f5361f4
Python: Move exception modelling to DataFlowDispatch.qll
tausbn Feb 24, 2026
7d8b4ac
Python: Add Reachability module
tausbn Feb 24, 2026
156d2c0
Python: Port getCyclomaticComplexity function
tausbn Feb 24, 2026
853df14
Python: Port OverlyComplexDelMethod.ql
tausbn Feb 24, 2026
54af9dd
Python: Port ConsistentReturns.ql
tausbn Feb 24, 2026
4606d90
Python: Extend ExceptionTypes API
tausbn Feb 24, 2026
c4ec331
Python: Port IllegalRaise.ql
tausbn Feb 24, 2026
e2eb69c
Python: Port IllegalExceptionHandlerType.ql
tausbn Feb 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions python/ql/lib/LegacyPointsTo.qll
Original file line number Diff line number Diff line change
Expand Up @@ -433,38 +433,6 @@ private predicate exits_early(BasicBlock b) {

/** The metrics for a function that require points-to analysis */
class FunctionMetricsWithPointsTo extends FunctionMetrics {
/**
* Gets the cyclomatic complexity of the function:
* The number of linearly independent paths through the source code.
* Computed as E - N + 2P,
* where
* E = the number of edges of the graph.
* N = the number of nodes of the graph.
* P = the number of connected components, which for a single function is 1.
*/
int getCyclomaticComplexity() {
exists(int e, int n |
n = count(BasicBlockWithPointsTo b | b = this.getABasicBlock() and b.likelyReachable()) and
e =
count(BasicBlockWithPointsTo b1, BasicBlockWithPointsTo b2 |
b1 = this.getABasicBlock() and
b1.likelyReachable() and
b2 = this.getABasicBlock() and
b2.likelyReachable() and
b2 = b1.getASuccessor() and
not b1.unlikelySuccessor(b2)
)
|
result = e - n + 2
)
}

private BasicBlock getABasicBlock() {
result = this.getEntryNode().getBasicBlock()
or
exists(BasicBlock mid | mid = this.getABasicBlock() and result = mid.getASuccessor())
}

/**
* Dependency of Callables
* One callable "this" depends on another callable "result"
Expand Down
27 changes: 27 additions & 0 deletions python/ql/lib/semmle/python/Metrics.qll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import python
private import semmle.python.SelfAttribute
private import semmle.python.dataflow.new.internal.DataFlowDispatch

/** The metrics for a function */
class FunctionMetrics extends Function {
Expand Down Expand Up @@ -27,6 +28,32 @@ class FunctionMetrics extends Function {
int getStatementNestingDepth() { result = max(Stmt s | s.getScope() = this | getNestingDepth(s)) }

int getNumberOfCalls() { result = count(Call c | c.getScope() = this) }

/**
* Gets the cyclomatic complexity of the function:
* The number of linearly independent paths through the source code.
* Computed as E - N + 2P,
* where
* E = the number of edges of the graph.
* N = the number of nodes of the graph.
* P = the number of connected components, which for a single function is 1.
*/
int getCyclomaticComplexity() {
exists(int n, int e |
n = count(BasicBlock b | b.getScope() = this and Reachability::likelyReachable(b)) and
e =
count(BasicBlock b1, BasicBlock b2 |
b1.getScope() = this and
Reachability::likelyReachable(b1) and
b2.getScope() = this and
Reachability::likelyReachable(b2) and
b2 = b1.getASuccessor() and
not Reachability::unlikelySuccessor(b1.getLastNode(), b2.firstNode())
)
|
result = e - n + 2
)
}
}

/** The metrics for a class */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ module Builtins {
"UnicodeDecodeError", "UnicodeEncodeError", "UnicodeError", "UnicodeTranslateError",
"UnicodeWarning", "UserWarning", "ValueError", "Warning", "ZeroDivisionError",
// Added for compatibility
"exec"
"exec",
// Added by the `site` module (available by default unless `-S` is used)
"copyright", "credits", "exit", "quit"
]
or
// Built-in constants shared between Python 2 and 3
Expand All @@ -51,8 +53,8 @@ module Builtins {
or
// Python 2 only
result in [
"basestring", "cmp", "execfile", "file", "long", "raw_input", "reduce", "reload", "unichr",
"unicode", "xrange"
"apply", "basestring", "cmp", "execfile", "file", "long", "raw_input", "reduce", "reload",
"unichr", "unicode", "xrange"
]
}

Expand Down
Loading