Skip to content

Commit 87d7738

Browse files
committed
Python: Expand QLDoc for get[Named]ArgumentForCall
1 parent 061bbb8 commit 87d7738

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

python/ql/src/semmle/python/objects/ObjectAPI.qll

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,29 @@ class CallableValue extends Value {
352352
result = this.(CallableObjectInternal).getParameterByName(name)
353353
}
354354

355-
/** Gets the argument corresponding to the `n'th parameter node of this callable. */
355+
/**
356+
* Gets the argument in `call` corresponding to the `n`'th positional parameter of this callable.
357+
*
358+
* Use this method instead of `call.getArg(n)` to handle the fact that this function might be used as
359+
* a bound-method, such that argument `n` of the call corresponds to the `n+1` parameter of the callable.
360+
*
361+
* This method also gives results when the argument is passed as a keyword argument in `call`, as long
362+
* as `this` is not a builtin function or a builtin method.
363+
*
364+
* Examples:
365+
*
366+
* - if `this` represents the `PythonFunctionValue` for `def func(a, b):`, and `call` represents
367+
* `func(10, 20)`, then `getArgumentForCall(call, 0)` will give the `ControlFlowNode` for `10`.
368+
*
369+
* - with `call` representing `func(b=20, a=10)`, `getArgumentForCall(call, 0)` will give
370+
* the `ControlFlowNode` for `10`.
371+
*
372+
* - if `this` represents the `PythonFunctionValue` for `def func(self, a, b):`, and `call`
373+
* represents `foo.func(10, 20)`, then `getArgumentForCall(call, 1)` will give the
374+
* `ControlFlowNode` for `10`.
375+
* Note: There will also exist a `BoundMethodValue bm` where `bm.getArgumentForCall(call, 0)`
376+
* will give the `ControlFlowNode` for `10` (notice the shift in index used).
377+
*/
356378
cached
357379
ControlFlowNode getArgumentForCall(CallNode call, int n) {
358380
exists(ObjectInternal called, int offset |
@@ -373,7 +395,25 @@ class CallableValue extends Value {
373395
)
374396
}
375397

376-
/** Gets the argument corresponding to the `name`d parameter node of this callable. */
398+
/**
399+
* Gets the argument in `call` corresponding to the `name`d keyword parameter of this callable.
400+
* ONLY WORKS FOR NON-BUILTINS.
401+
*
402+
* This method also gives results when the argument is passed as a positional argument in `call`, as long
403+
* as `this` is not a builtin function or a builtin method.
404+
*
405+
* Examples:
406+
*
407+
* - if `this` represents the `PythonFunctionValue` for `def func(a, b):`, and `call` represents
408+
* `func(10, 20)`, then `getNamedArgumentForCall(call, "a")` will give the `ControlFlowNode` for `10`.
409+
*
410+
* - with `call` representing `func(b=20, a=10)`, `getNamedArgumentForCall(call, "a")` will give
411+
* the `ControlFlowNode` for `10`.
412+
*
413+
* - if `this` represents the `PythonFunctionValue` for `def func(self, a, b):`, and `call`
414+
* represents `foo.func(10, 20)`, then `getNamedArgumentForCall(call, "a")` will give the
415+
* `ControlFlowNode` for `10`.
416+
*/
377417
cached
378418
ControlFlowNode getNamedArgumentForCall(CallNode call, string name) {
379419
exists(CallableObjectInternal called, int offset |

0 commit comments

Comments
 (0)