List<PsiElement> () { if (getAllImports().isEmpty()) { return Collections.emptyList(); } // PY-1315 Unused imports inspection shouldn't work in python REPL console final PyImportedNameDefiner first = getAllImports().iterator().next(); if (first.getContainingFile() instanceof PyExpressionCodeFragment || PythonRuntimeService.getInstance().isInPydevConsole(first)) { return Collections.emptyList(); } List<PsiElement> result = new ArrayList<>(); Set<PyImportedNameDefiner> unusedImports = new HashSet<>(getAllImports()); unusedImports.removeAll(getUsedImports()); // Remove those unsed, that are reported to be skipped by extension points final Set<PyImportedNameDefiner> unusedImportToSkip = new HashSet<>(); for (final PyImportedNameDefiner unusedImport : unusedImports) { if (PyInspectionExtension.EP_NAME.getExtensionList().stream().anyMatch(o -> o.ignoreUnusedImports(unusedImport))) { unusedImportToSkip.add(unusedImport); } } unusedImports.removeAll(unusedImportToSkip); Set<String> usedImportNames = new HashSet<>(); for (PyImportedNameDefiner usedImport : getUsedImports()) { for (PyElement e : usedImport.iterateNames()) { usedImportNames.add(e.getName()); } } Set<PyImportStatementBase> unusedStatements = new HashSet<>(); QualifiedName packageQName = null; List<String> dunderAll = null; // TODO: Use strategies instead of pack of "continue" iterUnused: for (PyImportedNameDefiner unusedImport : unusedImports) { if (packageQName == null) { final PsiFile file = unusedImport.getContainingFile(); if (file instanceof PyFile) { dunderAll = ((PyFile)file).getDunderAll(); } if (file != null && PyUtil.isPackage(file)) { packageQName = QualifiedNameFinder.findShortestImportableQName(file); } } PyImportStatementBase importStatement = PsiTreeUtil.getParentOfType(unusedImport, PyImportStatementBase.class); if (importStatement != null && !unusedStatements.contains(importStatement) && !getUsedImports().contains(unusedImport)) { PyInspection inspection = myInspection; assert inspection != null; if (inspection.isSuppressedFor(importStatement)) { continue; } // don't remove as unused imports in try/except statements if (PsiTreeUtil.getParentOfType(importStatement, PyTryExceptStatement.class) != null) { continue; } // Don't report conditional imports as unused if (PsiTreeUtil.getParentOfType(unusedImport, PyIfStatement.class) != null) { for (PyElement e : unusedImport.iterateNames()) { if (usedImportNames.contains(e.getName())) { continue iterUnused; } } } PsiFileSystemItem importedElement; if (unusedImport instanceof PyImportElement importElement) { final PsiElement element = importElement.resolve(); if (element == null) { if (importElement.getImportedQName() != null) { //Mark import as unused even if it can't be resolved if (areAllImportsUnused(importStatement, unusedImports)) { result.add(importStatement); } else { result.add(importElement); } } continue; } if (dunderAll != null && dunderAll.contains(importElement.getVisibleName())) { continue; } importedElement = element.getContainingFile(); } else { assert importStatement instanceof PyFromImportStatement; importedElement = ((PyFromImportStatement)importStatement).resolveImportSource(); if (importedElement == null) { continue; } } if (packageQName != null && importedElement != null) { final QualifiedName importedQName = QualifiedNameFinder.findShortestImportableQName(importedElement); if (importedQName != null && importedQName.matchesPrefix(packageQName)) { continue; } } if (unusedImport instanceof PyStarImportElement || areAllImportsUnused(importStatement, unusedImports)) { unusedStatements.add(importStatement); result.add(importStatement); } else { result.add(unusedImport); } } } return result; }