Skip to content

Commit 6826c4e

Browse files
committed
Python: Port InconsistentMRO.ql
For this one we actually lose a test result. However, this is kind of to be expected since we no longer have the "precise" MRO that the points-to analysis computes. Honestly, I'm on the fence about even keeping this query at all. It seems like it might be superfluous in a world with good Python type checking.
1 parent e09a4ba commit 6826c4e

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

python/ql/src/Classes/InconsistentMRO.ql

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,24 @@
1212
*/
1313

1414
import python
15-
private import LegacyPointsTo
15+
private import semmle.python.dataflow.new.internal.DataFlowDispatch
1616

17-
ClassObject left_base(ClassObject type, ClassObject base) {
18-
exists(int i | i > 0 and type.getBaseType(i) = base and result = type.getBaseType(i - 1))
17+
/**
18+
* Gets the `i`th base class of `cls`, if it can be resolved to a user-defined class.
19+
*/
20+
Class getBaseType(Class cls, int i) { cls.getBase(i) = classTracker(result).asExpr() }
21+
22+
Class left_base(Class type, Class base) {
23+
exists(int i | i > 0 and getBaseType(type, i) = base and result = getBaseType(type, i - 1))
1924
}
2025

21-
predicate invalid_mro(ClassObject t, ClassObject left, ClassObject right) {
22-
t.isNewStyle() and
26+
predicate invalid_mro(Class t, Class left, Class right) {
27+
DuckTyping::isNewStyle(t) and
2328
left = left_base(t, right) and
24-
left = right.getAnImproperSuperType()
29+
left = getADirectSuperclass*(right)
2530
}
2631

27-
from ClassObject t, ClassObject left, ClassObject right
32+
from Class t, Class left, Class right
2833
where invalid_mro(t, left, right)
2934
select t,
3035
"Construction of class " + t.getName() +
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| inconsistent_mro.py:9:1:9:14 | class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | class X | X | inconsistent_mro.py:6:1:6:11 | class Y | Y |
1+
| inconsistent_mro.py:9:1:9:14 | Class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | Class X | X | inconsistent_mro.py:6:1:6:11 | Class Y | Y |
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
| inconsistent_mro.py:9:1:9:14 | class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | class X | X | inconsistent_mro.py:6:1:6:11 | class Y | Y |
2-
| inconsistent_mro.py:16:1:16:19 | class N | Construction of class N can fail due to invalid method resolution order(MRO) for bases $@ and $@. | file://:Compiled Code:0:0:0:0 | builtin-class object | object | inconsistent_mro.py:12:1:12:8 | class O | O |
1+
| inconsistent_mro.py:9:1:9:14 | Class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | Class X | X | inconsistent_mro.py:6:1:6:11 | Class Y | Y |

0 commit comments

Comments
 (0)