void () { final List<PyInspectionExtension> filters = PyInspectionExtension.EP_NAME.getExtensionList(); // Register problems final Set<PyFunction> functionsWithInheritors = new HashSet<>(); final Map<PyFunction, Boolean> emptyFunctions = new HashMap<>(); for (PsiElement element : myUnusedElements) { boolean ignoreUnused = false; for (PyInspectionExtension filter : filters) { if (filter.ignoreUnused(element, myTypeEvalContext)) { ignoreUnused = true; } } if (ignoreUnused) continue; if (element instanceof PyFunction) { // Local function final PsiElement nameIdentifier = ((PyFunction)element).getNameIdentifier(); registerWarning(nameIdentifier == null ? element : nameIdentifier, PyPsiBundle.message("INSP.unused.locals.local.function.isnot.used", ((PyFunction)element).getName()), new PyRemoveStatementQuickFix()); } else if (element instanceof PyClass cls) { // Local class final PsiElement name = cls.getNameIdentifier(); registerWarning(name != null ? name : element, PyPsiBundle.message("INSP.unused.locals.local.class.isnot.used", cls.getName()), new PyRemoveStatementQuickFix()); } else { // Local variable or parameter String name = element.getText(); if (element instanceof PyNamedParameter || element.getParent() instanceof PyNamedParameter) { PyNamedParameter namedParameter = element instanceof PyNamedParameter ? (PyNamedParameter) element : (PyNamedParameter) element.getParent(); name = namedParameter.getName(); // When function is inside a class, first parameter may be either self or cls which is always 'used'. if (namedParameter.isSelf()) { continue; } if (myIgnoreLambdaParameters && PsiTreeUtil.getParentOfType(element, PyCallable.class) instanceof PyLambdaExpression) { continue; } boolean mayBeField = false; PyClass containingClass = null; PyParameterList paramList = PsiTreeUtil.getParentOfType(element, PyParameterList.class); if (paramList != null && paramList.getParent() instanceof PyFunction func) { containingClass = func.getContainingClass(); if (containingClass != null && PyUtil.isInitMethod(func) && !namedParameter.isKeywordContainer() && !namedParameter.isPositionalContainer()) { mayBeField = true; } else if (ignoreUnusedParameters(func, functionsWithInheritors)) { continue; } if (func.asMethod() != null) { Boolean isEmpty = emptyFunctions.get(func); if (isEmpty == null) { isEmpty = PyUtil.isEmptyFunction(func); emptyFunctions.put(func, isEmpty); } if (isEmpty && !mayBeField) { continue; } } } boolean canRemove = !(PsiTreeUtil.getPrevSiblingOfType(element, PyParameter.class) instanceof PySingleStarParameter) || PsiTreeUtil.getNextSiblingOfType(element, PyParameter.class) != null; final List<LocalQuickFix> fixes = new ArrayList<>(); if (mayBeField) { fixes.add(new AddFieldQuickFix(name, name, containingClass.getName(), false)); } if (canRemove) { fixes.add(new PyRemoveParameterQuickFix()); } registerWarning(element, PyPsiBundle.message("INSP.unused.locals.parameter.isnot.used", name), fixes.toArray(LocalQuickFix.EMPTY_ARRAY)); } else { if (myIgnoreVariablesStartingWithUnderscore && element.getText().startsWith(PyNames.UNDERSCORE)) continue; if (myIgnoreTupleUnpacking && isTupleUnpacking(element)) continue; final String warningMsg = PyPsiBundle.message("INSP.unused.locals.local.variable.isnot.used", name); final PyForStatement forStatement = PyForStatementNavigator.getPyForStatementByIterable(element); if (forStatement != null) { if (!myIgnoreRangeIterationVariables || !isRangeIteration(forStatement)) { registerWarning(element, warningMsg, new ReplaceWithWildCard()); } continue; } if (isComprehensionTarget(element)) { registerWarning(element, warningMsg, new ReplaceWithWildCard()); continue; } final PyExceptPart exceptPart = PyExceptPartNavigator.getPyExceptPartByTarget(element); if (exceptPart != null) { registerWarning(element, warningMsg, new PyRemoveExceptionTargetQuickFix()); continue; } final PyWithItem withItem = PsiTreeUtil.getParentOfType(element, PyWithItem.class); if (withItem != null && PsiTreeUtil.isAncestor(withItem.getTarget(), element, false)) { if (withItem.getTarget() == element) { registerWarning(element, warningMsg, new PyRemoveWithTargetQuickFix()); } else { registerWarning(element, warningMsg, new ReplaceWithWildCard()); } continue; } final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); if (assignmentStatement != null && !PsiTreeUtil.isAncestor(assignmentStatement.getAssignedValue(), element, false)) { if (assignmentStatement.getLeftHandSideExpression() == element) { // Single assignment target (unused = value) registerWarning(element, warningMsg, new PyRemoveAssignmentStatementTargetQuickFix(), new PyRemoveStatementQuickFix()); } else if (ArrayUtil.contains(element, assignmentStatement.getRawTargets())) { // Chained assignment target (used = unused = value) registerWarning(element, warningMsg, new PyRemoveAssignmentStatementTargetQuickFix()); } else { // Unpacking (used, unused = value) registerWarning(element, warningMsg, new ReplaceWithWildCard()); } continue; } registerWarning(element, warningMsg); } } } }