public Property getProperty() {
   final PyClass containingClass = getContainingClass();
   if (containingClass != null) {
     return containingClass.findPropertyByCallable(this);
   }
   return null;
 }
  /**
   * Looks for two standard decorators to a function, or a wrapping assignment that closely follows
   * it.
   *
   * @return a flag describing what was detected.
   */
  @Nullable
  public Modifier getModifier() {
    final String deconame = getClassOrStaticMethodDecorator();
    if (PyNames.CLASSMETHOD.equals(deconame)) {
      return CLASSMETHOD;
    } else if (PyNames.STATICMETHOD.equals(deconame)) {
      return STATICMETHOD;
    }
    // implicit staticmethod __new__
    final PyClass cls = getContainingClass();
    if (cls != null && PyNames.NEW.equals(getName()) && cls.isNewStyleClass(null)) {
      return STATICMETHOD;
    }
    //
    if (getStub() != null) {
      return getWrappersFromStub();
    }
    final String funcName = getName();
    if (funcName != null) {
      PyAssignmentStatement currentAssignment =
          PsiTreeUtil.getNextSiblingOfType(this, PyAssignmentStatement.class);
      while (currentAssignment != null) {
        final String modifier =
            currentAssignment
                .getTargetsToValuesMapping()
                .stream()
                .filter(
                    pair ->
                        pair.getFirst() instanceof PyTargetExpression
                            && funcName.equals(pair.getFirst().getName()))
                .filter(pair -> pair.getSecond() instanceof PyCallExpression)
                .map(
                    pair ->
                        interpretAsModifierWrappingCall((PyCallExpression) pair.getSecond(), this))
                .filter(interpreted -> interpreted != null && interpreted.getSecond() == this)
                .map(interpreted -> interpreted.getFirst())
                .filter(
                    wrapperName ->
                        PyNames.CLASSMETHOD.equals(wrapperName)
                            || PyNames.STATICMETHOD.equals(wrapperName))
                .findAny()
                .orElse(null);

        if (PyNames.CLASSMETHOD.equals(modifier)) {
          return CLASSMETHOD;
        } else if (PyNames.STATICMETHOD.equals(modifier)) {
          return STATICMETHOD;
        }

        currentAssignment =
            PsiTreeUtil.getNextSiblingOfType(currentAssignment, PyAssignmentStatement.class);
      }
    }
    return null;
  }
 protected String getElementLocation() {
   final PyClass containingClass = getContainingClass();
   if (containingClass != null) {
     return "("
         + containingClass.getName()
         + " in "
         + getPackageForFile(getContainingFile())
         + ")";
   }
   return super.getElementLocation();
 }
 private static boolean inConstructor(@NotNull PsiElement expression) {
   final PsiElement expr = expression instanceof PyClass ? expression : expression.getParent();
   PyClass clazz = PyUtil.getContainingClassOrSelf(expr);
   final ScopeOwner current = ScopeUtil.getScopeOwner(expression);
   if (clazz != null && current != null && current instanceof PyFunction) {
     PyFunction init = clazz.findMethodByName(PyNames.INIT, false, null);
     if (current == init) {
       return true;
     }
   }
   return false;
 }
 /**
  * Looks for two standard decorators to a function, or a wrapping assignment that closely follows
  * it.
  *
  * @return a flag describing what was detected.
  */
 @Nullable
 public Modifier getModifier() {
   String deconame = getClassOrStaticMethodDecorator();
   if (PyNames.CLASSMETHOD.equals(deconame)) {
     return CLASSMETHOD;
   } else if (PyNames.STATICMETHOD.equals(deconame)) {
     return STATICMETHOD;
   }
   // implicit staticmethod __new__
   PyClass cls = getContainingClass();
   if (cls != null && PyNames.NEW.equals(getName()) && cls.isNewStyleClass()) {
     return STATICMETHOD;
   }
   //
   if (getStub() != null) {
     return getWrappersFromStub();
   }
   String func_name = getName();
   if (func_name != null) {
     PyAssignmentStatement assignment =
         PsiTreeUtil.getNextSiblingOfType(this, PyAssignmentStatement.class);
     if (assignment != null) {
       for (Pair<PyExpression, PyExpression> pair : assignment.getTargetsToValuesMapping()) {
         PyExpression value = pair.getSecond();
         if (value instanceof PyCallExpression) {
           PyExpression target = pair.getFirst();
           if (target instanceof PyTargetExpression && func_name.equals(target.getName())) {
             Pair<String, PyFunction> interpreted =
                 interpretAsModifierWrappingCall((PyCallExpression) value, this);
             if (interpreted != null) {
               PyFunction original = interpreted.getSecond();
               if (original == this) {
                 String wrapper_name = interpreted.getFirst();
                 if (PyNames.CLASSMETHOD.equals(wrapper_name)) {
                   return CLASSMETHOD;
                 } else if (PyNames.STATICMETHOD.equals(wrapper_name)) {
                   return STATICMETHOD;
                 }
               }
             }
           }
         }
       }
     }
   }
   return null;
 }
 @Nullable
 private static PsiElement addFieldToSetUp(
     PyClass clazz, final Function<String, PyStatement> callback) {
   final PyFunction init =
       clazz.findMethodByName(PythonUnitTestUtil.TESTCASE_SETUP_NAME, false, null);
   if (init != null) {
     return AddFieldQuickFix.appendToMethod(init, callback);
   }
   final PyFunctionBuilder builder =
       new PyFunctionBuilder(PythonUnitTestUtil.TESTCASE_SETUP_NAME, clazz);
   builder.parameter(PyNames.CANONICAL_SELF);
   PyFunction setUp = builder.buildFunction(clazz.getProject(), LanguageLevel.getDefault());
   final PyStatementList statements = clazz.getStatementList();
   final PsiElement anchor = statements.getFirstChild();
   setUp = (PyFunction) statements.addBefore(setUp, anchor);
   return AddFieldQuickFix.appendToMethod(setUp, callback);
 }
 @Nullable
 @Override
 public String getQualifiedName() {
   String name = getName();
   if (name == null) {
     return null;
   }
   PyClass containingClass = getContainingClass();
   if (containingClass != null) {
     return containingClass.getQualifiedName() + "." + name;
   }
   if (PsiTreeUtil.getStubOrPsiParent(this) instanceof PyFile) {
     VirtualFile virtualFile = getContainingFile().getVirtualFile();
     if (virtualFile != null) {
       final String packageName =
           QualifiedNameFinder.findShortestImportableName(this, virtualFile);
       return packageName + "." + name;
     }
   }
   return null;
 }