Python: drop unused, deprecated symbols.

Still used symbols are in `DeprecatedUtils` now to be dropped later

GitOrigin-RevId: 550eab3d417185b868072b06101bf7634263b4a2
This commit is contained in:
Ilya.Kazakevich
2025-05-12 17:58:14 +02:00
committed by intellij-monorepo-bot
parent c8fb196d52
commit 01754edfcb
16 changed files with 189 additions and 590 deletions

View File

@@ -1,46 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.newProject;
import com.intellij.openapi.projectRoots.Sdk;
import org.jetbrains.annotations.Nullable;
/**
* Project generation settings selected on the first page of the new project dialog.
*
* @author catherine
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
*/
@Deprecated(forRemoval = true)
public class PyNewProjectSettings {
private Sdk mySdk;
/**
* Path on remote server for remote project
*/
private @Nullable String myRemotePath;
private @Nullable Object myInterpreterInfoForStatistics;
public final @Nullable Sdk getSdk() {
return mySdk;
}
public final void setSdk(final @Nullable Sdk sdk) {
mySdk = sdk;
}
public final void setRemotePath(final @Nullable String remotePath) {
myRemotePath = remotePath;
}
public final void setInterpreterInfoForStatistics(@Nullable Object interpreterInfoForStatistics) {
myInterpreterInfoForStatistics = interpreterInfoForStatistics;
}
public final @Nullable Object getInterpreterInfoForStatistics() {
return myInterpreterInfoForStatistics;
}
public final @Nullable String getRemotePath() {
return myRemotePath;
}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.python.community.plugin.java.facet;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;

View File

@@ -24,7 +24,7 @@ import com.jetbrains.python.Result
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
import com.jetbrains.python.errorProcessing.ErrorSink
import com.jetbrains.python.inspections.PyInterpreterInspection
import com.jetbrains.python.newProject.steps.ProjectSpecificSettingsStep
import com.jetbrains.python.newProject.DeprecatedUtils
import com.jetbrains.python.projectCreation.createVenvAndSdk
import com.jetbrains.python.sdk.PySdkToInstall
import com.jetbrains.python.sdk.add.PySdkPathChoosingComboBox
@@ -111,7 +111,7 @@ internal class PythonLangSupport(private val errorSink: ErrorSink = ShowingMessa
override fun startFromWelcomeFrame(startCallback: (Sdk?) -> Unit) {
val allExistingSdks = listOf(*PyConfigurableInterpreterList.getInstance(null).model.sdks)
val existingSdks = ProjectSpecificSettingsStep.getValidPythonSdks(allExistingSdks)
val existingSdks = DeprecatedUtils.getValidPythonSdks(allExistingSdks)
ApplicationManager.getApplication().executeOnPooledThread {
val context = UserDataHolderBase()

View File

@@ -8,7 +8,7 @@ import com.intellij.openapi.util.UserDataHolderBase
import com.intellij.ui.dsl.builder.Panel
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
import com.jetbrains.python.inspections.PyInterpreterInspection
import com.jetbrains.python.newProject.steps.ProjectSpecificSettingsStep
import com.jetbrains.python.newProject.DeprecatedUtils
import com.jetbrains.python.sdk.findBaseSdks
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
import com.jetbrains.python.sdk.pythonSdk
@@ -59,7 +59,7 @@ object PythonLessonsUtil {
}
val allExistingSdks = listOf(*PyConfigurableInterpreterList.getInstance(null).model.sdks)
val existingSdks = ProjectSpecificSettingsStep.getValidPythonSdks(allExistingSdks)
val existingSdks = DeprecatedUtils.getValidPythonSdks(allExistingSdks)
val interpreterVersions = CompletableFuture<List<String>>()
ApplicationManager.getApplication().executeOnPooledThread {

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.module;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
@@ -21,8 +21,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import static com.jetbrains.python.newProject.PythonProjectGenerator.NO_SETTINGS;
public class PythonModuleBuilderBase extends ModuleBuilder {
private final List<Runnable> mySdkChangedListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@@ -92,7 +90,7 @@ public class PythonModuleBuilderBase extends ModuleBuilder {
if (contentRoots.length > 0 && contentRoots[0] != null) {
dir = contentRoots[0];
}
myGenerator.generateProject(project, dir, NO_SETTINGS, module);
myGenerator.generateProject(project, dir, new Object(), module);
}
return module;
}

View File

@@ -0,0 +1,175 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.newProject;
import com.intellij.execution.ExecutionException;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.Pair;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyPsiPackageUtil;
import com.jetbrains.python.packaging.PyPackage;
import com.jetbrains.python.packaging.PyPackageManager;
import com.jetbrains.python.packaging.PyPackageUtil;
import com.jetbrains.python.packaging.PyPackagesNotificationPanel;
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
import com.jetbrains.python.sdk.PreferredSdkComparator;
import com.jetbrains.python.sdk.PySdkExtKt;
import com.jetbrains.python.sdk.PythonSdkType;
import com.jetbrains.python.sdk.PythonSdkUtil;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
/**
* Various ancient utils that are still used, but will be dropped soon.
*
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
*/
@Deprecated(forRemoval = true)
@ApiStatus.Internal
public final class DeprecatedUtils {
private DeprecatedUtils() {
}
/**
* @param sdkAndException if you have SDK and execution exception provide them here (both must not be null).
*/
private static void reportPackageInstallationFailure(final @NotNull String frameworkName,
final @Nullable Pair<Sdk, ExecutionException> sdkAndException) {
final PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription =
getErrorDescription(sdkAndException, frameworkName);
final Application app = ApplicationManager.getApplication();
app.invokeLater(() -> {
PyPackagesNotificationPanel.showPackageInstallationError(PyBundle.message("python.new.project.install.failed.title", frameworkName),
errorDescription);
});
}
private static @NotNull PyPackageManagementService.PyPackageInstallationErrorDescription getErrorDescription(final @Nullable Pair<Sdk, ExecutionException> sdkAndException,
@NotNull String packageName) {
PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription = null;
if (sdkAndException != null) {
final ExecutionException exception = sdkAndException.second;
errorDescription =
PyPackageManagementService.toErrorDescription(Collections.singletonList(exception), sdkAndException.first, packageName);
if (errorDescription == null) {
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(exception.getMessage());
}
}
if (errorDescription == null) {
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(
PyBundle.message("python.new.project.error.solution.another.sdk"));
}
return errorDescription;
}
//TODO: Support for plugin also
/**
* Installs framework and runs callback on success.
* Installation runs in modal dialog and callback is posted to AWT thread.
* <p>
* If "forceInstallFramework" is passed then installs framework in any case.
* If SDK is remote then checks if it has interpreter and installs if missing
*
* @param frameworkName user-readable framework name (i.e. "Django")
* @param requirement name of requirement to install (i.e. "django")
* @param forceInstallFramework pass true if you are sure required framework is missing
* @param callback to be called after installation (or instead of is framework is installed) on AWT thread
* @return future to be used instead of callback.
*/
public static @NotNull Future<Void> installFrameworkIfNeeded(final @NotNull Project project,
final @NotNull String frameworkName,
final @NotNull String requirement,
final @NotNull Sdk sdk,
final boolean forceInstallFramework,
final @Nullable Runnable callback) {
var future = new CompletableFuture<Void>();
// For remote SDK we are not sure if framework exists or not, so we'll check it anyway
if (forceInstallFramework || PythonSdkUtil.isRemote(sdk)) {
ProgressManager.getInstance()
.run(new Task.Modal(project, PyBundle.message("python.install.framework.ensure.installed", frameworkName), false) {
@Override
public void run(final @NotNull ProgressIndicator indicator) {
installPackages(frameworkName, forceInstallFramework, indicator, requirement, sdk);
}
@Override
public void onThrowable(@NotNull Throwable error) {
future.completeExceptionally(error);
}
@Override
public void onSuccess() {
future.complete(null);
// Installed / checked successfully, call callback on AWT
if (callback != null) {
callback.run();
}
}
});
}
else {
future.complete(null);
// No need to install, but still need to call callback on AWT
if (callback != null) {
assert SwingUtilities.isEventDispatchThread();
callback.run();
}
}
return future;
}
private static void installPackages(final @NotNull String frameworkName,
boolean forceInstallFramework,
@NotNull ProgressIndicator indicator,
final @NotNull String requirement,
final @NotNull Sdk sdk) {
final PyPackageManager packageManager = PyPackageManager.getInstance(sdk);
boolean installed = false;
if (!forceInstallFramework) {
// First check if we need to do it
indicator.setText(PyBundle.message("python.install.framework.checking.is.installed", frameworkName));
final List<PyPackage> packages = PyPackageUtil.refreshAndGetPackagesModally(sdk);
installed = PyPsiPackageUtil.findPackage(packages, requirement) != null;
}
if (!installed) {
indicator.setText(PyBundle.message("python.install.framework.installing", frameworkName));
try {
packageManager.install(requirement);
packageManager.refresh();
}
catch (final ExecutionException e) {
reportPackageInstallationFailure(requirement, Pair.create(sdk, e));
}
}
}
// TODO: Migrate to interpreter service
public static @NotNull List<Sdk> getValidPythonSdks(@NotNull List<Sdk> existingSdks) {
return StreamEx
.of(existingSdks)
.filter(sdk -> sdk != null && sdk.getSdkType() instanceof PythonSdkType && PySdkExtKt.getSdkSeemsValid(sdk))
.sorted(new PreferredSdkComparator())
.toList();
}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.newProject
import com.intellij.ide.highlighter.ModuleFileType
@@ -19,7 +19,6 @@ import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.Panel
import com.jetbrains.python.PyBundle
import com.jetbrains.python.PythonModuleTypeBase
import com.jetbrains.python.newProject.steps.ProjectSpecificSettingsStep
import com.jetbrains.python.newProject.steps.PyAddExistingSdkPanel
import com.jetbrains.python.sdk.PySdkProvider
import com.jetbrains.python.sdk.PySdkSettings
@@ -237,5 +236,5 @@ private fun existingSdks(context: WizardContext): List<Sdk> {
disposeUIResources()
})
}
return ProjectSpecificSettingsStep.getValidPythonSdks(sdksModel.sdks.toList())
return DeprecatedUtils.getValidPythonSdks(sdksModel.sdks.toList())
}

View File

@@ -1,407 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.newProject;
import com.intellij.execution.ExecutionException;
import com.intellij.facet.ui.ValidationResult;
import com.intellij.icons.AllIcons.General;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.NlsContexts.DialogMessage;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.platform.DirectoryProjectGeneratorBase;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyPsiPackageUtil;
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo;
import com.jetbrains.python.newProjectWizard.collector.PyProjectTypeGenerator;
import com.jetbrains.python.newProjectWizard.collector.PythonNewProjectWizardCollector;
import com.jetbrains.python.packaging.PyPackage;
import com.jetbrains.python.packaging.PyPackageManager;
import com.jetbrains.python.packaging.PyPackageUtil;
import com.jetbrains.python.packaging.PyPackagesNotificationPanel;
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
import com.jetbrains.python.remote.*;
import com.jetbrains.python.sdk.PyLazySdk;
import com.jetbrains.python.sdk.PythonSdkUtil;
import com.jetbrains.python.sdk.add.v2.PythonInterpreterSelectionMode;
import com.jetbrains.python.statistics.PyStatisticToolsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Consumer;
/**
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
*/
@Deprecated(forRemoval = true)
public abstract class PythonProjectGenerator<T extends PyNewProjectSettings> extends DirectoryProjectGeneratorBase<T> implements
PyProjectTypeGenerator {
public static final PyNewProjectSettings NO_SETTINGS = new PyNewProjectSettings();
private static final Logger LOGGER = Logger.getInstance(PythonProjectGenerator.class);
private final List<SettingsListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final boolean myAllowRemoteProjectCreation;
protected Consumer<String> myErrorCallback;
private final @Nullable PythonInterpreterSelectionMode preferredEnvironmentType;
/**
* @param allowRemoteProjectCreation if project of this type could be created remotely
*/
protected PythonProjectGenerator(final boolean allowRemoteProjectCreation) {
this(allowRemoteProjectCreation, null);
}
protected PythonProjectGenerator() {
this(false, null);
}
@Override
public final @NlsSafe @NotNull String getProjectTypeForStatistics() {
return getClass().getName();
}
/**
* @param allowRemoteProjectCreation if project of this type could be created remotely
* @param preferredInterpreter interpreter type to select by default
*/
protected PythonProjectGenerator(final boolean allowRemoteProjectCreation,
@Nullable PythonInterpreterSelectionMode preferredInterpreter) {
myAllowRemoteProjectCreation = allowRemoteProjectCreation;
preferredEnvironmentType = preferredInterpreter;
}
public final void setErrorCallback(final @NotNull Consumer<String> errorCallback) {
myErrorCallback = errorCallback;
}
/**
* Checks if project type and remote ask allows project creation.
* Throws exception with reason if can't
*
* @param sdk sdk to check
* @param projectDirectory base project directory
* @throws PyNoProjectAllowedOnSdkException project can't be created (check message)
*/
public void checkProjectCanBeCreatedOnSdk(final @NotNull Sdk sdk,
final @NotNull File projectDirectory) throws PyNoProjectAllowedOnSdkException {
// Check if project does not support remote creation at all
if (!myAllowRemoteProjectCreation && PythonSdkUtil.isRemote(sdk)) {
throw new PyNoProjectAllowedOnSdkException(
PyBundle.message("python.remote.interpreter.can.t.create.project.this.type"));
}
// Check if project synchronizer could be used with this project dir
// No project can be created remotely if project synchronizer can't work with it
final PyProjectSynchronizer synchronizer = PyProjectSynchronizerProvider.getSynchronizer(sdk);
if (synchronizer == null) {
return;
}
final String syncError = synchronizer.checkSynchronizationAvailable(new PySyncCheckOnly(projectDirectory));
if (syncError != null) {
throw new PyNoProjectAllowedOnSdkException(syncError);
}
}
@Override
public final void generateProject(final @NotNull Project project,
final @NotNull VirtualFile baseDir,
final @NotNull T settings,
final @NotNull Module module) {
// Use NO_SETTINGS to avoid nullable settings of project generator
if (settings == NO_SETTINGS) {
// We are in Intellij Module and framework is implemented as project template, not facet.
// See class doc for mote info
configureProjectNoSettings(project, baseDir, module);
return;
}
/*Instead of this method overwrite ``configureProject``*/
// If we deal with remote project -- use remote manager to configure it
final Sdk sdk = settings.getSdk();
LOGGER.info(String.format("Wizard created PythonSDK %s", sdk));
if (sdk instanceof PyLazySdk) {
final Sdk createdSdk = ((PyLazySdk)sdk).create();
LOGGER.info(String.format("Lazy PythonSDK generated sdk: %s", createdSdk));
settings.setSdk(createdSdk);
}
final PyProjectSynchronizer synchronizer = sdk != null ? PyProjectSynchronizerProvider.getSynchronizer(sdk) : null;
if (synchronizer != null) {
// Before project creation we need to configure sync
// We call "checkSynchronizationAvailable" until it returns success (means sync is available)
// Or user confirms she does not need sync
String userProvidedPath = settings.getRemotePath();
while (true) {
final String syncError = synchronizer.checkSynchronizationAvailable(new PySyncCheckCreateIfPossible(module, userProvidedPath));
if (syncError == null) {
break;
}
userProvidedPath = null; // According to checkSynchronizationAvailable should be cleared
final String message =
PyBundle.message("python.new.project.synchronization.not.configured.dialog.message", syncError);
if (Messages.showYesNoDialog(project,
message,
PyBundle.message("python.new.project.synchronization.not.configured.dialog.title"),
General.WarningDialog) == Messages.YES) {
break;
}
}
}
configureProject(project, baseDir, settings, module, synchronizer);
reportStatistics(settings);
}
/**
* Report FUS statics on the created project.
* Inheritors can override this method to supply customized data for the statistics.
*/
protected void reportStatistics(final @NotNull T settings) {
var statisticsInfo = settings.getInterpreterInfoForStatistics();
if (statisticsInfo instanceof InterpreterStatisticsInfo interpreterStatisticsInfo && settings.getSdk() != null) {
PythonNewProjectWizardCollector.logPythonNewProjectGenerated(interpreterStatisticsInfo,
PyStatisticToolsKt.getVersion(settings.getSdk()),
this,
Collections.emptyList());
}
}
/**
* Same as {@link #configureProject(Project, VirtualFile, PyNewProjectSettings, Module, PyProjectSynchronizer)}
* but with out of settings. Called by Intellij Plugin when framework is installed as project template.
*/
protected void configureProjectNoSettings(final @NotNull Project project,
final @NotNull VirtualFile baseDir,
final @NotNull Module module) {
throw new IllegalStateException(String.format("%s does not support project creation with out of settings. " +
"See %s doc for detail", getClass(), PythonProjectGenerator.class));
}
/**
* Does real work to generate project.
* Parent class does its best to handle remote interpreters.
* Inheritors should only create project.
* To support remote project creation, be sure to use {@link PyProjectSynchronizer}.
* <br/>
* When overwriting this method, <strong>be sure</strong> to call super() or call
* {@link PyProjectSynchronizer#syncProject(Module, PySyncDirection, Consumer, String...)} at least once: automatic sync works only after it.
*
* @param synchronizer null if project is local and no sync required.
* Otherwise, be sure to use it move code between local (java) and remote (python) side.
* Remote interpreters can't be used with out of it. Contract is following:
* <ol>
* <li>Create some code on python (remote) side using helpers</li>
* <li>call {@link PyProjectSynchronizer#syncProject(Module, PySyncDirection, Consumer, String...)}</li>
* <li>Change locally</li>
* <li>call {@link PyProjectSynchronizer#syncProject(Module, PySyncDirection, Consumer, String...)} again in opposite direction</li>
* </ol>
*/
protected void configureProject(final @NotNull Project project,
final @NotNull VirtualFile baseDir,
final @NotNull T settings,
final @NotNull Module module,
final @Nullable PyProjectSynchronizer synchronizer) {
// Automatic deployment works only after first sync
if (synchronizer != null) {
synchronizer.syncProject(module, PySyncDirection.LOCAL_TO_REMOTE, null);
}
}
public Object getProjectSettings() {
return new PyNewProjectSettings();
}
public ValidationResult warningValidation(final @Nullable Sdk sdk) {
return ValidationResult.OK;
}
public void addSettingsStateListener(@NotNull SettingsListener listener) {
myListeners.add(listener);
}
public void locationChanged(final @NotNull String newLocation) {
}
/**
* @return Python interpreter type this generator prefered to use. Null if no preferences
*/
public final @Nullable PythonInterpreterSelectionMode getPreferredEnvironmentType() {
return preferredEnvironmentType;
}
public interface SettingsListener {
void stateChanged();
}
public void afterProjectGenerated(final @NotNull Project project) {
}
/**
* @param sdkAndException if you have SDK and execution exception provide them here (both must not be null).
*/
protected static void reportPackageInstallationFailure(final @NotNull String frameworkName,
final @Nullable Pair<Sdk, ExecutionException> sdkAndException) {
final PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription =
getErrorDescription(sdkAndException, frameworkName);
final Application app = ApplicationManager.getApplication();
app.invokeLater(() -> {
PyPackagesNotificationPanel.showPackageInstallationError(PyBundle.message("python.new.project.install.failed.title", frameworkName),
errorDescription);
});
}
private static @NotNull PyPackageManagementService.PyPackageInstallationErrorDescription getErrorDescription(final @Nullable Pair<Sdk, ExecutionException> sdkAndException,
@NotNull String packageName) {
PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription = null;
if (sdkAndException != null) {
final ExecutionException exception = sdkAndException.second;
errorDescription =
PyPackageManagementService.toErrorDescription(Collections.singletonList(exception), sdkAndException.first, packageName);
if (errorDescription == null) {
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(exception.getMessage());
}
}
if (errorDescription == null) {
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(
PyBundle.message("python.new.project.error.solution.another.sdk"));
}
return errorDescription;
}
//TODO: Support for plugin also
/**
* Installs framework and runs callback on success.
* Installation runs in modal dialog and callback is posted to AWT thread.
* <p>
* If "forceInstallFramework" is passed then installs framework in any case.
* If SDK is remote then checks if it has interpreter and installs if missing
*
* @param frameworkName user-readable framework name (i.e. "Django")
* @param requirement name of requirement to install (i.e. "django")
* @param forceInstallFramework pass true if you are sure required framework is missing
* @param callback to be called after installation (or instead of is framework is installed) on AWT thread
* @return future to be used instead of callback.
*/
public static @NotNull Future<Void> installFrameworkIfNeeded(final @NotNull Project project,
final @NotNull String frameworkName,
final @NotNull String requirement,
final @NotNull Sdk sdk,
final boolean forceInstallFramework,
final @Nullable Runnable callback) {
var future = new CompletableFuture<Void>();
// For remote SDK we are not sure if framework exists or not, so we'll check it anyway
if (forceInstallFramework || PythonSdkUtil.isRemote(sdk)) {
ProgressManager.getInstance()
.run(new Task.Modal(project, PyBundle.message("python.install.framework.ensure.installed", frameworkName), false) {
@Override
public void run(final @NotNull ProgressIndicator indicator) {
installPackages(frameworkName, forceInstallFramework, indicator, requirement, sdk);
}
@Override
public void onThrowable(@NotNull Throwable error) {
future.completeExceptionally(error);
}
@Override
public void onSuccess() {
future.complete(null);
// Installed / checked successfully, call callback on AWT
if (callback != null) {
callback.run();
}
}
});
}
else {
future.complete(null);
// No need to install, but still need to call callback on AWT
if (callback != null) {
assert SwingUtilities.isEventDispatchThread();
callback.run();
}
}
return future;
}
public @Nullable String getNewProjectPrefix() {
return null;
}
public boolean supportsWelcomeScript() {
return false;
}
/**
* To be thrown if project can't be created on this sdk
*
* @author Ilya.Kazakevich
*/
public static class PyNoProjectAllowedOnSdkException extends Exception {
/**
* @param reason why project can't be created
*/
PyNoProjectAllowedOnSdkException(final @NotNull @DialogMessage String reason) {
super(reason);
}
}
private static void installPackages(final @NotNull String frameworkName,
boolean forceInstallFramework,
@NotNull ProgressIndicator indicator,
final @NotNull String requirement,
final @NotNull Sdk sdk) {
final PyPackageManager packageManager = PyPackageManager.getInstance(sdk);
boolean installed = false;
if (!forceInstallFramework) {
// First check if we need to do it
indicator.setText(PyBundle.message("python.install.framework.checking.is.installed", frameworkName));
final List<PyPackage> packages = PyPackageUtil.refreshAndGetPackagesModally(sdk);
installed = PyPsiPackageUtil.findPackage(packages, requirement) != null;
}
if (!installed) {
indicator.setText(PyBundle.message("python.install.framework.installing", frameworkName));
try {
packageManager.install(requirement);
packageManager.refresh();
}
catch (final ExecutionException e) {
reportPackageInstallationFailure(requirement, Pair.create(sdk, e));
}
}
}
}

View File

@@ -1,29 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.newProject.steps;
import com.intellij.openapi.projectRoots.Sdk;
import com.jetbrains.python.sdk.PreferredSdkComparator;
import com.jetbrains.python.sdk.PySdkExtKt;
import com.jetbrains.python.sdk.PythonSdkType;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
*/
@Deprecated(forRemoval = true)
public final class ProjectSpecificSettingsStep {
private ProjectSpecificSettingsStep() {
}
// TODO: Migrate to interpreter service
public static @NotNull List<Sdk> getValidPythonSdks(@NotNull List<Sdk> existingSdks) {
return StreamEx
.of(existingSdks)
.filter(sdk -> sdk != null && sdk.getSdkType() instanceof PythonSdkType && PySdkExtKt.getSdkSeemsValid(sdk))
.sorted(new PreferredSdkComparator())
.toList();
}
}

View File

@@ -1,32 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.newProject.steps
import com.intellij.ide.IdeBundle
import com.intellij.openapi.GitRepositoryInitializer
import com.intellij.openapi.progress.runBackgroundableTask
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
/**
* @deprecated Use [com.jetbrains.python.newProjectWizard]
*/
@java.lang.Deprecated(forRemoval = true)
@Deprecated("use com.jetbrains.python.newProjectWizard", level = DeprecationLevel.ERROR)
class PythonProjectSpecificSettingsStep {
companion object {
/**
* @deprecated Use [com.jetbrains.python.newProjectWizard]
*/
@JvmStatic
@java.lang.Deprecated(forRemoval = true)
@Deprecated("use PyV3 in com.jetbrains.python.newProjectWizard or access GitRepositoryInitializer directly",
level = DeprecationLevel.ERROR)
fun initializeGit(project: Project, root: VirtualFile) {
runBackgroundableTask(IdeBundle.message("progress.title.creating.git.repository"), project) {
GitRepositoryInitializer.getInstance()?.initRepository(project, root, true)
}
}
}
}

View File

@@ -18,7 +18,6 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.jetbrains.python.PySdkBundle;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.sdk.PyLazySdk;
import com.jetbrains.python.sdk.PySdkExtKt;
import com.jetbrains.python.sdk.PySdkUtil;
import com.jetbrains.python.sdk.PythonEnvUtil;
@@ -152,10 +151,6 @@ public class PyPackageManagerImpl extends PyPackageManagerImplBase {
@Override
protected @NotNull List<PyPackage> collectPackages() throws ExecutionException {
if (getSdk() instanceof PyLazySdk) {
return List.of();
}
try {
LOG.debug("Collecting installed packages for the SDK " + getSdk().getName(), new Throwable());
String output = getHelperResult(List.of("list"), false, false);

View File

@@ -33,7 +33,6 @@ import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory;
import com.jetbrains.python.run.PythonScriptExecution;
import com.jetbrains.python.run.PythonScripts;
import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest;
import com.jetbrains.python.sdk.PyLazySdk;
import com.jetbrains.python.sdk.PySdkExtKt;
import com.jetbrains.python.venvReader.VirtualEnvReader;
import org.jetbrains.annotations.ApiStatus;
@@ -181,10 +180,6 @@ public final class PyTargetEnvironmentPackageManager extends PyPackageManagerImp
@Override
protected @NotNull List<PyPackage> collectPackages() throws ExecutionException {
if (getSdk() instanceof PyLazySdk) {
return List.of();
}
HelpersAwareTargetEnvironmentRequest helpersAwareRequest = getPythonTargetInterpreter();
TargetEnvironmentRequest targetEnvironmentRequest = helpersAwareRequest.getTargetEnvironmentRequest();
final String output;

View File

@@ -6,6 +6,7 @@ import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.runBlockingCancellable
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.jetbrains.python.PyBundle
import com.jetbrains.python.packaging.PyPackage
import com.jetbrains.python.packaging.PyRequirement
@@ -16,6 +17,7 @@ import org.jetbrains.annotations.ApiStatus
class PythonPackagesInstaller {
companion object {
@JvmStatic
@RequiresBackgroundThread
fun installPackages(
project: Project,
sdk: Sdk,

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.remote
import com.intellij.openapi.extensions.ExtensionPointName
@@ -31,7 +17,7 @@ typealias PathMappings = List<PathMappingSettings.PathMapping>
/**
* ProjectSynchronizer is an engine that synchronize code between local and remote system or between java (which is local)
* and python (which may be remote).
* This engine is sdk-specific and used by [com.jetbrains.python.newProject.PythonProjectGenerator] (and friends).
* This engine is sdk-specific and used by [com.jetbrains.python.newProject.DeprecatedUtils] (and friends).
*
* When generator creates remote project, it may use python helpers (with aid of tasks) and it may need some way
* to pull remote files, patch them and push 'em back. The way it does it is skd-specific and this interface encapsulates it.

View File

@@ -1,26 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.sdk
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl
import com.intellij.openapi.util.NullableComputable
@java.lang.Deprecated(forRemoval = true)
@Deprecated("Migrate to `com.jetbrains.python.newProjectWizard`, it doesn't need this class", level = DeprecationLevel.WARNING)
class PyLazySdk(name: String, private val create: NullableComputable<Sdk>) : ProjectJdkImpl(name, PythonSdkType.getInstance(), "", null) {
fun create(): Sdk? = create.compute()
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.sdk.add.v1
import com.intellij.execution.target.FullPathOnTarget
@@ -172,8 +172,6 @@ class PyAddCondaPanelModel(val targetConfiguration: TargetEnvironmentConfigurati
private fun condaPathIsValid(path: FullPathOnTarget): Boolean = path.matches(condaPathRegex)
fun isCondaPathValid() = condaPathIsValid(condaPathTextBoxRwProp.get())
/**
* Detects condas in well-known locations so user doesn't have to provide conda path
@@ -211,15 +209,6 @@ class PyAddCondaPanelModel(val targetConfiguration: TargetEnvironmentConfigurati
}
}
/**
* This method ignores the error if condaEnvs are not loaded yet
* @return either null (if no error in name validation) or localized error string
*/
fun getEnvIdentitiesNameValidationError(): @Nls String? {
val envIdentities = getEnvIdentities().getOrElse { return null }
return validateEnvIdentitiesName(envIdentities)
}
/**
* This method returns envIdentities from loaded envs
*/