@Override
    public void visitPyFunction(@NotNull PyFunction node) {
      final PyClass containingClass = node.getContainingClass();
      if (containingClass == null) return;
      final String name = node.getName();
      if (name != null && name.startsWith("_")) return;
      if (!isApplicable(containingClass, myTypeEvalContext)) {
        return;
      }
      if (node.getModifier() != null) {
        return;
      }

      final Map<String, Property> localProperties = containingClass.getProperties();
      final Map<String, PyTargetExpression> declaredAttributes = new HashMap<>();
      final Set<String> inheritedProperties = new HashSet<>();

      StreamEx.of(containingClass.getClassAttributes())
              .filter(attribute -> !localProperties.containsKey(attribute.getName()))
              .forEach(attribute -> declaredAttributes.put(attribute.getName(), attribute));

      final PyFunction initMethod = containingClass.findMethodByName(PyNames.INIT, false, myTypeEvalContext);
      if (initMethod != null) {
        PyClassImpl.collectInstanceAttributes(initMethod, declaredAttributes);
      }
      for (PyClass superClass : containingClass.getAncestorClasses(myTypeEvalContext)) {
        final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, false, myTypeEvalContext);
        if (superInit != null) {
          PyClassImpl.collectInstanceAttributes(superInit, declaredAttributes);
        }

        for (PyTargetExpression classAttr : superClass.getClassAttributes()) {
          declaredAttributes.put(classAttr.getName(), classAttr);
        }

        inheritedProperties.addAll(superClass.getProperties().keySet());
      }

      final Map<String, PyTargetExpression> attributes = new HashMap<>();
      PyClassImpl.collectInstanceAttributes(node, attributes);

      for (PyTargetExpression attribute : attributes.values()) {
        final String attributeName = attribute.getName();
        if (attributeName == null) continue;
        if (!declaredAttributes.containsKey(attributeName) &&
            !inheritedProperties.contains(attributeName) &&
            !localProperties.containsKey(attributeName) &&
            !isDefinedByProperty(attribute, localProperties.values(), declaredAttributes)) {
          final PyExpression assignedValue = attribute.findAssignedValue();
          if (assignedValue == null) continue;

          if (expressionReferencesLocalName(assignedValue, node)) {
            registerProblem(attribute, PyPsiBundle.message("INSP.attribute.outside.init", attributeName),
                            new AddFieldQuickFix(attributeName, "None", containingClass.getName(), false));
          }
          else {
            registerProblem(attribute, PyPsiBundle.message("INSP.attribute.outside.init", attributeName),
                            new PyMoveAttributeToInitQuickFix(),
                            new AddFieldQuickFix(attributeName, "None", containingClass.getName(), false));
          }
        }
      }
    }
@Override
    public void visitPyFunction(@NotNull PyFunction node)