Python points-to: Fix up metaclass determination for Python 2.

This commit is contained in:
Mark Shannon
2019-05-13 14:20:43 +01:00
parent 26044f20c7
commit 1f00c3b248
4 changed files with 21 additions and 14 deletions

View File

@@ -426,6 +426,11 @@ module ObjectInternal {
result = TBuiltinClassObject(Builtin::special("super"))
}
/** The old-style class type (Python 2 only) */
ObjectInternal classType() {
result = TBuiltinClassObject(Builtin::special("ClassType"))
}
}
/** Helper for boolean predicates returning both `true` and `false` */

View File

@@ -1692,9 +1692,9 @@ cached module Types {
}
cached ClassObjectInternal getMetaClass(PythonClassObjectInternal cls) {
result = declaredMetaClass(cls)
or
hasDeclaredMetaclass(cls) = false and result = getInheritedMetaclass(cls)
result = declaredMetaClass(cls)
or
hasDeclaredMetaclass(cls) = false and result = getInheritedMetaclass(cls)
}
private ClassObjectInternal declaredMetaClass(PythonClassObjectInternal cls) {
@@ -1799,7 +1799,9 @@ cached module Types {
c = cls.(PythonClassObjectInternal).getScope() and
n = count(c.getABase())
|
result = ObjectInternal::builtin("type")
result = ObjectInternal::type() and major_version() = 3
or
result = ObjectInternal::classType() and major_version() = 2
)
or
exists(ClassObjectInternal meta1, ClassObjectInternal meta2 |
@@ -1811,6 +1813,8 @@ cached module Types {
or
improperSuperType(meta2) = meta1 and result = meta2
or
meta2 = ObjectInternal::classType() and result = meta1
or
/* Make sure we have a metaclass, even if base is unknown */
meta1 = ObjectInternal::unknownClass() and result = ObjectInternal::builtin("type")
or

View File

@@ -1,15 +1,17 @@
import python
import semmle.python.pointsto.MRO
import semmle.python.pointsto.PointsTo
import semmle.python.objects.ObjectInternal
ClassList mro(ClassObject cls) {
if cls.isNewStyle() then
result = new_style_mro(cls)
ClassList mro(ClassObjectInternal cls) {
if Types::isNewStyle(cls) then
result = Mro::newStyleMro(cls)
else
result = old_style_mro(cls)
result = Mro::oldStyleMro(cls)
}
from ClassObject cls
from ClassObjectInternal cls
where not cls.isBuiltin()
select cls.toString(), mro(cls)

View File

@@ -1,8 +1,4 @@
/**
* @name class_attr
* @kind test
* @problem.severity warning
*/
import python