mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Many pypi packages could install same modules. Support this in PyPIPackageUtil.PACKAGES_TOPLEVEL and its usages.
This commit is contained in:
@@ -62,9 +62,10 @@ object PyTypeShed {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
return true
|
||||
}
|
||||
val pyPIPackage = PyPIPackageUtil.PACKAGES_TOPLEVEL[topLevelPackage] ?: topLevelPackage
|
||||
val pyPIPackages = PyPIPackageUtil.PACKAGES_TOPLEVEL[topLevelPackage] ?: emptyList()
|
||||
val packages = PyPackageManagers.getInstance().forSdk(sdk).packages ?: return true
|
||||
return PyPackageUtil.findPackage(packages, pyPIPackage) != null
|
||||
return PyPackageUtil.findPackage(packages, topLevelPackage) != null ||
|
||||
pyPIPackages.any { PyPackageUtil.findPackage(packages, it) != null }
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.codeInsight.imports.AddImportHelper;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyStdlibUtil;
|
||||
@@ -159,10 +160,11 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
|
||||
final String packageName = packageReferenceExpression.getName();
|
||||
if (packageName != null && !myIgnoredPackages.contains(packageName)) {
|
||||
final String possiblePyPIPackageName = PyPIPackageUtil.PACKAGES_TOPLEVEL.get(packageName);
|
||||
final List<String> possiblePyPIPackageNames = PyPIPackageUtil.PACKAGES_TOPLEVEL.getOrDefault(packageName, Collections.emptyList());
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() &&
|
||||
StreamEx.of(packageName, possiblePyPIPackageName).nonNull().noneMatch(PyPIPackageUtil.INSTANCE::isInPyPI)) return;
|
||||
!PyPIPackageUtil.INSTANCE.isInPyPI(packageName) &&
|
||||
!ContainerUtil.exists(possiblePyPIPackageNames, PyPIPackageUtil.INSTANCE::isInPyPI)) return;
|
||||
|
||||
if (PyPackageUtil.SETUPTOOLS.equals(packageName)) return;
|
||||
|
||||
@@ -177,16 +179,16 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
|
||||
for (PyRequirement req : requirements) {
|
||||
final String name = req.getName();
|
||||
if (packageName.equalsIgnoreCase(name) || possiblePyPIPackageName != null && possiblePyPIPackageName.equalsIgnoreCase(name)) {
|
||||
if (name.equalsIgnoreCase(packageName) || ContainerUtil.exists(possiblePyPIPackageNames, name::equalsIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
final String nameWhereUnderscoreReplacedWithHyphen = name.replaceAll("_", "-");
|
||||
if (possiblePyPIPackageName != null && possiblePyPIPackageName.equalsIgnoreCase(nameWhereUnderscoreReplacedWithHyphen)) {
|
||||
if (ContainerUtil.exists(possiblePyPIPackageNames, nameWhereUnderscoreReplacedWithHyphen::equalsIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
final String nameWhereHyphenReplacedWithUnderscore = name.replaceAll("-", "_");
|
||||
if (packageName.equalsIgnoreCase(nameWhereHyphenReplacedWithUnderscore) ||
|
||||
possiblePyPIPackageName != null && possiblePyPIPackageName.equalsIgnoreCase(nameWhereHyphenReplacedWithUnderscore)) {
|
||||
if (nameWhereHyphenReplacedWithUnderscore.equalsIgnoreCase(packageName) ||
|
||||
ContainerUtil.exists(possiblePyPIPackageNames, nameWhereHyphenReplacedWithUnderscore::equalsIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -208,8 +210,8 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
}
|
||||
|
||||
final String suggestedPackageName = StreamEx
|
||||
.of(packageName, possiblePyPIPackageName)
|
||||
.nonNull()
|
||||
.of(packageName)
|
||||
.append(possiblePyPIPackageNames)
|
||||
.findFirst(PyPIPackageUtil.INSTANCE::isInPyPI)
|
||||
.orElse(packageName);
|
||||
|
||||
|
||||
+5
-9
@@ -635,15 +635,11 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(node);
|
||||
final Sdk sdk = PythonSdkType.findPythonSdk(module);
|
||||
if (module != null && sdk != null && PyPackageUtil.packageManagementEnabled(sdk)) {
|
||||
if (PyPIPackageUtil.INSTANCE.isInPyPI(packageName)) {
|
||||
addInstallPackageAction(actions, packageName, module, sdk);
|
||||
}
|
||||
else {
|
||||
if (PyPIPackageUtil.PACKAGES_TOPLEVEL.containsKey(packageName)) {
|
||||
final String suggestedPackage = PyPIPackageUtil.PACKAGES_TOPLEVEL.get(packageName);
|
||||
addInstallPackageAction(actions, suggestedPackage, module, sdk);
|
||||
}
|
||||
}
|
||||
StreamEx
|
||||
.of(packageName)
|
||||
.append(PyPIPackageUtil.PACKAGES_TOPLEVEL.getOrDefault(packageName, Collections.emptyList()))
|
||||
.filter(PyPIPackageUtil.INSTANCE::isInPyPI)
|
||||
.forEach(pkg -> addInstallPackageAction(actions, pkg, module, sdk));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,9 +28,9 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.CatchingConsumer;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.HttpRequests;
|
||||
import com.intellij.webcore.packaging.PackageVersionComparator;
|
||||
@@ -44,11 +44,12 @@ import javax.swing.text.MutableAttributeSet;
|
||||
import javax.swing.text.html.HTML;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import javax.swing.text.html.parser.ParserDelegator;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -64,9 +65,9 @@ public class PyPIPackageUtil {
|
||||
public static final String PYPI_LIST_URL = PYPI_HOST + "/simple";
|
||||
|
||||
/**
|
||||
* Contains mapping "importable top-level package" -> "package name on PyPI".
|
||||
* Contains mapping "importable top-level package" -> "package names on PyPI".
|
||||
*/
|
||||
public static final ImmutableMap<String, String> PACKAGES_TOPLEVEL = loadPackageAliases();
|
||||
public static final ImmutableMap<String, List<String>> PACKAGES_TOPLEVEL = loadPackageAliases();
|
||||
|
||||
public static final PyPIPackageUtil INSTANCE = new PyPIPackageUtil();
|
||||
|
||||
@@ -138,15 +139,17 @@ public class PyPIPackageUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ImmutableMap<String, String> loadPackageAliases() {
|
||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||
try (FileReader reader = new FileReader(PythonHelpersLocator.getHelperPath("/tools/packages"))) {
|
||||
final String text = FileUtil.loadTextAndClose(reader);
|
||||
final List<String> lines = StringUtil.split(text, "\n");
|
||||
for (String line : lines) {
|
||||
final List<String> split = StringUtil.split(line, " ");
|
||||
builder.put(split.get(0), split.get(1));
|
||||
}
|
||||
private static ImmutableMap<String, List<String>> loadPackageAliases() {
|
||||
final ImmutableMap.Builder<String, List<String>> builder = ImmutableMap.builder();
|
||||
try {
|
||||
Files
|
||||
.lines(Paths.get(PythonHelpersLocator.getHelperPath("/tools/packages")))
|
||||
.forEach(
|
||||
line -> {
|
||||
final List<String> split = StringUtil.split(line, " ");
|
||||
builder.put(split.get(0), new SmartList<>(ContainerUtil.subList(split, 1)));
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("Cannot find \"packages\". " + e.getMessage());
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
django-recaptcha-mozilla
|
||||
pyzmq-ctypes
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<warning descr="Package requirements 'django-recaptcha-mozilla', 'pyzmq-ctypes' are not satisfied">import captcha
|
||||
import zmq</warning>
|
||||
+4
@@ -65,6 +65,10 @@ public class PyPackageRequirementsInspectionTest extends PyTestCase {
|
||||
doTest("test1.py");
|
||||
}
|
||||
|
||||
public void testOnePackageManyPossibleRequirements() {
|
||||
doTest("test1.py");
|
||||
}
|
||||
|
||||
private void doTest(@NotNull final String filename) {
|
||||
final String testName = getTestName(false);
|
||||
myFixture.copyDirectoryToProject("inspections/PyPackageRequirementsInspection/" + testName, "");
|
||||
|
||||
Reference in New Issue
Block a user