Skip to content

Commit cca1593

Browse files
authored
Merge pull request #1598 from markshannon/python-better-parameter-api
Python: Better API for parameters.
2 parents a42d9b1 + 3035178 commit cca1593

File tree

11 files changed

+81
-13
lines changed

11 files changed

+81
-13
lines changed

python/ql/src/semmle/python/AstExtended.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Comprehension extends Comprehension_, AstNode {
8181

8282
}
8383

84-
class BytesOrStr extends BytesOrStr_ {
84+
class BytesOrStr extends BytesOrStr_ {
8585

8686
}
8787

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,12 @@ class Parameter extends Parameter_ {
224224
Parameter() {
225225
/* Parameter_ is just defined as a Name or Tuple, narrow to actual parameters */
226226
exists(ParameterList pl | py_exprs(this, _, pl, _))
227+
or
228+
exists(Function f |
229+
f.getVararg() = this
230+
or
231+
f.getKwarg() = this
232+
)
227233
}
228234

229235
Location getLocation() {
@@ -242,6 +248,7 @@ class Parameter extends Parameter_ {
242248
result = this
243249
}
244250

251+
/** Gets the expression for the default value of this parameter */
245252
Expr getDefault() {
246253
exists(Function f, int n, int c, int d, Arguments args |
247254
args = f.getDefinition().getArgs() |
@@ -252,6 +259,24 @@ class Parameter extends Parameter_ {
252259
)
253260
}
254261

262+
/** Gets the annotation expression of this parameter */
263+
Expr getAnnotation() {
264+
exists(Function f, int n, Arguments args |
265+
args = f.getDefinition().getArgs() |
266+
f.getArg(n) = this and
267+
result = args.getAnnotation(n)
268+
)
269+
or
270+
exists(Function f, Arguments args |
271+
args = f.getDefinition().getArgs() |
272+
f.getKwarg() = this and
273+
result = args.getKwargannotation()
274+
or
275+
f.getVararg() = this and
276+
result = args.getVarargannotation()
277+
)
278+
}
279+
255280
Variable getVariable() {
256281
result.getAnAccess() = this.asName()
257282
}

python/ql/src/semmle/python/pointsto/Base.qll

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,19 @@ class ParameterDefinition extends PyNodeDefinition {
275275
this.getDefiningNode().getNode().(Parameter).isSelf()
276276
}
277277

278+
/** Gets the control flow node for the default value of this parameter */
278279
ControlFlowNode getDefault() {
279-
exists(Function f, int n, int c, int d, Arguments args |
280-
args = f.getDefinition().getArgs() |
281-
f.getArg(n) = this.getDefiningNode().getNode() and
282-
c = count(f.getAnArg()) and
283-
d = count(args.getADefault()) and
284-
result.getNode() = args.getDefault(d-c+n)
285-
)
280+
result.getNode() = this.getParameter().getDefault()
281+
}
282+
283+
/** Gets the annotation control flow node of this parameter */
284+
ControlFlowNode getAnnotation() {
285+
result.getNode() = this.getParameter().getAnnotation()
286+
}
287+
288+
/** Gets the name of this parameter definition */
289+
string getName() {
290+
result = this.getParameter().asName().getId()
286291
}
287292

288293
predicate isVarargs() {

python/ql/test/library-tests/PointsTo/new/SourceNodeDefinitions.expected

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
| a_simple.py:11 | Global Variable C | ControlFlowNode for C | definition |
1919
| a_simple.py:14 | Global Variable vararg_kwarg | ControlFlowNode for vararg_kwarg | definition |
2020
| a_simple.py:14 | Local Variable d | ControlFlowNode for d | definition |
21-
| a_simple.py:14 | Local Variable d | Entry node for Function vararg_kwarg | definition |
2221
| a_simple.py:14 | Local Variable t | ControlFlowNode for t | definition |
23-
| a_simple.py:14 | Local Variable t | Entry node for Function vararg_kwarg | definition |
2422
| a_simple.py:18 | Global Variable multi_loop | ControlFlowNode for multi_loop | definition |
2523
| a_simple.py:18 | Local Variable seq | ControlFlowNode for seq | definition |
2624
| a_simple.py:18 | Local Variable x | Entry node for Function multi_loop | definition |
@@ -40,9 +38,7 @@
4038
| a_simple.py:29 | Local Variable q | ControlFlowNode for q | definition |
4139
| a_simple.py:34 | Global Variable f | ControlFlowNode for f | definition |
4240
| a_simple.py:34 | Local Variable args | ControlFlowNode for args | definition |
43-
| a_simple.py:34 | Local Variable args | Entry node for Function f | definition |
4441
| a_simple.py:34 | Local Variable kwargs | ControlFlowNode for kwargs | definition |
45-
| a_simple.py:34 | Local Variable kwargs | Entry node for Function f | definition |
4642
| a_simple.py:38 | Global Variable multi_assign_and_packing | ControlFlowNode for multi_assign_and_packing | definition |
4743
| a_simple.py:38 | Local Variable a | ControlFlowNode for a | definition |
4844
| a_simple.py:38 | Local Variable b | ControlFlowNode for b | definition |
@@ -142,7 +138,6 @@
142138
| b_condition.py:99 | Local Variable x | ControlFlowNode for use() | refinement |
143139
| b_condition.py:101 | Global Variable not_or_not | ControlFlowNode for not_or_not | definition |
144140
| b_condition.py:101 | Local Variable a | ControlFlowNode for a | definition |
145-
| b_condition.py:101 | Local Variable a | Entry node for Function not_or_not | definition |
146141
| b_condition.py:109 | Global Variable method_check | ControlFlowNode for method_check | definition |
147142
| b_condition.py:109 | Local Variable x | ControlFlowNode for x | definition |
148143
| b_condition.py:111 | Local Variable x | ControlFlowNode for use() | refinement |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| args | test.py:5:13:5:22 | Subscript |
2+
| b | test.py:2:12:2:14 | str |
3+
| d | test.py:2:27:2:29 | int |
4+
| kwargs | test.py:5:34:5:47 | Subscript |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
import python
3+
4+
5+
from Parameter p
6+
select p.getName(), p.getAnnotation()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| c | test.py:2:19:2:22 | None |
2+
| d | test.py:2:31:2:34 | True |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
import python
3+
4+
5+
from Parameter p
6+
select p.getName(), p.getDefault()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| a | normal |
2+
| args | varargs |
3+
| b | normal |
4+
| c | normal |
5+
| d | normal |
6+
| kwargs | kwargs |
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
3+
import python
4+
5+
from Parameter p, string type
6+
where
7+
p.isKwargs() and type = "kwargs"
8+
or
9+
p.isVarargs() and type = "varargs"
10+
or
11+
not p.isKwargs() and not p.isVarargs() and type = "normal"
12+
13+
select p.getName(), type

0 commit comments

Comments
 (0)