mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
PY-27656 PY-27604 Exclude ancestors of metaclasses from class hierarchy
in case this relationship was created implicitly by inheriting an instance of metaclass. It also fixes warnings about the first parameter of SQLAlchemy model methods being named "self" instead of "cls" since we no longer consider these classes descendants of "type".
This commit is contained in:
@@ -427,7 +427,22 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
|
||||
final List<List<PyClassLikeType>> lines = new ArrayList<>();
|
||||
for (PyClassLikeType base : bases) {
|
||||
if (base != null) {
|
||||
final List<PyClassLikeType> baseClassMRO = mroLinearize(base, true, context, cache);
|
||||
// Don't include ancestors of a metaclass instance
|
||||
final List<PyClassLikeType> baseClassMRO;
|
||||
if (base.isDefinition()) {
|
||||
baseClassMRO = mroLinearize(base, true, context, cache);
|
||||
}
|
||||
else {
|
||||
List<PyClassLikeType> metaclassInstanceMro = new ArrayList<>();
|
||||
metaclassInstanceMro.add(base);
|
||||
if (base instanceof PyClassType) {
|
||||
final PyClassImpl pyClass = as(((PyClassType)base).getPyClass(), PyClassImpl.class);
|
||||
if (pyClass != null) {
|
||||
ContainerUtil.addIfNotNull(metaclassInstanceMro, pyClass.getImplicitSuper(context));
|
||||
}
|
||||
}
|
||||
baseClassMRO = metaclassInstanceMro;
|
||||
}
|
||||
if (!baseClassMRO.isEmpty()) {
|
||||
// mroMerge() updates passed MRO lists internally
|
||||
lines.add(new LinkedList<>(baseClassMRO));
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class MetaBase(type):
|
||||
pass
|
||||
|
||||
|
||||
class Meta(MetaBase):
|
||||
pass
|
||||
|
||||
|
||||
Base = Meta('Base', (), {})
|
||||
|
||||
|
||||
class MyClass(Base):
|
||||
pass
|
||||
@@ -125,6 +125,11 @@ public class PyClassMROTest extends PyTestCase {
|
||||
assertMRO(getClass("MyClass"), "Base", "object");
|
||||
}
|
||||
|
||||
// PY-27656
|
||||
public void testDirectlyInstantiatedMetaclassAncestor() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON30, () -> assertMRO(getClass("MyClass"), "Meta", "object"));
|
||||
}
|
||||
|
||||
// PY-20026
|
||||
public void testUnresolvedMetaClassAncestors() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON30, () -> assertMRO(getClass("CompositeFieldMeta"), "type", "object"));
|
||||
|
||||
Reference in New Issue
Block a user