Skip to content

Commit 03aa2e2

Browse files
committed
Python: Explain the funky logic in Find.ql
1 parent 1f8f6dd commit 03aa2e2

File tree

3 files changed

+17
-0
lines changed

3 files changed

+17
-0
lines changed

python/ql/src/meta/ClassHierarchy/Find.ql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,19 @@ predicate fullyQualifiedToYamlFormat(string fullyQualified, string type2, string
478478
from FindSubclassesSpec spec, string newModelFullyQualified, string type2, string path, Module mod
479479
where
480480
newModel(spec, newModelFullyQualified, _, mod, _) and
481+
// Since a class C which is a subclass for flask.MethodView is always a subclass of
482+
// flask.View, and we chose to care about this distinction, in a naive approach we
483+
// would always record rows for _both_ specs... that's just wasteful, so instead we
484+
// only record the row for the more specific spec -- this is captured by the
485+
// .getSuperClass() method on a spec, which can links specs together in this way.
486+
// However, if the definition actually depends on some logic, like below, we should
487+
// still record both rows
488+
// ```
489+
// if <cond>:
490+
// class C(flask.View): ...
491+
// else:
492+
// class C(flask.MethodView): ...
493+
// ```
481494
not exists(FindSubclassesSpec subclass | subclass.getSuperClass() = spec |
482495
newModel(subclass, newModelFullyQualified, _, mod, _)
483496
) and

python/ql/test/experimental/library-tests/FindSubclass/Find.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
| flask.MethodView~Subclass | find_subclass_test | Member[C] |
12
| flask.MethodView~Subclass | find_subclass_test | Member[MethodView] |
23
| flask.MethodView~Subclass | find_subclass_test | Member[clash] |
34
| flask.View~Subclass | find_subclass_test | Member[A] |

python/ql/test/experimental/library-tests/FindSubclass/find_subclass_test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
from flask.views import View
2+
import flask.views
23

34
class A(View):
45
pass
56

67
class B(A):
78
pass
89

10+
class C(flask.views.MethodView):
11+
pass
912

1013
ViewAlias = View
1114

0 commit comments

Comments
 (0)