@Override
  public boolean processClassObjectAttributes(@NotNull PsiScopeProcessor processor, @Nullable PsiElement location) {
    if (!processClassLevelDeclarations(processor)) return false;
    PyFunction containingMethod = PsiTreeUtil.getStubOrPsiParentOfType(location, PyFunction.class);
    PyClass containingClass = containingMethod != null ? containingMethod.getContainingClass() : null;
    boolean isClassMethod = containingMethod != null && containingMethod.getModifier() == Modifier.CLASSMETHOD;
    List<PyTargetExpression> allClassAttributes = getClassAttributesDefinedInClassMethods();
    List<PyTargetExpression> prioritizedClassAttrs;
    if (isClassMethod && containingClass != null && CompletionUtilCoreImpl.getOriginalElement(containingClass) == this) {
      List<PyTargetExpression> sameMethodClassAttrs = ContainerUtil.filter(allClassAttributes,
                                                                           attr -> ScopeUtil.getScopeOwner(attr) == containingMethod);
      List<PyTargetExpression> otherMethodClassAttrs = ContainerUtil.filter(allClassAttributes,
                                                                            attr -> ScopeUtil.getScopeOwner(attr) != containingMethod);
      prioritizedClassAttrs = ContainerUtil.concat(sameMethodClassAttrs, otherMethodClassAttrs);
    }
    else {
      prioritizedClassAttrs = allClassAttributes;
    }
    for (PyTargetExpression target : prioritizedClassAttrs) {
      if (!processor.execute(target, ResolveState.initial())) {
        return false;
      }
    }
    return true;
  }
@Override
  public boolean processClassObjectAttributes(@NotNull PsiScopeProcessor processor, @Nullable PsiElement location)