private static boolean isAbstract(@NotNull PyClass pyClass) { final PyType metaClass = pyClass.getMetaClassType( TypeEvalContext.userInitiated(pyClass.getProject(), pyClass.getContainingFile())); if (metaClass instanceof PyClassLikeType && PyNames.ABC_META_CLASS.equals(metaClass.getName())) { return true; } if (metaClass == null) { final PyExpression metaClassExpr = as(pyClass.getMetaClassExpression(), PyReferenceExpression.class); if (metaClassExpr != null && PyNames.ABC_META_CLASS.equals(metaClassExpr.getName())) { return true; } } for (PyFunction method : pyClass.getMethods(false)) { if (PyUtil.isDecoratedAsAbstract(method)) { return true; } } return false; }
// TODO: Copy/Paste with PyClass.getMeta.. private static boolean addMetaAbcIfNeeded(@NotNull final PyClass aClass) { final PsiFile file = aClass.getContainingFile(); final PyType type = aClass.getMetaClassType(TypeEvalContext.userInitiated(file)); if (type != null) { return false; // User already has metaclass. He probably knows about metaclasses, so we should // not add ABCMeta } final LanguageLevel languageLevel = LanguageLevel.forElement(aClass); if (languageLevel .isPy3K()) { // TODO: Copy/paste, use strategy because we already has the same check in // #couldBeAbstract // Add (metaclass= for Py3K PyClassRefactoringUtil.addSuperClassExpressions( aClass.getProject(), aClass, null, Collections.singletonList(Pair.create(PyNames.METACLASS, ABC_META_CLASS))); } else { // Add __metaclass__ for Py2 PyClassRefactoringUtil.addClassAttributeIfNotExist( aClass, PyNames.DUNDER_METACLASS, ABC_META_CLASS); } return true; }