mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-22899 Fixed: type's __getattribute__ unresolved reference
PY-22937 Fixed: type's __setattr__ unresolved reference Add `object` as implicit super for all builtin classes except `staticmethod`, `classmethod` and `object`.
This commit is contained in:
@@ -1400,35 +1400,24 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
|
||||
if (PyNames.TYPES_INSTANCE_TYPE.equals(getQualifiedName())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final PyClassStub stub = getStub();
|
||||
final List<PyClassLikeType> result = new ArrayList<>();
|
||||
|
||||
// In some cases stub may not provide all information, so we use stubs only if AST access id disabled
|
||||
if (!context.maySwitchToAST(this)) {
|
||||
fillSuperClassesNoSwitchToAst(context, stub, result);
|
||||
fillSuperClassesNoSwitchToAst(context, getStub(), result);
|
||||
}
|
||||
else {
|
||||
fillSuperClassesSwitchingToAst(context, result);
|
||||
}
|
||||
|
||||
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(this);
|
||||
PyPsiUtils.assertValid(this);
|
||||
if (result.isEmpty() && isValid() && !builtinCache.isBuiltin(this)) {
|
||||
final PyClass implicitSuper;
|
||||
if (LanguageLevel.forElement(this).isOlderThan(LanguageLevel.PYTHON30) && getMetaClassQName() == null) {
|
||||
implicitSuper = as(resolveTopLevelMember(QualifiedName.fromDottedString(PyNames.TYPES_INSTANCE_TYPE),
|
||||
fromFoothold(this)), PyClass.class);
|
||||
}
|
||||
else {
|
||||
implicitSuper = builtinCache.getClass(PyNames.OBJECT);
|
||||
}
|
||||
if (implicitSuper != null) {
|
||||
final PyType type = context.getType(implicitSuper);
|
||||
if (type instanceof PyClassLikeType) {
|
||||
result.add((PyClassLikeType)type);
|
||||
}
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
return Optional
|
||||
.ofNullable(getImplicitSuper(context))
|
||||
.map(Collections::singletonList)
|
||||
.orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1475,6 +1464,29 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PyClassLikeType getImplicitSuper(@NotNull TypeEvalContext context) {
|
||||
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(this);
|
||||
final PyClassType objectType = builtinCache.getObjectType();
|
||||
|
||||
if (objectType != null && this == objectType.getPyClass()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (LanguageLevel.forElement(this).isOlderThan(LanguageLevel.PYTHON30) && getMetaClassQName() == null) {
|
||||
final QualifiedName typesInstanceTypeQName = QualifiedName.fromDottedString(PyNames.TYPES_INSTANCE_TYPE);
|
||||
final PsiElement typesInstanceType = resolveTopLevelMember(typesInstanceTypeQName, fromFoothold(this));
|
||||
|
||||
return Optional
|
||||
.ofNullable(as(typesInstanceType, PyClass.class))
|
||||
.map(context::getType)
|
||||
.map(type -> as(type, PyClassLikeType.class))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
return objectType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PyClassLikeType> getAncestorTypes(@NotNull TypeEvalContext context) {
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class ConfigMeta(type):
|
||||
def __getattribute__(self, item):
|
||||
return super().__getattribute__(item)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
super().__setattr__(key, value)
|
||||
+5
@@ -205,4 +205,9 @@ public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
|
||||
public void testTypingGenericDunderGetItem() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-22899, PY-22937
|
||||
public void testCallTypeGetAttributeAndSetAttrInInheritor() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user