Consider class foo(six.with_metaclass(bar)) as new-style class (PY-22806)

Even if there are no new-style parents, the fact of having a metaclass
defined in a class is sufficient to treat it as a new-style class.
This commit is contained in:
Andrey Vlasovskikh
2017-03-10 21:07:09 +03:00
parent 6caae6ff5e
commit 8373787e76
3 changed files with 18 additions and 3 deletions

View File

@@ -1386,7 +1386,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
PyPsiUtils.assertValid(this);
if (result.isEmpty() && isValid() && !builtinCache.isBuiltin(this)) {
final PyClass implicitSuper;
if (LanguageLevel.forElement(this).isOlderThan(LanguageLevel.PYTHON30)) {
if (LanguageLevel.forElement(this).isOlderThan(LanguageLevel.PYTHON30) && getMetaClassQName() == null) {
implicitSuper = as(resolveTopLevelMember(QualifiedName.fromDottedString(PyNames.TYPES_INSTANCE_TYPE),
fromFoothold(this)), PyClass.class);
}
@@ -1461,8 +1461,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
}
}
else {
final PyClassStub stub = getStub();
final QualifiedName name = stub != null ? stub.getMetaClass() : PyPsiUtils.asQualifiedName(getMetaClassExpression());
final QualifiedName name = getMetaClassQName();
final PsiFile file = getContainingFile();
if (file instanceof PyFile) {
final PyFile pyFile = (PyFile)file;
@@ -1485,6 +1484,12 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
return null;
}
@Nullable
private QualifiedName getMetaClassQName() {
final PyClassStub stub = getStub();
return stub != null ? stub.getMetaClass() : PyPsiUtils.asQualifiedName(getMetaClassExpression());
}
@Nullable
@Override
public PyExpression getMetaClassExpression() {

View File

@@ -0,0 +1,5 @@
import six
class C(six.with_metaclass(type)):
pass

View File

@@ -72,6 +72,11 @@ public class PyClassMROTest extends PyTestCase {
assertMRO(getClass("C"), "B", "D", "object");
}
// PY-22806
public void testSixWithMetaclassOnly() {
assertMRO(getClass("C"), "object");
}
// PY-4183
public void testComplicatedDiamond() {
assertMRO(getClass("H"), "E", "F", "B", "G", "C", "D", "A", "object");