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
57d662d
Python: Use API graphs instead of points-to for simple built-ins
tausbn Feb 18, 2026
61b4980
Python: Port `py/print-during-import`
tausbn Feb 19, 2026
ed6a6bc
Python: Introduce `DuckTyping` module
tausbn Feb 20, 2026
be61d3d
Python: Port ContainsNonContainer.ql
tausbn Feb 20, 2026
0acad03
Python: Port NonIteratorInForLoop.ql
tausbn Feb 20, 2026
da16454
Python: Port ShouldUseWithStatement.ql
tausbn Feb 20, 2026
4928947
Python: Port UnusedExceptionObject.ql
tausbn Feb 20, 2026
70a67aa
Python: Add `DuckTyping::isNewStyle`
tausbn Feb 20, 2026
815a7ad
Python: Add declares/getAttribute API
tausbn Feb 20, 2026
2af8b29
Python: Port SlotsInOldStyleClass.ql
tausbn Feb 20, 2026
671571d
Python: Port SuperInOldStyleClass.ql
tausbn Feb 20, 2026
ecd8fe6
Python: Port PropertyInOldStyleClass.ql
tausbn Feb 20, 2026
c30a25f
Python: Port InconsistentMRO.ql
tausbn Feb 20, 2026
933af14
Python: Port HashedButNoHash.ql
tausbn Feb 20, 2026
3834763
Python: Port UselessClass.ql
tausbn Feb 20, 2026
096bcd5
Python: Port ShouldBeContextManager.ql
tausbn Feb 20, 2026
849da28
Python: Port WrongNameForArgumentInClassInstantiation.ql
tausbn Feb 23, 2026
52d45a1
Python: Port WrongNumberArgumentsInClassInstantiation.ql
tausbn Feb 23, 2026
9c54c41
Python: Remove missing results
tausbn Feb 23, 2026
6d339b5
Python: Extend DuckTyping module
tausbn Feb 23, 2026
1112a18
Python: Port DeprecatedSliceMethod.ql
tausbn Feb 23, 2026
5bd96a5
Python: Port DocStrings.ql
tausbn Feb 23, 2026
c1e2d9f
Python: Move exception modelling to DataFlowDispatch.qll
tausbn Feb 24, 2026
f6962a2
Python: Add Reachability module
tausbn Feb 24, 2026
109edad
Python: Port getCyclomaticComplexity function
tausbn Feb 24, 2026
c4c797b
Python: Port OverlyComplexDelMethod.ql
tausbn Feb 24, 2026
c5f29c6
Python: Port ConsistentReturns.ql
tausbn Feb 24, 2026
1593cbf
Python: Extend ExceptionTypes API
tausbn Feb 24, 2026
bca03d1
Python: Port IllegalRaise.ql
tausbn Feb 24, 2026
679f920
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