Skip to content

Commit c508e89

Browse files
committed
Python: Handle keyword-only arguments properly
1 parent 4185edc commit c508e89

File tree

5 files changed

+27
-3
lines changed

5 files changed

+27
-3
lines changed

python/ql/src/semmle/python/Function.qll

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ class Function extends Function_, Scope, AstNode {
4949
string getArgName(int index) { result = this.getArg(index).(Name).getId() }
5050

5151
Parameter getArgByName(string name) {
52-
result = this.getAnArg() and
52+
(
53+
result = this.getAnArg()
54+
or
55+
result = this.getAKeywordOnlyArg()
56+
) and
5357
result.(Name).getId() = name
5458
}
5559

@@ -102,6 +106,7 @@ class Function extends Function_, Scope, AstNode {
102106
result = this.getAStmt() or
103107
result = this.getAnArg() or
104108
result = this.getVararg() or
109+
result = this.getAKeywordOnlyArg() or
105110
result = this.getKwarg()
106111
}
107112

@@ -185,6 +190,8 @@ class Parameter extends Parameter_ {
185190
f.getVararg() = this
186191
or
187192
f.getKwarg() = this
193+
or
194+
f.getAKeywordOnlyArg() = this
188195
)
189196
}
190197

@@ -322,11 +329,14 @@ class Lambda extends Lambda_, CallableExpr {
322329
* that is generally only used for type hints today (PEP 484).
323330
*/
324331
class Arguments extends Arguments_ {
332+
325333
Expr getASubExpression() {
334+
result = this.getADefault() or
326335
result = this.getAKwDefault() or
336+
//
327337
result = this.getAnAnnotation() or
328-
result = this.getKwargannotation() or
329338
result = this.getVarargannotation() or
330-
result = this.getADefault()
339+
result = this.getAKwAnnotation() or
340+
result = this.getKwargannotation()
331341
}
332342
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
| test.py:4:1:11:2 | Function func | test.py:5:5:5:12 | pos_only |
22
| test.py:4:1:11:2 | Function func | test.py:7:5:7:10 | normal |
33
| test.py:4:1:11:2 | Function func | test.py:8:6:8:9 | args |
4+
| test.py:4:1:11:2 | Function func | test.py:9:5:9:16 | keyword_only |
45
| test.py:4:1:11:2 | Function func | test.py:10:7:10:12 | kwargs |
56
| test.py:4:1:11:2 | Function func | test.py:12:5:12:41 | ExprStmt |
67
| test.py:4:1:11:2 | Function func | test.py:13:5:13:15 | ExprStmt |
78
| test.py:4:1:11:2 | Function func | test.py:14:5:14:17 | ExprStmt |
89
| test.py:23:1:31:2 | Function func2 | test.py:24:5:24:11 | pos_req |
910
| test.py:23:1:31:2 | Function func2 | test.py:25:5:25:17 | pos_w_default |
1011
| test.py:23:1:31:2 | Function func2 | test.py:26:5:26:18 | pos_w_default2 |
12+
| test.py:23:1:31:2 | Function func2 | test.py:28:5:28:15 | keyword_req |
13+
| test.py:23:1:31:2 | Function func2 | test.py:29:5:29:21 | keyword_w_default |
14+
| test.py:23:1:31:2 | Function func2 | test.py:30:5:30:20 | keyword_also_req |
1115
| test.py:23:1:31:2 | Function func2 | test.py:32:5:32:18 | ExprStmt |
1216
| test.py:23:1:31:2 | Function func2 | test.py:33:5:40:5 | ExprStmt |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
| test.py:4:1:11:2 | Function func | keyword_only | test.py:9:5:9:16 | Parameter |
12
| test.py:4:1:11:2 | Function func | normal | test.py:7:5:7:10 | Parameter |
23
| test.py:4:1:11:2 | Function func | pos_only | test.py:5:5:5:12 | Parameter |
4+
| test.py:23:1:31:2 | Function func2 | keyword_also_req | test.py:30:5:30:20 | Parameter |
5+
| test.py:23:1:31:2 | Function func2 | keyword_req | test.py:28:5:28:15 | Parameter |
6+
| test.py:23:1:31:2 | Function func2 | keyword_w_default | test.py:29:5:29:21 | Parameter |
37
| test.py:23:1:31:2 | Function func2 | pos_req | test.py:24:5:24:11 | Parameter |
48
| test.py:23:1:31:2 | Function func2 | pos_w_default | test.py:25:5:25:17 | Parameter |
59
| test.py:23:1:31:2 | Function func2 | pos_w_default2 | test.py:26:5:26:18 | Parameter |

python/ql/test/3/library-tests/functions/FunctionExpr.getASubExpression.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
| test.py:4:1:11:2 | FunctionExpr | test.py:7:13:7:15 | int |
44
| test.py:4:1:11:2 | FunctionExpr | test.py:7:19:7:20 | UnaryExpr |
55
| test.py:4:1:11:2 | FunctionExpr | test.py:8:12:8:23 | Str |
6+
| test.py:4:1:11:2 | FunctionExpr | test.py:9:19:9:21 | int |
67
| test.py:4:1:11:2 | FunctionExpr | test.py:9:25:9:26 | UnaryExpr |
78
| test.py:4:1:11:2 | FunctionExpr | test.py:10:15:10:30 | Str |
89
| test.py:23:1:31:2 | FunctionExpr | test.py:25:20:25:24 | Str |
910
| test.py:23:1:31:2 | FunctionExpr | test.py:25:28:25:31 | None |
1011
| test.py:23:1:31:2 | FunctionExpr | test.py:26:20:26:23 | None |
12+
| test.py:23:1:31:2 | FunctionExpr | test.py:29:24:29:28 | Str |
1113
| test.py:23:1:31:2 | FunctionExpr | test.py:29:32:29:35 | None |

python/ql/test/3/library-tests/parameters/Special.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
| args | varargs |
2+
| keyword_also_req | normal |
3+
| keyword_only | normal |
4+
| keyword_req | normal |
5+
| keyword_w_default | normal |
26
| kwargs | kwargs |
37
| normal | normal |
48
| pos_only | normal |

0 commit comments

Comments
 (0)