Python: Add DuckTyping::isNewStyle

Approximates the behaviour of `Types::isNewStyle` but without depending
on points-to
This commit is contained in:
Taus
2026-02-20 15:19:18 +00:00
parent 33ed6034f6
commit cd92162920

View File

@@ -2068,4 +2068,30 @@ module DuckTyping {
hasMethod(cls, "__getitem__") and
(hasMethod(cls, "keys") or hasMethod(cls, "__iter__"))
}
/**
* Holds if `cls` is a new-style class. In Python 3, all classes are new-style.
* In Python 2, a class is new-style if it (transitively) inherits from `object`,
* or has a declared `__metaclass__`, or has an unresolved base class.
*/
predicate isNewStyle(Class cls) {
major_version() = 3
or
major_version() = 2 and
(
cls.getABase() = API::builtin("object").getAValueReachableFromSource().asExpr()
or
isNewStyle(getADirectSuperclass(cls))
or
hasUnresolvedBase(cls)
or
exists(cls.getMetaClass())
or
// Module-level __metaclass__ = type makes all classes in the module new-style
exists(Assign a |
a.getScope() = cls.getEnclosingModule() and
a.getATarget().(Name).getId() = "__metaclass__"
)
)
}
}