Show warnings about unsupported python interpreter (PY-27705)

This commit is contained in:
Semyon Proshev
2018-01-24 17:03:03 +03:00
parent 257fe1163c
commit 0cfe9ad924
4 changed files with 54 additions and 16 deletions

View File

@@ -32,12 +32,12 @@ import java.util.stream.Stream;
public enum LanguageLevel {
/**
* @deprecated This level will be removed in 2018.2.
* @deprecated This level is not supported since 2018.1.
*/
@Deprecated
PYTHON24(24, false, true, false, false),
/**
* @deprecated This level will be removed in 2018.2.
* @deprecated This level is not supported since 2018.1.
*/
@Deprecated
PYTHON25(25, false, true, false, false),
@@ -123,6 +123,12 @@ public enum LanguageLevel {
public static LanguageLevel fromPythonVersion(@NotNull String pythonVersion) {
if (pythonVersion.startsWith("2")) {
if (pythonVersion.startsWith("2.4")) {
return PYTHON24;
}
if (pythonVersion.startsWith("2.5")) {
return PYTHON25;
}
if (pythonVersion.startsWith("2.6")) {
return PYTHON26;
}

View File

@@ -27,6 +27,7 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.util.PlatformUtils;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.Nls;
@@ -35,6 +36,7 @@ import org.jetbrains.annotations.Nullable;
public class PyInterpreterInspection extends PyInspection {
@Override
@Nls
@NotNull
public String getDisplayName() {
@@ -58,17 +60,29 @@ public class PyInterpreterInspection extends PyInspection {
@Override
public void visitPyFile(PyFile node) {
super.visitPyFile(node);
if (PlatformUtils.isPyCharm()) {
final Module module = ModuleUtilCore.findModuleForPsiElement(node);
if (module != null) {
final Sdk sdk = PythonSdkType.findPythonSdk(module);
if (sdk == null) {
registerProblem(node, "No Python interpreter configured for the project", new ConfigureInterpreterFix());
}
else if (PythonSdkType.isInvalid(sdk)) {
registerProblem(node, "Invalid Python interpreter selected for the project", new ConfigureInterpreterFix());
}
final Module module = ModuleUtilCore.findModuleForPsiElement(node);
if (module == null) return;
final boolean pyCharm = PlatformUtils.isPyCharm();
final String interpreterOwner = pyCharm ? "project" : "module";
final LocalQuickFix[] fixes = pyCharm ? new LocalQuickFix[]{new ConfigureInterpreterFix()} : LocalQuickFix.EMPTY_ARRAY;
final String product = pyCharm ? "PyCharm" : "Python plugin";
final Sdk sdk = PythonSdkType.findPythonSdk(module);
if (sdk == null) {
registerProblem(node, "No Python interpreter configured for the " + interpreterOwner, fixes);
}
else if (PythonSdkType.isInvalid(sdk)) {
registerProblem(node, "Invalid Python interpreter selected for the " + interpreterOwner, fixes);
}
else {
final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(sdk);
if (!LanguageLevel.SUPPORTED_LEVELS.contains(languageLevel)) {
registerProblem(node,
"Python " + languageLevel + " has reached its end-of-life and is no longer supported by " + product,
fixes);
}
}
}
@@ -79,7 +93,7 @@ public class PyInterpreterInspection extends PyInspection {
@NotNull
@Override
public String getFamilyName() {
return "Configure Python Interpreter";
return "Configure Python interpreter";
}
@Override

View File

@@ -84,6 +84,12 @@ public class PyPackageManagerImpl extends PyPackageManager {
@Override
public void installManagement() throws ExecutionException {
final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(getSdk());
if (languageLevel.isOlderThan(LanguageLevel.PYTHON26)) {
throw new ExecutionException("Package management for Python " + languageLevel + " is not supported. " +
"Upgrade your project interpreter to Python " + LanguageLevel.PYTHON26 + " or newer");
}
if (!refreshAndCheckForSetuptools()) {
installManagement(PyPackageUtil.SETUPTOOLS + "-" + SETUPTOOLS_VERSION);
}
@@ -161,12 +167,12 @@ public class PyPackageManagerImpl extends PyPackageManager {
@Override
public void install(@NotNull String requirementString) throws ExecutionException {
installManagement();
install(Collections.singletonList(PyRequirement.fromLine(requirementString)), Collections.emptyList());
}
@Override
public void install(@NotNull List<PyRequirement> requirements, @NotNull List<String> extraArgs) throws ExecutionException {
installManagement();
final List<String> args = new ArrayList<>();
args.add(INSTALL);
final File buildDir;
@@ -292,6 +298,12 @@ public class PyPackageManagerImpl extends PyPackageManager {
final List<String> args = new ArrayList<>();
final Sdk sdk = getSdk();
final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(sdk);
if (languageLevel.isOlderThan(LanguageLevel.PYTHON26)) {
throw new ExecutionException("Creating virtual environment for Python " + languageLevel + " is not supported. " +
"Upgrade your project interpreter to Python " + LanguageLevel.PYTHON26 + " or newer");
}
final boolean usePyVenv = languageLevel.isAtLeast(LanguageLevel.PYTHON33);
if (usePyVenv) {
args.add("pyvenv");

View File

@@ -26,6 +26,7 @@ import com.intellij.ui.LayeredIcon
import com.intellij.ui.SimpleTextAttributes
import com.intellij.ui.TitledSeparator
import com.intellij.util.ui.JBUI
import com.jetbrains.python.psi.LanguageLevel
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
import java.awt.Component
import javax.swing.Icon
@@ -62,6 +63,8 @@ open class PySdkListCellRenderer(private val sdkModifiers: Map<Sdk, SdkModificat
append("[invalid] $name", SimpleTextAttributes.ERROR_ATTRIBUTES)
PythonSdkType.isIncompleteRemote(sdk) ->
append("[incomplete] $name", SimpleTextAttributes.ERROR_ATTRIBUTES)
!LanguageLevel.SUPPORTED_LEVELS.contains(PythonSdkType.getLanguageLevelForSdk(sdk)) ->
append("[unsupported] $name", SimpleTextAttributes.ERROR_ATTRIBUTES)
else ->
append(name)
}
@@ -79,7 +82,10 @@ open class PySdkListCellRenderer(private val sdkModifiers: Map<Sdk, SdkModificat
val flavor = PythonSdkFlavor.getPlatformIndependentFlavor(sdk.homePath)
val icon = if (flavor != null) flavor.icon else (sdk.sdkType as? SdkType)?.icon ?: return null
return when {
PythonSdkType.isInvalid(sdk) || PythonSdkType.isIncompleteRemote(sdk) || PythonSdkType.hasInvalidRemoteCredentials(sdk) ->
PythonSdkType.isInvalid(sdk) ||
PythonSdkType.isIncompleteRemote(sdk) ||
PythonSdkType.hasInvalidRemoteCredentials(sdk) ||
!LanguageLevel.SUPPORTED_LEVELS.contains(PythonSdkType.getLanguageLevelForSdk(sdk)) ->
wrapIconWithWarningDecorator(icon)
sdk is PyDetectedSdk ->
IconLoader.getTransparentIcon(icon)