Skip to content

Commit 47a292b

Browse files
authored
Merge pull request #2264 from tausbn/python-fix-unused-import-join-order
Python: Fix bad join order in `py/unused-import`
2 parents 8ffd7c1 + b6f16de commit 47a292b

File tree

1 file changed

+38
-21
lines changed

1 file changed

+38
-21
lines changed

python/ql/src/Imports/UnusedImport.ql

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,41 +41,58 @@ predicate all_not_understood(Module m) {
4141
}
4242

4343
predicate imported_module_used_in_doctest(Import imp) {
44-
exists(string modname |
44+
exists(string modname, string docstring |
4545
imp.getAName().getAsname().(Name).getId() = modname and
4646
// Look for doctests containing the patterns:
4747
// >>> …name…
4848
// ... …name…
49-
exists(StrConst doc |
50-
doc.getEnclosingModule() = imp.getScope() and
51-
doc.isDocString() and
52-
doc.getText().regexpMatch("[\\s\\S]*(>>>|\\.\\.\\.).*" + modname + "[\\s\\S]*")
53-
)
49+
docstring = doctest_in_scope(imp.getScope()) and
50+
docstring.regexpMatch("[\\s\\S]*(>>>|\\.\\.\\.).*" + modname + "[\\s\\S]*")
51+
)
52+
}
53+
54+
pragma[noinline]
55+
private string doctest_in_scope(Scope scope) {
56+
exists(StrConst doc |
57+
doc.getEnclosingModule() = scope and
58+
doc.isDocString() and
59+
result = doc.getText() and
60+
result.regexpMatch("[\\s\\S]*(>>>|\\.\\.\\.)[\\s\\S]*")
61+
)
62+
}
63+
64+
pragma[noinline]
65+
private string typehint_annotation_in_file(File file) {
66+
exists(StrConst annotation |
67+
annotation = any(Arguments a).getAnAnnotation()
68+
or
69+
annotation = any(AnnAssign a).getAnnotation()
70+
|
71+
annotation.pointsTo(Value::forString(result)) and
72+
file = annotation.getLocation().getFile()
73+
)
74+
}
75+
76+
pragma[noinline]
77+
private string typehint_comment_in_file(File file) {
78+
exists(Comment typehint |
79+
file = typehint.getLocation().getFile() and
80+
result = typehint.getText() and
81+
result.matches("# type:%")
5482
)
5583
}
5684

5785
predicate imported_module_used_in_typehint(Import imp) {
58-
exists(string modname, Location loc |
86+
exists(string modname, File file |
5987
imp.getAName().getAsname().(Name).getId() = modname and
60-
loc.getFile() = imp.getScope().(Module).getFile()
88+
file = imp.getScope().(Module).getFile()
6189
|
6290
// Look for type hints containing the patterns:
6391
// # type: …name…
64-
exists(Comment typehint |
65-
loc = typehint.getLocation() and
66-
typehint.getText().regexpMatch("# type:.*" + modname + ".*")
67-
)
92+
typehint_comment_in_file(file).regexpMatch("# type:.*" + modname + ".*")
6893
or
6994
// Type hint is inside a string annotation, as needed for forward references
70-
exists(string typehint, Expr annotation |
71-
annotation = any(Arguments a).getAnAnnotation()
72-
or
73-
annotation = any(AnnAssign a).getAnnotation()
74-
|
75-
annotation.pointsTo(Value::forString(typehint)) and
76-
loc = annotation.getLocation() and
77-
typehint.regexpMatch(".*\\b" + modname + "\\b.*")
78-
)
95+
typehint_annotation_in_file(file).regexpMatch(".*\\b" + modname + "\\b.*")
7996
)
8097
}
8198

0 commit comments

Comments
 (0)