Python: getStarArg gives first *args argument

I couldn't see any reason that we should give up altogether if there are
multiple `*args` arguments. Including the first one looks like a win to
me!
This commit is contained in:
Rasmus Wriedt Larsen
2022-09-12 17:02:31 +02:00
parent 3384521fb6
commit 41ce1c2016
3 changed files with 10 additions and 4 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* `getStarArg` member-predicate on `Call` and `CallNode` has been changed for calls that have multiple `*args` arguments (for example `func(42, *my_args, *other_args)`): Instead of producing no results, it will always have a result for the _first_ such `*args` argument.

View File

@@ -245,10 +245,12 @@ class Call extends Call_ {
result = count(Expr arg | arg = this.getAPositionalArg() and not arg instanceof Starred)
}
/** Gets the tuple (*) argument of this call, provided there is exactly one. */
/** Gets the first tuple (*) argument of this call, if any. */
Expr getStarArg() {
count(this.getStarargs()) < 2 and
result = this.getStarargs()
exists(int firstStarArgIndex |
firstStarArgIndex = min(int i | this.getPositionalArg(i) instanceof Starred | i) and
result = this.getPositionalArg(firstStarArgIndex).(Starred).getValue()
)
}
}

View File

@@ -406,7 +406,7 @@ class CallNode extends ControlFlowNode {
exists(FunctionExpr func | this.getNode() = func.getADecoratorCall())
}
/** Gets the tuple (*) argument of this call, provided there is exactly one. */
/** Gets the first tuple (*) argument of this call, if any. */
ControlFlowNode getStarArg() {
result.getNode() = this.getNode().getStarArg() and
result.getBasicBlock().dominates(this.getBasicBlock())