From 5f648e46e5ad7357f11116f62a0551951e9ce024 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 6 Jan 2026 15:26:27 +0100 Subject: [PATCH] cleanup [python]: Remove unused, pre-target APIs (cherry picked from commit 11a0ac8481da2f8dc14d8cce9b7ecce17ae8df5b) IJ-MR-187064 GitOrigin-RevId: 979870da15b64fdeea9b202888193dafbc2b74f0 --- .../intellij.python.community.impl.xml | 6 - .../jetbrains/python/PyHelpersDataConstant.kt | 6 + .../configuration/PyRemotePathEditor.java | 11 +- .../PythonInterpreterDetailsConfigurables.kt | 22 -- .../PydevConsoleCommunicationClient.kt | 200 ------------- .../console/PydevConsoleRunnerImpl.java | 24 +- .../python/console/PydevConsoleRunnerUtil.kt | 13 - .../PythonConsoleRemoteProcessCreator.kt | 29 -- .../python/debugger/PyDebugRunner.java | 5 - .../python/remote/NewFilesProcessor.java | 19 +- .../python/remote/PyProjectSynchronizer.kt | 142 ---------- .../python/remote/PyRemoteFilesChooser.kt | 11 - .../remote/PyRemoteInterpreterUtil.java | 67 ----- .../remote/PyRemoteSdkAdditionalData.java | 264 ------------------ .../remote/PyRemoteSdkAdditionalDataBase.java | 17 -- .../python/remote/PyRemoteSdkWithoutSudo.kt | 12 +- .../PyRemoteSocketToLocalHostProvider.java | 1 - .../remote/PyUnknownProjectSynchronizer.java | 57 ---- .../PythonRemoteInterpreterManager.java | 9 - .../remote/PythonSshInterpreterManager.java | 13 - .../run/PyRemoteAnalyzeStacktraceFilter.java | 49 ---- .../python/run/PyRemoteProcessStarter.java | 67 ----- .../run/PyRemoteProcessStarterManager.java | 54 ---- .../PyRemoteProcessStarterManagerUtil.java | 33 --- .../python/run/PythonCommandLineState.java | 59 ++-- ...thonInterpreterTargetEnvironmentFactory.kt | 3 +- .../com/jetbrains/python/run/PythonTask.java | 15 +- .../com/jetbrains/python/sdk/PyInvalidSdk.kt | 7 + .../src/com/jetbrains/python/sdk/PySdkExt.kt | 12 +- .../jetbrains/python/sdk/PythonSdkType.java | 63 +---- .../python/sdk/conda/PyAddCondaTools.kt | 7 - .../com/jetbrains/python/sdk/sdkExecApi.kt | 2 - .../python/statistics/PyStatisticTools.kt | 11 - .../target/PyTargetAwareAdditionalData.kt | 36 +-- .../PyProjectSynchronizerProviderTest.kt | 96 ------- .../python/sdk/PySdkAdditionalDataTest.kt | 8 - .../python/sdk/PythonSdkTypePlatformTest.java | 6 - 37 files changed, 69 insertions(+), 1387 deletions(-) create mode 100644 python/src/com/jetbrains/python/PyHelpersDataConstant.kt delete mode 100644 python/src/com/jetbrains/python/console/PydevConsoleCommunicationClient.kt delete mode 100644 python/src/com/jetbrains/python/remote/PyProjectSynchronizer.kt delete mode 100644 python/src/com/jetbrains/python/remote/PyRemoteFilesChooser.kt delete mode 100644 python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java delete mode 100644 python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java delete mode 100644 python/src/com/jetbrains/python/remote/PyUnknownProjectSynchronizer.java delete mode 100644 python/src/com/jetbrains/python/run/PyRemoteAnalyzeStacktraceFilter.java delete mode 100644 python/src/com/jetbrains/python/run/PyRemoteProcessStarterManager.java delete mode 100644 python/src/com/jetbrains/python/run/PyRemoteProcessStarterManagerUtil.java create mode 100644 python/src/com/jetbrains/python/sdk/PyInvalidSdk.kt delete mode 100644 python/testSrc/com/jetbrains/python/remote/PyProjectSynchronizerProviderTest.kt diff --git a/python/pluginResources/intellij.python.community.impl.xml b/python/pluginResources/intellij.python.community.impl.xml index c296a13e51a4..0b6e2441f064 100644 --- a/python/pluginResources/intellij.python.community.impl.xml +++ b/python/pluginResources/intellij.python.community.impl.xml @@ -371,7 +371,6 @@ implementation="com.jetbrains.python.refactoring.changeSignature.PyChangeSignatureUsageProcessor" id="Python"/> - @@ -746,8 +745,6 @@ - - diff --git a/python/src/com/jetbrains/python/PyHelpersDataConstant.kt b/python/src/com/jetbrains/python/PyHelpersDataConstant.kt new file mode 100644 index 000000000000..8e8c26b70d83 --- /dev/null +++ b/python/src/com/jetbrains/python/PyHelpersDataConstant.kt @@ -0,0 +1,6 @@ +package com.jetbrains.python + +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +const val PYCHARM_HELPERS: String = ".pycharm_helpers" diff --git a/python/src/com/jetbrains/python/configuration/PyRemotePathEditor.java b/python/src/com/jetbrains/python/configuration/PyRemotePathEditor.java index 0fc5737b7311..f1d12cabaa6a 100644 --- a/python/src/com/jetbrains/python/configuration/PyRemotePathEditor.java +++ b/python/src/com/jetbrains/python/configuration/PyRemotePathEditor.java @@ -19,9 +19,7 @@ import com.intellij.ui.ToolbarDecorator; import com.intellij.util.ArrayUtil; import com.intellij.util.PathMappingSettings; import com.jetbrains.python.PyBundle; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; import com.jetbrains.python.remote.PyRemoteSourceItem; -import com.jetbrains.python.remote.PythonRemoteInterpreterManager; import com.jetbrains.python.sdk.PySdkExtKt; import com.jetbrains.python.target.PyTargetAwareAdditionalData; import com.jetbrains.python.ui.targetPathEditor.ManualPathEntryDialog; @@ -109,14 +107,7 @@ class PyRemotePathEditor extends PythonPathEditor { private String @NotNull [] chooseRemoteFiles() throws ExecutionException, InterruptedException { SdkAdditionalData sdkAdditionalData = mySdk.getSdkAdditionalData(); - if (sdkAdditionalData instanceof PyRemoteSdkAdditionalDataBase) { - PythonRemoteInterpreterManager remoteInterpreterManager = PythonRemoteInterpreterManager.getInstance(); - if (remoteInterpreterManager == null) { - return ArrayUtil.EMPTY_STRING_ARRAY; - } - return remoteInterpreterManager.chooseRemoteFiles(myProject, (PyRemoteSdkAdditionalDataBase)sdkAdditionalData, false); - } - else if (sdkAdditionalData instanceof PyTargetAwareAdditionalData) { + if (sdkAdditionalData instanceof PyTargetAwareAdditionalData) { var dialog = new ManualPathEntryDialog(myProject, ((PyTargetAwareAdditionalData)sdkAdditionalData).getTargetEnvironmentConfiguration()); if (dialog.showAndGet()) { diff --git a/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurables.kt b/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurables.kt index fe99b7dc854e..fc20f8b67674 100644 --- a/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurables.kt +++ b/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurables.kt @@ -8,8 +8,6 @@ import com.intellij.openapi.module.Module import com.intellij.openapi.options.Configurable import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData -import com.jetbrains.python.run.target.ConnectionCredentialsToTargetConfigurationConverter import com.jetbrains.python.sdk.legacy.PythonSdkUtil import com.jetbrains.python.target.PyTargetAwareAdditionalData import com.jetbrains.python.target.PythonLanguageRuntimeConfiguration @@ -32,15 +30,6 @@ internal fun createPythonInterpreterConfigurable(project: Project, else if (sdkAdditionalData is PyTargetAwareAdditionalData) { createPythonInterpreterConfigurable(project, sdk, sdkAdditionalData, parentConfigurable) } - else if (sdkAdditionalData is PyRemoteSdkAdditionalData) { - val convertedSdkAdditionalData = sdkAdditionalData.convertToTargetAwareAdditionalData() - if (convertedSdkAdditionalData != null) { - createPythonInterpreterConfigurable(project, sdk, convertedSdkAdditionalData, parentConfigurable) - } - else { - UnsupportedPythonInterpreterConfigurable(sdk) - } - } else { UnsupportedPythonInterpreterConfigurable(sdk) } @@ -73,14 +62,3 @@ private fun createPythonInterpreterConfigurable(project: Project, } } -private fun PyRemoteSdkAdditionalData.convertToTargetAwareAdditionalData(): PyTargetAwareAdditionalData? { - val connectionCredentials = connectionCredentials() - val targetEnvironmentConfiguration = ConnectionCredentialsToTargetConfigurationConverter.EP_NAME.extensionList.firstNotNullOfOrNull { - it.tryConvert(connectionCredentials) - } - if (targetEnvironmentConfiguration == null) return null - val targetAwareAdditionalData = PyTargetAwareAdditionalData(flavorAndData) - targetAwareAdditionalData.targetEnvironmentConfiguration = targetEnvironmentConfiguration - targetAwareAdditionalData.interpreterPath = this.interpreterPath - return targetAwareAdditionalData -} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/console/PydevConsoleCommunicationClient.kt b/python/src/com/jetbrains/python/console/PydevConsoleCommunicationClient.kt deleted file mode 100644 index 2a58edaec470..000000000000 --- a/python/src/com/jetbrains/python/console/PydevConsoleCommunicationClient.kt +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.jetbrains.python.console - -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.progress.ProcessCanceledException -import com.intellij.openapi.progress.ProgressIndicator -import com.intellij.openapi.progress.ProgressIndicatorProvider -import com.intellij.openapi.project.Project -import com.jetbrains.python.PyBundle -import com.jetbrains.python.console.protocol.PythonConsoleBackendService -import com.jetbrains.python.console.protocol.PythonConsoleFrontendService -import com.jetbrains.python.console.transport.client.TNettyClientTransport -import com.jetbrains.python.console.transport.server.TNettyServer -import com.jetbrains.python.debugger.PyDebugValueExecutionService -import com.jetbrains.python.debugger.PyFrameAccessor -import com.jetbrains.python.debugger.PyFrameListener -import org.apache.thrift.protocol.TBinaryProtocol -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future -import java.util.concurrent.TimeUnit -import java.util.concurrent.locks.Condition -import java.util.concurrent.locks.Lock -import java.util.concurrent.locks.ReentrantLock -import kotlin.concurrent.withLock - -/** - * This is [PydevConsoleCommunication] where Python Console backend acts like a - * server and IDE acts like a client. - * - * Python Console [Process] is expected to be already started. It is passed as - * [_pythonConsoleProcess] property. - */ -class PydevConsoleCommunicationClient(project: Project, - private val host: String, private val port: Int, - private val _pythonConsoleProcess: Process) : PydevConsoleCommunication(project) { - private var server: TNettyServer? = null - - /** - * Thrift RPC client for sending messages to the server. - * - * Guarded by [stateLock]. - */ - private var client: PythonConsoleBackendServiceDisposable? = null - - private val clientTransport: TNettyClientTransport = TNettyClientTransport(host, port) - - private val stateLock: Lock = ReentrantLock() - private val stateChanged: Condition = stateLock.newCondition() - - /** - * Initial non-thread safe [PythonConsoleBackendService.Client]. - * - * Guarded by [stateLock]. - */ - private var initialPythonConsoleClient: PythonConsoleBackendService.Iface? = null - - /** - * Guarded by [stateLock]. - */ - private var isClosed = false - - /** - * Establishes connection to Python Console backend listening at - * [host]:[port]. - */ - fun connect() { - ApplicationManager.getApplication().executeOnPooledThread { - try { - clientTransport.open() - } - catch (e: Exception) { - LOG.warn(e) - - stateLock.withLock { - isClosed = true - - stateChanged.signalAll() - } - return@executeOnPooledThread - } - - val clientProtocol = TBinaryProtocol(clientTransport) - val client = PythonConsoleBackendService.Client(clientProtocol) - - val serverTransport = clientTransport.serverTransport - - val serverHandler = createPythonConsoleFrontendHandler() - val serverProcessor = PythonConsoleFrontendService.Processor(serverHandler) - - val server = TNettyServer(serverTransport, serverProcessor) - - stateLock.withLock { - if (isClosed) throw ProcessCanceledException() - - this.server = server - initialPythonConsoleClient = client - - stateChanged.signalAll() - } - - ApplicationManager.getApplication().executeOnPooledThread { server.serve() } - - val executionService = PyDebugValueExecutionService.getInstance(myProject) - executionService.sessionStarted(this) - addFrameListener(object : PyFrameListener { - override fun frameChanged() { - executionService.cancelSubmittedTasks(this@PydevConsoleCommunicationClient) - } - - override fun sessionStopped(communication: PyFrameAccessor?) { - executionService.cancelSubmittedTasks(this@PydevConsoleCommunicationClient) - } - }) - } - } - - override fun getPythonConsoleBackendClient(): PythonConsoleBackendServiceDisposable { - stateLock.withLock { - while (!isClosed && _pythonConsoleProcess.isAlive) { - // if `client` is set just return it - client?.let { - return it - } - - val initialPythonConsoleClient = initialPythonConsoleClient - - if (initialPythonConsoleClient != null) { - val newClient = synchronizedPythonConsoleClient(PydevConsoleCommunication::class.java.classLoader, - initialPythonConsoleClient, _pythonConsoleProcess) - client = newClient - return newClient - } - else { - stateChanged.await() - } - } - if (!_pythonConsoleProcess.isAlive) { - throw PyConsoleProcessFinishedException(_pythonConsoleProcess.exitValue()) - } - throw CommunicationClosedException() - } - } - - override fun closeCommunication(): Future<*> { - stateLock.withLock { - try { - isClosed = true - } - finally { - stateChanged.signalAll() - } - } - - // `client` cannot be assigned after `isClosed` is set - - val progressIndicator: ProgressIndicator? = ProgressIndicatorProvider.getInstance().progressIndicator - - // if client exists then try to gracefully `close()` it - try { - client?.apply { - progressIndicator?.text2 = PyBundle.message("debugger.sending.close.message") - - close() - dispose() - } - } - catch (e: Exception) { - // ignore exceptions on `client` shutdown - } - - _pythonConsoleProcess.let { - progressIndicator?.text2 = PyBundle.message("debugger.waiting.to.finish") - - // TODO move under the future! - try { - do { - progressIndicator?.checkCanceled() - } - while (!it.waitFor(500, TimeUnit.MILLISECONDS)) - } - catch (e: InterruptedException) { - Thread.currentThread().interrupt() - } - } - - - // explicitly close Netty client - clientTransport.close() - - // we know that in this case `server.stop()` would do almost nothing - return server?.stop() ?: CompletableFuture.completedFuture(null) - } - - override fun isCommunicationClosed(): Boolean = stateLock.withLock { isClosed } - - companion object { - private val LOG: Logger = Logger.getInstance(Logger::class.java) - } -} diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java b/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java index b961d13dcc1f..59a2a169a521 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java @@ -35,7 +35,6 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.NlsContexts; @@ -75,7 +74,6 @@ import com.jetbrains.python.debugger.ValuesPolicy; import com.jetbrains.python.debugger.settings.PyDebuggerSettings; import com.jetbrains.python.parser.icons.PythonParserIcons; import com.jetbrains.python.remote.PyRemotePathMapper; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; import com.jetbrains.python.run.*; import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest; import com.jetbrains.python.sdk.PythonEnvUtil; @@ -383,11 +381,7 @@ public class PydevConsoleRunnerImpl implements PydevConsoleRunner { PythonExecution pythonConsoleScriptExecution = PydevConsoleCli.createPythonConsoleScriptInClientMode(ideServerPort, helpersAwareTargetRequest); - PyRemoteSdkAdditionalDataBase remoteSdkAdditionalData = getRemoteAdditionalData(mySdk); - PyRemotePathMapper pathMapper = remoteSdkAdditionalData != null - ? PydevConsoleRunnerUtil.getPathMapper(myProject, myConsoleSettings, remoteSdkAdditionalData) - : null; - PythonCommandLineState.initEnvironment(myProject, pythonConsoleScriptExecution, runParams, helpersAwareTargetRequest, pathMapper, + PythonCommandLineState.initEnvironment(myProject, pythonConsoleScriptExecution, runParams, helpersAwareTargetRequest, null, mySdk); if (myWorkingDirFunction != null) { @@ -530,22 +524,6 @@ public class PydevConsoleRunnerImpl implements PydevConsoleRunner { PythonScripts.ensureProjectSdkAndModuleDirsAreOnTarget(targetEnvironmentRequest, myProject, modules); } - @Contract("null -> null") - private static @Nullable PyRemoteSdkAdditionalDataBase getRemoteAdditionalData(@Nullable Sdk sdk) { - if (sdk == null) { - return null; - } - else { - SdkAdditionalData sdkAdditionalData = sdk.getSdkAdditionalData(); - if (sdkAdditionalData instanceof PyRemoteSdkAdditionalDataBase) { - return (PyRemoteSdkAdditionalDataBase)sdkAdditionalData; - } - else { - return null; - } - } - } - public static int getRemotePortFromProcess(@NotNull Process process) throws ExecutionException { Scanner s = new Scanner(process.getInputStream()); return readInt(s, process); diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunnerUtil.kt b/python/src/com/jetbrains/python/console/PydevConsoleRunnerUtil.kt index 5304c215aff3..b8f14d375d60 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleRunnerUtil.kt +++ b/python/src/com/jetbrains/python/console/PydevConsoleRunnerUtil.kt @@ -27,7 +27,6 @@ import com.jetbrains.python.console.completion.PydevConsoleElement import com.jetbrains.python.console.pydev.ConsoleCommunication import com.jetbrains.python.parsing.console.PythonConsoleData import com.jetbrains.python.remote.PyRemotePathMapper -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase import com.jetbrains.python.remote.PythonRemoteInterpreterManager import com.jetbrains.python.run.PythonCommandLineState import com.jetbrains.python.run.toStringLiteral @@ -62,7 +61,6 @@ fun getPathMapper(project: Project, if (sdk == null) return null return when (val sdkAdditionalData = sdk.sdkAdditionalData) { is PyTargetAwareAdditionalData -> getPathMapper(project, consoleSettings, sdkAdditionalData) - is PyRemoteSdkAdditionalDataBase -> getPathMapper(project, consoleSettings, sdkAdditionalData) else -> null } } @@ -114,17 +112,6 @@ private fun appendBasicMappings(project: Project, data: RemoteSdkProperties): Py return pathMapper } -fun getPathMapper(project: Project, - consoleSettings: PyConsoleSettings, - remoteSdkAdditionalData: PyRemoteSdkAdditionalDataBase): PyRemotePathMapper { - val remotePathMapper = PythonRemoteInterpreterManager.appendBasicMappings(project, null, remoteSdkAdditionalData) - val mappingSettings = consoleSettings.mappingSettings - if (mappingSettings != null) { - remotePathMapper.addAll(mappingSettings.pathMappings, PyRemotePathMapper.PyPathMappingType.USER_DEFINED) - } - return remotePathMapper -} - fun findPythonSdkAndModule(project: Project, contextModule: Module?): Pair { var sdk: Sdk? = null var module: Module? = null diff --git a/python/src/com/jetbrains/python/console/PythonConsoleRemoteProcessCreator.kt b/python/src/com/jetbrains/python/console/PythonConsoleRemoteProcessCreator.kt index 51ce05b3fb0e..1e54e0324687 100644 --- a/python/src/com/jetbrains/python/console/PythonConsoleRemoteProcessCreator.kt +++ b/python/src/com/jetbrains/python/console/PythonConsoleRemoteProcessCreator.kt @@ -1,36 +1,12 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.jetbrains.python.console -import com.intellij.execution.ExecutionException -import com.intellij.execution.configurations.GeneralCommandLine import com.intellij.openapi.extensions.ExtensionPointName -import com.intellij.openapi.project.Project import com.intellij.remote.CredentialsType -import com.jetbrains.python.remote.PyRemotePathMapper -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase -import com.jetbrains.python.remote.PyRemoteSocketToLocalHostProvider -import java.io.IOException interface PythonConsoleRemoteProcessCreator { val credentialsType: CredentialsType - @Throws(ExecutionException::class) - fun createRemoteConsoleProcess(commandLine: GeneralCommandLine, - pathMapper: PyRemotePathMapper, - project: Project, - data: PyRemoteSdkAdditionalDataBase, - runnerFileFromHelpers: String, - credentials: T): RemoteConsoleProcessData - - /** - * Tries to create a remote tunnel. - * @return Port on the remote server or null if port forwarding by this method is not implemented. - */ - @Throws(IOException::class) - fun createRemoteTunnel(project: Project, - data: PyRemoteSdkAdditionalDataBase, - localPort: Int): Int? = localPort - companion object { @JvmField val EP_NAME: ExtensionPointName> = ExtensionPointName.create( @@ -38,8 +14,3 @@ interface PythonConsoleRemoteProcessCreator { } } -data class RemoteConsoleProcessData(val pydevConsoleCommunication: PydevConsoleCommunication, - val commandLine: String, - val process: Process, - val socketProvider: PyRemoteSocketToLocalHostProvider) - diff --git a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java index e94a1890e4fe..52fca2756199 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java @@ -5,7 +5,6 @@ import com.intellij.codeWithMe.ClientId; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionManager; import com.intellij.execution.ExecutionResult; -import com.intellij.execution.Executor; import com.intellij.execution.configurations.*; import com.intellij.execution.console.LanguageConsoleBuilder; import com.intellij.execution.executors.DefaultDebugExecutor; @@ -297,7 +296,6 @@ public class PyDebugRunner implements ProgramRunner { session = createXDebugSession(environment, pyState, serverSocket, result); } - initSession(session, state, environment.getExecutor()); return session.getRunContentDescriptor(); } @@ -327,7 +325,6 @@ public class PyDebugRunner implements ProgramRunner { if (sessionListener != null) { session.addSessionListener(sessionListener); } - initSession(session, state, environment.getExecutor()); return session.getRunContentDescriptor(); })); } @@ -358,8 +355,6 @@ public class PyDebugRunner implements ProgramRunner { return AppUIExecutor.onUiThread().submit(() -> doExecute(state, environment)); } - protected void initSession(XDebugSession session, RunProfileState state, Executor executor) { - } public static int findIndex(List paramList, String paramName) { for (int i = 0; i < paramList.size(); i++) { diff --git a/python/src/com/jetbrains/python/remote/NewFilesProcessor.java b/python/src/com/jetbrains/python/remote/NewFilesProcessor.java index 93dc78107f2f..95616ca826c7 100644 --- a/python/src/com/jetbrains/python/remote/NewFilesProcessor.java +++ b/python/src/com/jetbrains/python/remote/NewFilesProcessor.java @@ -37,28 +37,13 @@ public final class NewFilesProcessor { public static @NotNull String processNewFiles(final @NotNull Module module, final @NotNull String files) { final Sdk sdk = ModuleExtKt.getSdk(module); assert sdk != null : String.format("Sdk can't be null on module %s", module); - final PyProjectSynchronizer synchronizer = PyProjectSynchronizerProvider.getSynchronizer(sdk); final String[] fileNames = ArrayUtilRt.toStringArray(StringUtil.split(files, ",")); if (fileNames.length == 0) { return ""; } - if (synchronizer != null) { // We are on remote side, lets pull files from python first - synchronizer.syncProject(module, PySyncDirection.REMOTE_TO_LOCAL, success -> { - if (!success) { - return; - } - // Convert names to local and add to vcs - final String[] localFileNames = Arrays.stream(fileNames) - .map(remoteName -> synchronizer.mapFilePath(module.getProject(), PySyncDirection.REMOTE_TO_LOCAL, remoteName)) - .filter(localFileName -> localFileName != null) - .toArray(size -> new String[size]); - addToVcsIfNeeded(module, localFileNames); - }, fileNames); - } - else { // Local, simply add - addToVcsIfNeeded(module, fileNames); - } + // Local, simply add + addToVcsIfNeeded(module, fileNames); return String.format("Following files were affected \n %s", StringUtil.join(fileNames, "\n")); diff --git a/python/src/com/jetbrains/python/remote/PyProjectSynchronizer.kt b/python/src/com/jetbrains/python/remote/PyProjectSynchronizer.kt deleted file mode 100644 index cfe020e99973..000000000000 --- a/python/src/com/jetbrains/python/remote/PyProjectSynchronizer.kt +++ /dev/null @@ -1,142 +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.remote - -import com.intellij.openapi.extensions.ExtensionPointName -import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project -import com.intellij.openapi.projectRoots.Sdk -import com.intellij.remote.CredentialsType -import com.intellij.util.PathMappingSettings -import org.jetbrains.annotations.ApiStatus -import org.jetbrains.annotations.Nls -import java.util.function.Consumer - -typealias PathMappings = List - -/** - * 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. - * - * 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. - * - * Using this engine makes your generator compatible with remote interpreters. - * - * Project synchronizer is also responsible for project configuration for sync: it cooperates with user to make sure remote project is - * configured correctly. - * @author Ilya.Kazakevich - */ -interface PyProjectSynchronizer { - - /** - * Checks if sync is available. - * It supports several strategies: see concrete instance documentation. - * - * @param syncCheckStrategy strategy to check if sync is available. - * Several strategies are supported: see concrete instance documentation. - * @return null if sync is available or error message if something prevents project from sync. - */ - - @Nls fun checkSynchronizationAvailable(syncCheckStrategy: PySyncCheckStrategy): String? - - /** - * if remote box allows user to configure remote path, this method returns default path - * that should be shown to user. - * - * Must return null if [getAutoMappings] are not null. - */ - fun getDefaultRemotePath(): String? - - /** - * If remote box does not allow user to configure path mapping then these mappings could be used to automatically convert - * local path to remote path. If set, can't be empty and can't coexist with [getDefaultRemotePath] - */ - fun getAutoMappings(): com.jetbrains.python.Result? = null - - - /** - * Synchronizes project. - * @param module current module - * @param syncDirection local-to-remote (aka java-to-python) or opposite. See enum value doc. - * @param callback code to be called after sync completion. Argument tells if sync was success or not. - * @param fileNames files to be used as source (local files in case of java-to-python, remote otherwise). - * If no file provided, *all* files are copied. So, use this arg as filter to sync subset of files. - */ - fun syncProject(module: Module, syncDirection: PySyncDirection, - callback: Consumer?, vararg fileNames: String) - - /** - * Maps file name from one side to another. - * @param filePath local file name (in case of java-to-python), remote otherwise - */ - fun mapFilePath(project: Project, direction: PySyncDirection, filePath: String): String? -} - -/** - * Plugin registers [PyProjectSynchronizer] for [CredentialsType] - */ -@ApiStatus.Internal -interface PyProjectSynchronizerProvider { - fun getSynchronizer(credsType: CredentialsType<*>, sdk: Sdk): PyProjectSynchronizer? - - companion object { - val EP_NAME: ExtensionPointName = ExtensionPointName.create("Pythonid.projectSynchronizerProvider") - - fun find(credsType: CredentialsType<*>, sdk: Sdk) = EP_NAME.extensions.mapNotNull { it.getSynchronizer(credsType, sdk) }.firstOrNull() - - /** - * Returns [PyProjectSynchronizer] that is suitable for remote Python - * [sdk]. - * - * Returns [PyUnknownProjectSynchronizer.INSTANCE] if [sdk] is remote but - * no [PyProjectSynchronizer] is registered for this type of Python SDK. - * - * Returns `null` if [sdk] is local or it is not Python SDK. - */ - @JvmStatic - fun getSynchronizer(sdk: Sdk): PyProjectSynchronizer? { - val sdkAdditionalData = sdk.sdkAdditionalData - if (sdkAdditionalData is PyRemoteSdkAdditionalDataBase) { - return find(sdkAdditionalData.remoteConnectionType, sdk) ?: PyUnknownProjectSynchronizer.INSTANCE - } - return null - } - } -} - -/** - * Several strategies to be used for [PyProjectSynchronizer.checkSynchronizationAvailable]. - * See concrete impls. - */ -sealed interface PySyncCheckStrategy - -/** - * Checks if specific folder could be synced with remote interpreter. - * It does not cooperate with user but simply checks folder instead. - * - * Strategy should return "false" only if it is technically impossible to sync with this folder what ever user does. - * If it is possible but requires some aid from user should return true. - * - * No remote project creation would be allowed if this strategy returns "false". - */ -class PySyncCheckOnly() : PySyncCheckStrategy - -/** - * Checks if project with specific module could be synced with remote server. - * It may contact user taking one through some wizard steps to configure project to support remote interpreter. - * So, it does its best to make project synchronizable.* - * - * @param remotePath user provided remote path. Should only be provided if [PyProjectSynchronizer.getDefaultRemotePath] is not null. - * This argument should only be provided first time. On next call always provide null to prevent infinite loop because - * user will be asked for path only if this argument is null. - */ -class PySyncCheckCreateIfPossible(val module: Module, val remotePath: String?) : PySyncCheckStrategy - -/** - * Local-remote sync direction - */ -enum class PySyncDirection { - LOCAL_TO_REMOTE, - REMOTE_TO_LOCAL, -} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/remote/PyRemoteFilesChooser.kt b/python/src/com/jetbrains/python/remote/PyRemoteFilesChooser.kt deleted file mode 100644 index f6193fa81a57..000000000000 --- a/python/src/com/jetbrains/python/remote/PyRemoteFilesChooser.kt +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.jetbrains.python.remote - -import com.intellij.execution.ExecutionException -import com.intellij.openapi.project.Project - -interface PyRemoteFilesChooser { - - @Throws(ExecutionException::class, InterruptedException::class) - fun chooseRemoteFiles(project: Project, data: PyRemoteSdkAdditionalDataBase, foldersOnly: Boolean): Array -} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/remote/PyRemoteInterpreterUtil.java b/python/src/com/jetbrains/python/remote/PyRemoteInterpreterUtil.java index 9f6bfe441aa1..fbeed55d1276 100644 --- a/python/src/com/jetbrains/python/remote/PyRemoteInterpreterUtil.java +++ b/python/src/com/jetbrains/python/remote/PyRemoteInterpreterUtil.java @@ -6,84 +6,17 @@ import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.process.ProcessListener; import com.intellij.execution.process.ProcessOutput; -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.util.Key; -import com.intellij.openapi.util.Ref; import com.intellij.remote.RemoteSdkException; -import com.intellij.util.ui.UIUtil; import com.jetbrains.python.PyBundle; import com.jetbrains.python.packaging.PyExecutionException; -import com.jetbrains.python.run.PyRemoteProcessStarterManagerUtil; -import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.io.Closeable; import java.io.IOException; import java.io.UncheckedIOException; -import static com.jetbrains.python.PythonBinaryKt.PYTHON_VERSION_ARG; - public final class PyRemoteInterpreterUtil { - /** - * @param nullForUnparsableVersion if version returns by python can't be parsed -- return null instead of exception - * @return version or null if sdk does not have flavor / version can't be parsed etc - */ - public static @Nullable String getInterpreterVersion(final @Nullable Project project, - final @NotNull PyRemoteSdkAdditionalDataBase data, - final boolean nullForUnparsableVersion) - throws RemoteSdkException { - final Ref result = Ref.create(null); - final Ref exception = Ref.create(null); - - final Task.Modal task = new Task.Modal(project, PyBundle.message("python.sdk.getting.remote.interpreter.version"), true) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - final PythonSdkFlavor flavor = data.getFlavor(); - if (flavor != null) { - ProcessOutput processOutput; - try { - try { - String[] command = {data.getInterpreterPath(), PYTHON_VERSION_ARG}; - processOutput = PyRemoteProcessStarterManagerUtil.getManager(data).executeRemoteProcess(myProject, command, null, - data, new PyRemotePathMapper()); - if (processOutput.getExitCode() == 0) { - final String version = PythonSdkFlavor.getVersionStringFromOutput(processOutput); - if (version != null || nullForUnparsableVersion) { - result.set(version); - return; - } - } - exception.set(createException(processOutput, command)); - } - catch (Exception e) { - throw RemoteSdkException.cantObtainRemoteCredentials(e); - } - } - catch (RemoteSdkException e) { - exception.set(e); - } - } - } - }; - - if (!ProgressManager.getInstance().hasProgressIndicator()) { - - UIUtil.invokeAndWaitIfNeeded(() -> ProgressManager.getInstance().run(task)); - } - else { - task.run(ProgressManager.getInstance().getProgressIndicator()); - } - - if (!exception.isNull()) { - throw exception.get(); - } - - return result.get(); - } private static @NotNull RemoteSdkException createException(final @NotNull ProcessOutput processOutput, String @NotNull [] command) { return RemoteSdkException.cantObtainRemoteCredentials( diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java deleted file mode 100644 index 7dbe46d53d74..000000000000 --- a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java +++ /dev/null @@ -1,264 +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.remote; - -import com.intellij.execution.ExecutionException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.remote.*; -import com.intellij.remote.ext.CredentialsCase; -import com.intellij.remote.ext.CredentialsManager; -import com.intellij.util.PathMappingSettings; -import com.jetbrains.python.sdk.PythonSdkAdditionalData; -import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; -import com.jetbrains.python.sdk.flavors.UnixPythonSdkFlavor; -import com.jetbrains.python.sdk.flavors.WinPythonSdkFlavor; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public class PyRemoteSdkAdditionalData extends PythonSdkAdditionalData implements PyRemoteSdkAdditionalDataBase { - public static final String PYCHARM_HELPERS = ".pycharm_helpers"; - - private static final String SKELETONS_PATH = "SKELETONS_PATH"; - private static final String VERSION = "VERSION"; - private static final String RUN_AS_ROOT_VIA_SUDO = "RUN_AS_ROOT_VIA_SUDO"; - - private final RemoteConnectionCredentialsWrapper myWrapper = new RemoteConnectionCredentialsWrapper(); - private final RemoteSdkPropertiesHolder myRemoteSdkProperties = new RemoteSdkPropertiesHolder(PYCHARM_HELPERS); - private String mySkeletonsPath; - private String myVersionString; - - public PyRemoteSdkAdditionalData(String interpreterPath) { - this(interpreterPath, false); - } - - public PyRemoteSdkAdditionalData(String interpreterPath, boolean runAsRootViaSudo) { - super(computeFlavor(interpreterPath)); - setInterpreterPath(interpreterPath); - setRunAsRootViaSudo(runAsRootViaSudo); - } - - @Override - public @NotNull RemoteConnectionCredentialsWrapper connectionCredentials() { - return myWrapper; - } - - private static @Nullable PythonSdkFlavor computeFlavor(@Nullable String sdkPath) { - if (sdkPath != null) { - // FIXME: converge with sdk flavor & use os.isWindows - for (var flavor : getApplicableFlavors(sdkPath.contains("\\"))) { - if (flavor.isValidSdkPath(sdkPath)) { - return flavor; - } - } - } - return null; - } - - private static List> getApplicableFlavors(boolean isWindows) { - var result = new ArrayList>(); - if (isWindows) { - result.add(WinPythonSdkFlavor.getInstance()); - } - else { - result.add(UnixPythonSdkFlavor.getInstance()); - } - result.addAll(PythonSdkFlavor.getPlatformIndependentFlavors()); - return result; - } - - public String getSkeletonsPath() { - return mySkeletonsPath; - } - - public void setSkeletonsPath(String path) { - mySkeletonsPath = path; - } - - @Override - public void setCredentials(Key key, C credentials) { - myWrapper.setCredentials(key, credentials); - } - - @Override - public CredentialsType getRemoteConnectionType() { - return myWrapper.getRemoteConnectionType(); - } - - @Override - public void switchOnConnectionType(CredentialsCase... cases) { - myWrapper.switchType(cases); - } - - @Override - public String getInterpreterPath() { - return myRemoteSdkProperties.getInterpreterPath(); - } - - @Override - public void setInterpreterPath(String interpreterPath) { - myRemoteSdkProperties.setInterpreterPath(interpreterPath); - } - - @Override - public boolean isRunAsRootViaSudo() { - return myRemoteSdkProperties.isRunAsRootViaSudo(); - } - - @Override - public void setRunAsRootViaSudo(boolean runAsRootViaSudo) { - myRemoteSdkProperties.setRunAsRootViaSudo(runAsRootViaSudo); - } - - @Override - public String getHelpersPath() { - return myRemoteSdkProperties.getHelpersPath(); - } - - @Override - public void setHelpersPath(String helpersPath) { - myRemoteSdkProperties.setHelpersPath(helpersPath); - } - - @Override - public String getDefaultHelpersName() { - return myRemoteSdkProperties.getDefaultHelpersName(); - } - - @Override - public @NotNull PathMappingSettings getPathMappings() { - return myRemoteSdkProperties.getPathMappings(); - } - - @Override - public void setPathMappings(@Nullable PathMappingSettings pathMappings) { - myRemoteSdkProperties.setPathMappings(pathMappings); - } - - @Override - public boolean isHelpersVersionChecked() { - return myRemoteSdkProperties.isHelpersVersionChecked(); - } - - @Override - public void setHelpersVersionChecked(boolean helpersVersionChecked) { - myRemoteSdkProperties.setHelpersVersionChecked(helpersVersionChecked); - } - - @Override - public void setSdkId(String sdkId) { - throw new IllegalStateException("sdkId in this class is constructed based on fields, so it can't be set"); - } - - @Override - public String getSdkId() { - return constructSdkID(myWrapper, myRemoteSdkProperties); - } - - public String getPresentableDetails() { - return myWrapper.getPresentableDetails(myRemoteSdkProperties.getInterpreterPath()); - } - - private static String constructSdkID(RemoteConnectionCredentialsWrapper wrapper, RemoteSdkPropertiesHolder properties) { - return wrapper.getId() + properties.getInterpreterPath(); - } - - @Override - public boolean isValid() { - return myRemoteSdkProperties.isValid(); - } - - @Override - public void setValid(boolean valid) { - myRemoteSdkProperties.setValid(valid); - } - - @Override - public RemoteCredentials getRemoteCredentials(@Nullable Project project, boolean allowSynchronousInteraction) throws InterruptedException, ExecutionException { - var manager = PythonSshInterpreterManager.Factory.getInstance(); - if (manager == null) throw new IllegalStateException("No plugin"); - return manager.getRemoteCredentials(myWrapper, project, allowSynchronousInteraction); - } - - @Override - public void produceRemoteCredentials(@Nullable Project project, boolean allowSynchronousInteraction, @NotNull Consumer consumer) { - var manager = PythonSshInterpreterManager.Factory.getInstance(); - if (manager == null) throw new IllegalStateException("No plugin"); - manager.produceRemoteCredentials(myWrapper, project, allowSynchronousInteraction, consumer); - } - - public boolean connectionEquals(PyRemoteSdkAdditionalData data) { - return myWrapper.equals(data.myWrapper); - } - - @Override - public Object getRemoteSdkDataKey() { - return myWrapper.getConnectionKey(); - } - - @Override - public @NotNull PyRemoteSdkAdditionalData copy() { - var copy = new PyRemoteSdkAdditionalData(myRemoteSdkProperties.getInterpreterPath(), isRunAsRootViaSudo()); - copyTo(copy); - return copy; - } - - public void copyTo(@NotNull PyRemoteSdkAdditionalData copy) { - copy.setSkeletonsPath(mySkeletonsPath); - copy.setVersionString(myVersionString); - myRemoteSdkProperties.copyTo(copy.myRemoteSdkProperties); - myWrapper.copyTo(copy.myWrapper); - } - - @Override - public void save(final @NotNull Element rootElement) { - super.save(rootElement); - myRemoteSdkProperties.save(rootElement); - rootElement.setAttribute(SKELETONS_PATH, StringUtil.notNullize(getSkeletonsPath())); - rootElement.setAttribute(VERSION, StringUtil.notNullize(getVersionString())); - rootElement.setAttribute(RUN_AS_ROOT_VIA_SUDO, Boolean.toString(isRunAsRootViaSudo())); - // this should be executed at the end because of the case with UnknownCredentialsHolder - myWrapper.save(rootElement); - } - - public static @NotNull PyRemoteSdkAdditionalData loadRemote(@NotNull Sdk sdk, @Nullable Element element) { - var path = sdk.getHomePath(); - assert path != null; - var data = new PyRemoteSdkAdditionalData(RemoteSdkProperties.getInterpreterPathFromFullPath(path), false); - data.load(element); - - if (element != null) { - CredentialsManager.getInstance().loadCredentials(path, element, data); - if (data.myWrapper.getRemoteConnectionType().hasPrefix(RemoteCredentialsHolder.SSH_PREFIX)) { - CredentialsManager.updateOutdatedSdk(data, null); - } - data.myRemoteSdkProperties.load(element); - - data.setSkeletonsPath(StringUtil.nullize(element.getAttributeValue(SKELETONS_PATH))); - var helpersPath = StringUtil.nullize(element.getAttributeValue("PYCHARM_HELPERS_PATH")); - if (helpersPath != null) { - data.setHelpersPath(helpersPath); - } - data.setVersionString(StringUtil.nullize(element.getAttributeValue(VERSION))); - data.setRunAsRootViaSudo(StringUtil.equals(element.getAttributeValue(RUN_AS_ROOT_VIA_SUDO), "true")); - } - - return data; - } - - @Override - public void setVersionString(String versionString) { - myVersionString = versionString; - } - - @Override - public String getVersionString() { - return myVersionString; - } -} diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java deleted file mode 100644 index 34959142cb64..000000000000 --- a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java +++ /dev/null @@ -1,17 +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.remote; - -import com.intellij.remote.RemoteSdkAdditionalData; -import com.jetbrains.python.sdk.PyRemoteSdkAdditionalDataMarker; -import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; -import org.jetbrains.annotations.Nullable; - -public interface PyRemoteSdkAdditionalDataBase - extends RemoteSdkAdditionalData, PyRemoteSdkSkeletonsPathAware, PyRemoteSdkAdditionalDataMarker -{ - String getVersionString(); - - void setVersionString(String versionString); - - @Nullable PythonSdkFlavor getFlavor(); -} diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkWithoutSudo.kt b/python/src/com/jetbrains/python/remote/PyRemoteSdkWithoutSudo.kt index 1b3e33e18258..c36ca30cff4b 100644 --- a/python/src/com/jetbrains/python/remote/PyRemoteSdkWithoutSudo.kt +++ b/python/src/com/jetbrains/python/remote/PyRemoteSdkWithoutSudo.kt @@ -3,7 +3,6 @@ package com.jetbrains.python.remote import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.SdkAdditionalData -import java.lang.IllegalStateException /** * This is an ugly but necessary workaround. @@ -15,15 +14,6 @@ import java.lang.IllegalStateException * and SFTP always tries to do changes with user privileges. */ class PyRemoteSdkWithoutSudo(private val forward: Sdk) : Sdk by forward { - override fun getSdkAdditionalData(): SdkAdditionalData? = forward.sdkAdditionalData?.let { - if (it is PyRemoteSdkAdditionalDataBase) PyRemoteSdkAdditionalDataWithoutSudo(it) else it - } + override fun getSdkAdditionalData(): SdkAdditionalData? = forward.sdkAdditionalData } -class PyRemoteSdkAdditionalDataWithoutSudo(forward: PyRemoteSdkAdditionalDataBase) : PyRemoteSdkAdditionalDataBase by forward { - override fun isRunAsRootViaSudo(): Boolean = false - - override fun setRunAsRootViaSudo(runAsRootViaSudo: Boolean) { - throw IllegalStateException("Tried to set runAsRootViaSudo in ${javaClass}") - } -} diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSocketToLocalHostProvider.java b/python/src/com/jetbrains/python/remote/PyRemoteSocketToLocalHostProvider.java index 3afce81fb5ca..4eb5164a8d40 100644 --- a/python/src/com/jetbrains/python/remote/PyRemoteSocketToLocalHostProvider.java +++ b/python/src/com/jetbrains/python/remote/PyRemoteSocketToLocalHostProvider.java @@ -9,7 +9,6 @@ import java.io.Closeable; /** * A new instance should be created for every new process. Should be closed when process terminates. * - * See also {@link PyRemoteInterpreterUtil#closeOnProcessTermination(com.intellij.execution.process.ProcessHandler, Closeable)}. */ public interface PyRemoteSocketToLocalHostProvider extends Closeable { /** diff --git a/python/src/com/jetbrains/python/remote/PyUnknownProjectSynchronizer.java b/python/src/com/jetbrains/python/remote/PyUnknownProjectSynchronizer.java deleted file mode 100644 index 508ffb469e4b..000000000000 --- a/python/src/com/jetbrains/python/remote/PyUnknownProjectSynchronizer.java +++ /dev/null @@ -1,57 +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.remote; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.NlsContexts.DialogMessage; -import com.intellij.util.PathMappingSettings; -import com.jetbrains.python.PyBundle; -import com.jetbrains.python.Result; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.function.Consumer; - -/** - * Sync project for SDKs that does not allow sync. Always denies to sync anything. - * Singleton, so use instance - */ -@ApiStatus.Internal -public final class PyUnknownProjectSynchronizer implements PyProjectSynchronizer { - public static final PyProjectSynchronizer INSTANCE = new PyUnknownProjectSynchronizer(); - - private PyUnknownProjectSynchronizer() { - } - - @Override - public @DialogMessage @NotNull String checkSynchronizationAvailable(final @NotNull PySyncCheckStrategy syncCheckStrategy) { - return PyBundle.message("python.unknown.project.synchronizer.this.interpreter.type.does.not.support.remote.project.creation"); - } - - @Override - public @Nullable String mapFilePath(final @NotNull Project project, final @NotNull PySyncDirection direction, final @NotNull String filePath) { - return null; - } - - @Override - public @Nullable String getDefaultRemotePath() { - return null; - } - - @Override - public @Nullable Result, String> getAutoMappings() { - return null; - } - - @Override - public void syncProject(final @NotNull Module module, - final @NotNull PySyncDirection syncDirection, - final @Nullable Consumer callback, - final String @NotNull ... fileNames) { - if (callback != null) { - callback.accept(false); - } - } -} diff --git a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java index 4e26a868eef3..3984ade0ad7a 100644 --- a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java +++ b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java @@ -1,13 +1,10 @@ // 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.execution.ExecutionException; import com.intellij.execution.configurations.ParamsGroup; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.python.community.helpersLocator.PythonHelpersLocator; @@ -21,7 +18,6 @@ import com.jetbrains.python.PyBundle; import com.jetbrains.python.extensions.ProgressManagerExtKt; import com.jetbrains.python.remote.PyRemotePathMapper.PyPathMappingType; import kotlin.jvm.functions.Function0; -import org.jdom.Element; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -94,11 +90,6 @@ public abstract class PythonRemoteInterpreterManager { return newPathMapper; } - public abstract @NotNull SdkAdditionalData loadRemoteSdkData(@NotNull Sdk sdk, @Nullable Element additional); - - public abstract String @NotNull [] chooseRemoteFiles(@NotNull Project project, @NotNull PyRemoteSdkAdditionalDataBase data, boolean foldersOnly) - throws ExecutionException, InterruptedException; - public static class PyHelpersNotReadyException extends RuntimeException { public PyHelpersNotReadyException(Throwable cause) { super("Python helpers are not copied yet to the remote host. Please wait until remote interpreter initialization finishes.", cause); diff --git a/python/src/com/jetbrains/python/remote/PythonSshInterpreterManager.java b/python/src/com/jetbrains/python/remote/PythonSshInterpreterManager.java index da61a54ceea5..60b67896c831 100644 --- a/python/src/com/jetbrains/python/remote/PythonSshInterpreterManager.java +++ b/python/src/com/jetbrains/python/remote/PythonSshInterpreterManager.java @@ -5,8 +5,6 @@ import com.intellij.execution.ExecutionException; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.util.Pair; import com.intellij.remote.RemoteConnectionCredentialsWrapper; import com.intellij.remote.RemoteCredentials; import com.intellij.remote.RemoteSdkProperties; @@ -14,11 +12,9 @@ import com.intellij.util.PathMappingSettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.text.MessageFormat; import java.util.List; import java.util.function.Consumer; -import java.util.function.Supplier; /** * This service provides functionality for SSH remote interpreters. It is @@ -37,15 +33,6 @@ public interface PythonSshInterpreterManager { @NotNull List mapping ); - /** - * Creates form to browse remote box. You need to show it to user using a dialog. - * - * @return a pair of (user-chosen path supplier, panel to be displayed), or {@code null} if remote SDK can't be browsed. - * @throws ExecutionException credentials can't be obtained due to remote server error - * @throws InterruptedException credentials can't be obtained due to remote server error - */ - @Nullable Pair, JPanel> createServerBrowserForm(@NotNull Sdk remoteSdk) throws ExecutionException, InterruptedException; - @NotNull RemoteCredentials getRemoteCredentials( @NotNull RemoteConnectionCredentialsWrapper wrapper, @Nullable Project project, diff --git a/python/src/com/jetbrains/python/run/PyRemoteAnalyzeStacktraceFilter.java b/python/src/com/jetbrains/python/run/PyRemoteAnalyzeStacktraceFilter.java deleted file mode 100644 index f0df10bda473..000000000000 --- a/python/src/com/jetbrains/python/run/PyRemoteAnalyzeStacktraceFilter.java +++ /dev/null @@ -1,49 +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.run; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.remote.PathMappingProvider; -import com.intellij.util.PathMappingSettings; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; -import com.jetbrains.python.sdk.legacy.PythonSdkUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public final class PyRemoteAnalyzeStacktraceFilter extends PythonTracebackFilter { - public PyRemoteAnalyzeStacktraceFilter(Project project) { - super(project); - } - - @Override - protected @Nullable VirtualFile findFileByName(@NotNull String fileName) { - VirtualFile vFile = super.findFileByName(fileName); - if (vFile != null) { - return vFile; - } - for (Module m: ModuleManager.getInstance(getProject()).getModules()) { - Sdk s = PythonSdkUtil.findPythonSdk(m); - if (PythonSdkUtil.isRemote(s)) { - PyRemoteSdkAdditionalDataBase data = (PyRemoteSdkAdditionalDataBase) s.getSdkAdditionalData(); - - if (data != null) { - for (PathMappingProvider provider: PathMappingProvider.getSuitableMappingProviders(data)) { - PathMappingSettings mappingSettings = provider.getPathMappingSettings(getProject(), data); - String localFile = mappingSettings.convertToLocal(fileName); - VirtualFile file = LocalFileSystem.getInstance().findFileByPath(localFile); - if (file != null && file.exists()) { - return file; - } - } - - } - } - } - - return null; - } -} diff --git a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java index fa3d2e2b4300..d8248bdd8433 100644 --- a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java +++ b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java @@ -2,21 +2,7 @@ package com.jetbrains.python.run; import com.google.common.net.HostAndPort; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessTerminatedListener; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; -import com.jetbrains.python.PyBundle; -import com.jetbrains.python.remote.PyRemotePathMapper; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData; -import com.jetbrains.python.remote.PythonRemoteInterpreterManager; -import com.jetbrains.python.remote.UnsupportedPythonSdkTypeException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @deprecated use targets API instead @@ -38,57 +24,4 @@ public final class PyRemoteProcessStarter { private PyRemoteProcessStarter() { } - public static @NotNull ProcessHandler startLegacyRemoteProcess(@NotNull PyRemoteSdkAdditionalData legacyAdditionalData, - @NotNull GeneralCommandLine commandLine, - @Nullable Project project, - @Nullable PyRemotePathMapper pathMapper) - throws ExecutionException { - ProcessHandler processHandler; - - try { - processHandler = doStartLegacyRemoteProcess(legacyAdditionalData, commandLine, project, pathMapper); - } - catch (UnsupportedPythonSdkTypeException e) { - throw new ExecutionException(PyBundle.message("remote.interpreter.support.is.not.available", legacyAdditionalData.getClass()), e); - } - catch (ExecutionException e) { - final Application application = ApplicationManager.getApplication(); - if (application != null && (application.isUnitTestMode() || application.isHeadlessEnvironment())) { - throw new RuntimeException(e); - } - throw new ExecutionException(PyBundle.message("python.remote.process.starter.can.t.run.remote.interpreter", e.getMessage()), e); - } - ProcessTerminatedListener.attach(processHandler); - return processHandler; - } - - /** - * Starts a process using corresponding support (e.g. SSH, Vagrant, Docker, - * etc.) for the provided {@code sdk}. - * - * @param legacyAdditionalData //TODO: DOC - * @param commandLine the command line to start the Python interpreter - * @param project the optional project for additional path mappings - * @param pathMapper the mapping between paths on the host machine and the one - * the process will be executed on - * @return process handler for created process - * @throws UnsupportedPythonSdkTypeException if support cannot be found for - * the type of the provided sdk - */ - private static @NotNull ProcessHandler doStartLegacyRemoteProcess(@NotNull PyRemoteSdkAdditionalData legacyAdditionalData, - final @NotNull GeneralCommandLine commandLine, - final @Nullable Project project, - @Nullable PyRemotePathMapper pathMapper) - throws ExecutionException { - final PyRemotePathMapper extendedPathMapper = - PythonRemoteInterpreterManager.appendBasicMappings(project, pathMapper, legacyAdditionalData); - - try { - return PyRemoteProcessStarterManagerUtil.getManager(legacyAdditionalData) - .startRemoteProcess(project, commandLine, legacyAdditionalData, extendedPathMapper); - } - catch (InterruptedException e) { - throw new ExecutionException(e); - } - } } diff --git a/python/src/com/jetbrains/python/run/PyRemoteProcessStarterManager.java b/python/src/com/jetbrains/python/run/PyRemoteProcessStarterManager.java deleted file mode 100644 index 16a4a7a1685d..000000000000 --- a/python/src/com/jetbrains/python/run/PyRemoteProcessStarterManager.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2000-2015 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.run; - -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessOutput; -import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.project.Project; -import com.jetbrains.python.remote.PyRemotePathMapper; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * For anything but plain code execution consider introducing a separate - * extension point with implementations for different - * {@link com.intellij.remote.CredentialsType} using - * {@link PyRemoteSdkAdditionalDataBase#switchOnConnectionType(com.intellij.remote.ext.CredentialsCase[])}. - * - * @see PyRemoteProcessStarterManagerUtil - */ -public interface PyRemoteProcessStarterManager { - ExtensionPointName EP_NAME = ExtensionPointName.create("Pythonid.remoteProcessStarterManager"); - - boolean supports(@NotNull PyRemoteSdkAdditionalDataBase sdkAdditionalData); - - @NotNull - ProcessHandler startRemoteProcess(@Nullable Project project, - @NotNull GeneralCommandLine commandLine, - @NotNull PyRemoteSdkAdditionalDataBase sdkAdditionalData, - @NotNull PyRemotePathMapper pathMapper) throws ExecutionException, InterruptedException; - - @NotNull - ProcessOutput executeRemoteProcess(@Nullable Project project, - String @NotNull [] command, - @Nullable String workingDir, - @NotNull PyRemoteSdkAdditionalDataBase sdkAdditionalData, - @NotNull PyRemotePathMapper pathMapper) throws ExecutionException, InterruptedException; -} diff --git a/python/src/com/jetbrains/python/run/PyRemoteProcessStarterManagerUtil.java b/python/src/com/jetbrains/python/run/PyRemoteProcessStarterManagerUtil.java deleted file mode 100644 index a9d5bd306be2..000000000000 --- a/python/src/com/jetbrains/python/run/PyRemoteProcessStarterManagerUtil.java +++ /dev/null @@ -1,33 +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.run; - -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; -import com.jetbrains.python.remote.UnsupportedPythonSdkTypeException; -import org.jetbrains.annotations.NotNull; - -/** - * @author Alexander Koshevoy - */ -public final class PyRemoteProcessStarterManagerUtil { - private PyRemoteProcessStarterManagerUtil() { - } - - /** - * Returns an instance of {@link PyRemoteProcessStarterManager} that - * corresponds to the provided additional SDK data. - * - * @param pyRemoteSdkAdditionalDataBase additional SDK data - * @return an instance of {@link PyRemoteProcessStarterManager} - * @throws UnsupportedPythonSdkTypeException if support cannot be found for - * the type of the provided - * additional SDK data - */ - public static @NotNull PyRemoteProcessStarterManager getManager(@NotNull PyRemoteSdkAdditionalDataBase pyRemoteSdkAdditionalDataBase) { - for (PyRemoteProcessStarterManager processManager : PyRemoteProcessStarterManager.EP_NAME.getExtensions()) { - if (processManager.supports(pyRemoteSdkAdditionalDataBase)) { - return processManager; - } - } - throw new UnsupportedPythonSdkTypeException(); - } -} diff --git a/python/src/com/jetbrains/python/run/PythonCommandLineState.java b/python/src/com/jetbrains/python/run/PythonCommandLineState.java index d61335199f4d..4502866792f6 100644 --- a/python/src/com/jetbrains/python/run/PythonCommandLineState.java +++ b/python/src/com/jetbrains/python/run/PythonCommandLineState.java @@ -68,7 +68,6 @@ import com.jetbrains.python.facet.PythonPathContributingFacet; import com.jetbrains.python.library.PythonLibraryType; import com.jetbrains.python.packaging.PyExecutionException; import com.jetbrains.python.remote.PyRemotePathMapper; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData; import com.jetbrains.python.run.features.PyRunToolIds; import com.jetbrains.python.run.features.PyRunToolParameters; import com.jetbrains.python.run.features.PyRunToolProvider; @@ -76,7 +75,10 @@ import com.jetbrains.python.run.features.PyRunToolUsageCollector; import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest; import com.jetbrains.python.run.target.PySdkTargetPaths; import com.jetbrains.python.run.target.PythonCommandLineTargetEnvironmentProvider; -import com.jetbrains.python.sdk.*; +import com.jetbrains.python.sdk.PySdkExtKt; +import com.jetbrains.python.sdk.PySdkUtil; +import com.jetbrains.python.sdk.PythonEnvUtil; +import com.jetbrains.python.sdk.PythonSdkAdditionalData; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; import com.jetbrains.python.sdk.flavors.conda.CondaPythonExecKt; import com.jetbrains.python.sdk.legacy.PythonSdkUtil; @@ -273,7 +275,8 @@ public abstract class PythonCommandLineState extends CommandLineState { // TODO workaround if (PythonSdkUtil.isRemote(myConfig.getSdk()) && processHandler instanceof ProcessControlWithMappings) { consoleView - .addMessageFilter(new PyRemoteTracebackFilter(project, getExpandedWorkingDir(myConfig), (ProcessControlWithMappings)processHandler)); + .addMessageFilter( + new PyRemoteTracebackFilter(project, getExpandedWorkingDir(myConfig), (ProcessControlWithMappings)processHandler)); } else { consoleView.addMessageFilter(new PythonTracebackFilter(project, myConfig.getWorkingDirectorySafe())); @@ -303,7 +306,8 @@ public abstract class PythonCommandLineState extends CommandLineState { * @param patchers any number of patchers; any patcher may be null, and the whole argument may be null. * @return handler of the started process */ - protected @NotNull ProcessHandler startProcess(PythonProcessStarter processStarter, CommandLinePatcher... patchers) throws ExecutionException { + protected @NotNull ProcessHandler startProcess(PythonProcessStarter processStarter, CommandLinePatcher... patchers) + throws ExecutionException { GeneralCommandLine commandLine = generateCommandLine(patchers); // Extend command line @@ -393,7 +397,8 @@ public abstract class PythonCommandLineState extends CommandLineState { return processHandler; } - private @NotNull PythonExecution buildPythonExecutionFinal(HelpersAwareTargetEnvironmentRequest helpersAwareTargetRequest, @Nullable Sdk sdk) { + private @NotNull PythonExecution buildPythonExecutionFinal(HelpersAwareTargetEnvironmentRequest helpersAwareTargetRequest, + @Nullable Sdk sdk) { TargetEnvironmentRequest targetEnvironmentRequest = helpersAwareTargetRequest.getTargetEnvironmentRequest(); PythonExecution pythonExecution = buildPythonExecution(helpersAwareTargetRequest); pythonExecution.setWorkingDir(getPythonExecutionWorkingDir(targetEnvironmentRequest)); @@ -401,7 +406,9 @@ public abstract class PythonCommandLineState extends CommandLineState { customizePythonExecutionEnvironmentVars(helpersAwareTargetRequest, pythonExecution.getEnvs(), myConfig.isPassParentEnvs()); PythonScripts.ensureProjectSdkAndModuleDirsAreOnTarget(targetEnvironmentRequest, myConfig.getProject(), - myConfig.getModule() != null ? new Module[]{myConfig.getModule()} : Module.EMPTY_ARRAY); + myConfig.getModule() != null + ? new Module[]{myConfig.getModule()} + : Module.EMPTY_ARRAY); return pythonExecution; } @@ -432,17 +439,8 @@ public abstract class PythonCommandLineState extends CommandLineState { assert sdk != null : "No SDK For " + myConfig.getInterpreterPath(); final ProcessHandler processHandler; var additionalData = sdk.getSdkAdditionalData(); - if (additionalData instanceof PyRemoteSdkAdditionalDataMarker) { - assert additionalData instanceof PyRemoteSdkAdditionalData : "additionalData is remote, but not legacy. Is it a target-based? " + - additionalData; - PyRemotePathMapper pathMapper = createRemotePathMapper(); - processHandler = PyRemoteProcessStarter.startLegacyRemoteProcess((PyRemoteSdkAdditionalData)additionalData, commandLine, - myConfig.getProject(), pathMapper); - } - else { - processHandler = doCreateProcess(commandLine); - ProcessTerminatedListener.attach(processHandler); - } + processHandler = doCreateProcess(commandLine); + ProcessTerminatedListener.attach(processHandler); return processHandler; }; } @@ -491,7 +489,8 @@ public abstract class PythonCommandLineState extends CommandLineState { * @param patchers array of patchers * @return command line changed by patchers */ - private static @NotNull GeneralCommandLine applyPatchers(@NotNull GeneralCommandLine commandLine, CommandLinePatcher @Nullable [] patchers) { + private static @NotNull GeneralCommandLine applyPatchers(@NotNull GeneralCommandLine commandLine, + CommandLinePatcher @Nullable [] patchers) { if (patchers != null) { for (CommandLinePatcher patcher : patchers) { if (patcher != null) patcher.patchCommandLine(commandLine); @@ -637,10 +636,10 @@ public abstract class PythonCommandLineState extends CommandLineState { * {@link GeneralCommandLine}. */ public static @NotNull GeneralCommandLine createPythonCommandLine(Project project, - @Nullable SdkAdditionalData data, - PythonRunParams config, - boolean isDebug, - boolean runWithPty) { + @Nullable SdkAdditionalData data, + PythonRunParams config, + boolean isDebug, + boolean runWithPty) { GeneralCommandLine commandLine = generalCommandLine(runWithPty); commandLine.withCharset(EncodingProjectManager.getInstance(project).getDefaultCharset()); @@ -863,7 +862,8 @@ public abstract class PythonCommandLineState extends CommandLineState { if (sdk != null) { List pathList = new ArrayList<>(); pathList.addAll(getAddedPaths(sdk)); - pathList.addAll(collectPythonPath(module, sdkHome, configuration.shouldAddContentRoots(), configuration.shouldAddSourceRoots(), isDebug)); + pathList.addAll( + collectPythonPath(module, sdkHome, configuration.shouldAddContentRoots(), configuration.shouldAddSourceRoots(), isDebug)); PythonEnvUtil.initPythonPath(configuration.getEnvs(), passParentEnvs, pathList); } } @@ -1104,12 +1104,12 @@ public abstract class PythonCommandLineState extends CommandLineState { } public static @NotNull HelpersAwareTargetEnvironmentRequest getPythonTargetInterpreter(@NotNull Project project, @NotNull Sdk sdk) { - HelpersAwareTargetEnvironmentRequest helpersAwareTargetRequest = - PythonInterpreterTargetEnvironmentFactory.findPythonTargetInterpreter(sdk, project); - if (helpersAwareTargetRequest == null) { - throw new IllegalStateException("Cannot find execution environment for SDK " + sdk); - } - return helpersAwareTargetRequest; + HelpersAwareTargetEnvironmentRequest helpersAwareTargetRequest = + PythonInterpreterTargetEnvironmentFactory.findPythonTargetInterpreter(sdk, project); + if (helpersAwareTargetRequest == null) { + throw new IllegalStateException("Cannot find execution environment for SDK " + sdk); + } + return helpersAwareTargetRequest; } /** @@ -1150,6 +1150,7 @@ public abstract class PythonCommandLineState extends CommandLineState { * Decides whether the configuration should run. * This check happens at the moment that the run configuration is set to run (e.g., when the * user presses the green arrow button to run the configuration). + * * @return Returns `true` if the configuration should be allowed to run, `false` otherwise. */ @RequiresEdt diff --git a/python/src/com/jetbrains/python/run/PythonInterpreterTargetEnvironmentFactory.kt b/python/src/com/jetbrains/python/run/PythonInterpreterTargetEnvironmentFactory.kt index 0200a6998c22..7e5a96a99f0b 100644 --- a/python/src/com/jetbrains/python/run/PythonInterpreterTargetEnvironmentFactory.kt +++ b/python/src/com/jetbrains/python/run/PythonInterpreterTargetEnvironmentFactory.kt @@ -13,7 +13,6 @@ import com.intellij.openapi.extensions.PluginDescriptor import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory.Companion.isPackageManagementSupported import com.jetbrains.python.run.target.HelpersAwareLocalTargetEnvironmentRequest import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest @@ -105,7 +104,7 @@ interface PythonInterpreterTargetEnvironmentFactory : PluginAware { @JvmStatic fun findPythonTargetInterpreter(sdk: Sdk, project: Project): HelpersAwareTargetEnvironmentRequest = when (sdk.sdkAdditionalData) { - is TargetBasedSdkAdditionalData, is PyRemoteSdkAdditionalDataBase -> + is TargetBasedSdkAdditionalData -> EP_NAME.extensionList.firstNotNullOfOrNull { it.getPythonTargetInterpreter(sdk, project) } else -> null } ?: HelpersAwareLocalTargetEnvironmentRequest() diff --git a/python/src/com/jetbrains/python/run/PythonTask.java b/python/src/com/jetbrains/python/run/PythonTask.java index e3dd8c1d7f3f..0959b1bb0040 100644 --- a/python/src/com/jetbrains/python/run/PythonTask.java +++ b/python/src/com/jetbrains/python/run/PythonTask.java @@ -36,7 +36,6 @@ import com.jetbrains.python.HelperPackage; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PythonPluginDisposable; import com.jetbrains.python.console.PydevConsoleRunnerUtil; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData; import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest; import com.jetbrains.python.sdk.PyRemoteSdkAdditionalDataMarker; import com.jetbrains.python.sdk.PythonEnvUtil; @@ -169,10 +168,7 @@ public class PythonTask { var additionalData = mySdk.getSdkAdditionalData(); if (additionalData instanceof PyRemoteSdkAdditionalDataMarker) { // Either legacy remote or target SDK - if (additionalData instanceof PyRemoteSdkAdditionalData) { - handler = executeLegacyRemoteProcess(commandLine, (PyRemoteSdkAdditionalData)additionalData); - } - else if (additionalData instanceof PyTargetAwareAdditionalData) { + if (additionalData instanceof PyTargetAwareAdditionalData) { handler = executeTargetBasedProcess((PyTargetAwareAdditionalData)additionalData); } else { @@ -313,15 +309,6 @@ public class PythonTask { return handler; } - private @NotNull ProcessHandler executeLegacyRemoteProcess(@NotNull GeneralCommandLine commandLine, - @NotNull PyRemoteSdkAdditionalData additionalData) - throws ExecutionException { - // give the hint for Docker Compose process starter that this process should be run with `docker-compose run` command - // (yep, this is hacky) - commandLine.putUserData(PyRemoteProcessStarter.RUN_AS_AUXILIARY_PROCESS, true); - return PyRemoteProcessStarter.startLegacyRemoteProcess(additionalData, commandLine, myModule.getProject(), null); - } - /** * Runs command using env vars from facet diff --git a/python/src/com/jetbrains/python/sdk/PyInvalidSdk.kt b/python/src/com/jetbrains/python/sdk/PyInvalidSdk.kt new file mode 100644 index 000000000000..4e42872bc1e0 --- /dev/null +++ b/python/src/com/jetbrains/python/sdk/PyInvalidSdk.kt @@ -0,0 +1,7 @@ +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.jetbrains.python.sdk + +import com.intellij.openapi.projectRoots.SdkAdditionalData + +// Temporary solution to mark SDK invalid +internal object PyInvalidSdk: SdkAdditionalData \ No newline at end of file diff --git a/python/src/com/jetbrains/python/sdk/PySdkExt.kt b/python/src/com/jetbrains/python/sdk/PySdkExt.kt index fe60cacb3c67..ff3857ce51bf 100644 --- a/python/src/com/jetbrains/python/sdk/PySdkExt.kt +++ b/python/src/com/jetbrains/python/sdk/PySdkExt.kt @@ -1,12 +1,10 @@ // 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 -import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer import com.intellij.execution.ExecutionException import com.intellij.execution.target.* import com.intellij.ide.projectView.actions.MarkRootsManager import com.intellij.openapi.application.* -import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleUtil @@ -16,7 +14,6 @@ import com.intellij.openapi.progress.runBlockingMaybeCancellable import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil -import com.intellij.openapi.roots.ModuleRootModificationUtil import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.util.Key import com.intellij.openapi.util.NlsContexts @@ -40,7 +37,6 @@ import com.jetbrains.python.isCondaVirtualEnv import com.jetbrains.python.isVirtualEnv import com.jetbrains.python.packaging.ui.PyPackageManagementService import com.jetbrains.python.psi.LanguageLevel -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory import com.jetbrains.python.sdk.add.v2.PathHolder import com.jetbrains.python.sdk.configuration.PyProjectSdkConfiguration.setReadyToUseSdk @@ -584,7 +580,6 @@ val Sdk.remoteSourcesLocalPath: Path Path.of(PythonSdkUtil.REMOTE_SOURCES_DIR_NAME) / Path.of(when (val data = sdkAdditionalData) { is PyTargetAwareAdditionalData -> data.uuid.toString() - is PyRemoteSdkAdditionalData -> homePath!! else -> error("Only legacy and remote SDK and target-based SDKs are supported") }.hashCode().toString()) @@ -605,18 +600,17 @@ fun Sdk.configureBuilderToRunPythonOnTarget(targetCommandLineBuilder: TargetedCo * on a target. The latter case takes place when [PythonSdkAdditionalData] of this [Sdk] implements [PyTargetAwareAdditionalData] and the * corresponding target provides file system operations (see [com.jetbrains.python.pathValidation.ValidationRequest]). * - * Note that if [PythonSdkAdditionalData] of this [Sdk] is [PyRemoteSdkAdditionalData] this method does not do any checks and returns - * `false`. This behavior may be improved in the future by generating [TargetEnvironmentConfiguration] based on the present - * [PyRemoteSdkAdditionalData]. * * @see PythonSdkFlavor.sdkSeemsValid */ val Sdk.sdkSeemsValid: Boolean get() { if (!isPythonSdk(this, true)) return false + if (this.sdkAdditionalData == PyInvalidSdk) { + return false + } val pythonSdkAdditionalData = getOrCreateAdditionalData() - if (pythonSdkAdditionalData is PyRemoteSdkAdditionalData) return false return pythonSdkAdditionalData.flavorAndData.sdkSeemsValid(this, targetEnvConfiguration) } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 5149dc1c84e7..9f215aa70be4 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -18,7 +18,6 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.*; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -28,7 +27,6 @@ import com.intellij.platform.ide.progress.ModalTaskOwner; import com.intellij.platform.ide.progress.TaskCancellation; import com.intellij.reference.SoftReference; import com.intellij.remote.ExceptionFix; -import com.intellij.remote.ext.LanguageCaseCollector; import com.intellij.util.ExceptionUtil; import com.intellij.util.PlatformUtils; import com.intellij.util.concurrency.annotations.RequiresBackgroundThread; @@ -37,10 +35,6 @@ import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; import com.jetbrains.python.parser.icons.PythonParserIcons; import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.remote.PyCredentialsContribution; -import com.jetbrains.python.remote.PyRemoteInterpreterUtil; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; -import com.jetbrains.python.remote.PythonRemoteInterpreterManager; import com.jetbrains.python.sdk.add.PyAddSdkDialog; import com.jetbrains.python.sdk.flavors.CPythonSdkFlavor; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; @@ -87,11 +81,6 @@ public final class PythonSdkType extends SdkType { private static final Key> SDK_CREATOR_COMPONENT_KEY = Key.create("#com.jetbrains.python.sdk.creatorComponent"); - /** - * Old configuration may have this prefix in homepath. We must remove it - */ - private static final @NotNull String LEGACY_TARGET_PREFIX = "target://"; - public static PythonSdkType getInstance() { return findInstance(PythonSdkType.class); } @@ -283,11 +272,6 @@ public final class PythonSdkType extends SdkType { if (homePath != null) { - // We decided to get rid of this prefix - if (homePath.startsWith(LEGACY_TARGET_PREFIX)) { - ((SdkModificator)currentSdk).setHomePath(homePath.substring(LEGACY_TARGET_PREFIX.length())); - } - if (additional.getAttributeBooleanValue(PyDetectedSdkAdditionalData.PY_DETECTED_SDK_MARKER)) { PyDetectedSdkAdditionalData data = new PyDetectedSdkAdditionalData(null, null); data.load(additional); @@ -303,11 +287,8 @@ public final class PythonSdkType extends SdkType { return targetAdditionalData; } else if (isCustomPythonSdkHomePath(homePath)) { - PythonRemoteInterpreterManager manager = PythonRemoteInterpreterManager.getInstance(); - if (manager != null) { - return manager.loadRemoteSdkData(currentSdk, additional); - } - // TODO we should have "remote" SDK data with unknown credentials anyway! + LOG.warn("Pretarget SDK skipped " + homePath); + return PyInvalidSdk.INSTANCE; } } @@ -334,10 +315,6 @@ public final class PythonSdkType extends SdkType { return CustomSdkHomePattern.isCustomPythonSdkHomePath(homePath); } - public static boolean isSkeletonsPath(String path) { - return path.contains(PythonSdkUtil.SKELETON_DIR_NAME); - } - @Override public @NotNull @NonNls String getPresentableName() { return "Python SDK"; @@ -440,22 +417,6 @@ public final class PythonSdkType extends SdkType { } return versionString; } - else if (sdkAdditionalData instanceof PyRemoteSdkAdditionalDataBase data) { - assert data != null; - String versionString = data.getVersionString(); - if (StringUtil.isEmpty(versionString)) { - try { - versionString = - PyRemoteInterpreterUtil.getInterpreterVersion(null, data, true); - } - catch (Exception e) { - LOG.warn("Couldn't get interpreter version:" + e.getMessage(), e); - versionString = "undefined"; - } - data.setVersionString(versionString); - } - return versionString; - } else { if (ApplicationManager.getApplication().isUnitTestMode()) { final var version = sdk.getUserData(MOCK_PY_VERSION_KEY); @@ -494,33 +455,15 @@ public final class PythonSdkType extends SdkType { } public static boolean isIncompleteRemote(@NotNull Sdk sdk) { - if (sdk.getSdkAdditionalData() instanceof PyRemoteSdkAdditionalDataBase) { - if (!((PyRemoteSdkAdditionalDataBase)sdk.getSdkAdditionalData()).isValid()) { - return true; - } - } return false; } public static boolean isRunAsRootViaSudo(@NotNull Sdk sdk) { SdkAdditionalData data = sdk.getSdkAdditionalData(); - return data instanceof PyRemoteSdkAdditionalDataBase pyRemoteSdkAdditionalData && pyRemoteSdkAdditionalData.isRunAsRootViaSudo() || - data instanceof PyTargetAwareAdditionalData pyTargetAwareAdditionalData && pyTargetAwareAdditionalData.isRunAsRootViaSudo(); + return data instanceof PyTargetAwareAdditionalData pyTargetAwareAdditionalData && pyTargetAwareAdditionalData.isRunAsRootViaSudo(); } public static boolean hasInvalidRemoteCredentials(@NotNull Sdk sdk) { - if (sdk.getSdkAdditionalData() instanceof PyRemoteSdkAdditionalDataBase) { - final Ref result = Ref.create(false); - ((PyRemoteSdkAdditionalDataBase)sdk.getSdkAdditionalData()).switchOnConnectionType( - new LanguageCaseCollector() { - - @Override - protected void processLanguageContribution(PyCredentialsContribution languageContribution, Object credentials) { - result.set(!languageContribution.isValid(credentials)); - } - }.collectCases(PyCredentialsContribution.class)); - return result.get(); - } return false; } diff --git a/python/src/com/jetbrains/python/sdk/conda/PyAddCondaTools.kt b/python/src/com/jetbrains/python/sdk/conda/PyAddCondaTools.kt index ad7d96d2fe39..8bc263c14e6e 100644 --- a/python/src/com/jetbrains/python/sdk/conda/PyAddCondaTools.kt +++ b/python/src/com/jetbrains/python/sdk/conda/PyAddCondaTools.kt @@ -266,10 +266,3 @@ private fun Process.captureProcessOutput(commandLine: List): ProcessOutp return CapturingProcessHandler(this, Charsets.UTF_8, commandLineString).runProcess() } -internal class IntrospectableCommandExecutor(private val introspectable: LanguageRuntimeType.Introspectable) : TargetCommandExecutor { - override val local: Boolean = false // we never introspect local machine for now - override val targetPlatform: CompletableFuture - get() = introspectable.targetPlatform - - override fun execute(command: List): CompletableFuture = introspectable.promiseExecuteScript(command) -} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/sdk/sdkExecApi.kt b/python/src/com/jetbrains/python/sdk/sdkExecApi.kt index 6433a0b7b656..8d1a7157c06d 100644 --- a/python/src/com/jetbrains/python/sdk/sdkExecApi.kt +++ b/python/src/com/jetbrains/python/sdk/sdkExecApi.kt @@ -9,7 +9,6 @@ import com.jetbrains.python.PyBundle import com.jetbrains.python.Result import com.jetbrains.python.errorProcessing.MessageError import com.jetbrains.python.errorProcessing.PyResult -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData import com.jetbrains.python.target.PyTargetAwareAdditionalData import kotlinx.coroutines.CoroutineScope import org.jetbrains.annotations.ApiStatus @@ -103,7 +102,6 @@ fun Sdk.asBinToExecute(): Result { ) } } - is PyRemoteSdkAdditionalData -> null else -> homePath?.let { try { BinOnEel(Path.of(it)) diff --git a/python/src/com/jetbrains/python/statistics/PyStatisticTools.kt b/python/src/com/jetbrains/python/statistics/PyStatisticTools.kt index 7a21eb3c611c..240b94133240 100644 --- a/python/src/com/jetbrains/python/statistics/PyStatisticTools.kt +++ b/python/src/com/jetbrains/python/statistics/PyStatisticTools.kt @@ -3,7 +3,6 @@ package com.jetbrains.python.statistics import com.intellij.internal.statistic.eventLog.EventLogGroup import com.intellij.internal.statistic.eventLog.events.* -import com.intellij.internal.statistic.utils.getPluginInfo import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project @@ -15,7 +14,6 @@ import com.jetbrains.python.hatch.sdk.isHatch import com.jetbrains.python.isCondaVirtualEnv import com.jetbrains.python.isVirtualEnv import com.jetbrains.python.psi.LanguageLevel -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase import com.jetbrains.python.sdk.PySdkUtil import com.jetbrains.python.sdk.PythonSdkAdditionalData import com.jetbrains.python.sdk.legacy.PythonSdkUtil @@ -152,7 +150,6 @@ val Sdk.executionType: InterpreterTarget get() = when (val additionalData = sdkAdditionalData) { is PyTargetAwareAdditionalData -> additionalData.executionType - is PyRemoteSdkAdditionalDataBase -> additionalData.executionType else -> LOCAL } @@ -187,11 +184,3 @@ private val PyTargetAwareAdditionalData.executionType: InterpreterTarget } } ?: REMOTE_UNKNOWN -private val PyRemoteSdkAdditionalDataBase.executionType: InterpreterTarget - get() = remoteConnectionType.let { type -> - when { - type == null -> "Remote_null" - getPluginInfo(type.javaClass).isDevelopedByJetBrains() -> "Remote_${type.name?.replace(' ', '_')}" - else -> "third_party" - }.let { name -> InterpreterTarget.values().firstOrNull { it.value == name } ?: REMOTE_UNKNOWN } - } diff --git a/python/src/com/jetbrains/python/target/PyTargetAwareAdditionalData.kt b/python/src/com/jetbrains/python/target/PyTargetAwareAdditionalData.kt index 21bc5c28fcb1..cda64fe0d665 100644 --- a/python/src/com/jetbrains/python/target/PyTargetAwareAdditionalData.kt +++ b/python/src/com/jetbrains/python/target/PyTargetAwareAdditionalData.kt @@ -1,19 +1,13 @@ // 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.target -import com.intellij.execution.target.ContributedConfigurationsList -import com.intellij.execution.target.TargetBasedSdkAdditionalData -import com.intellij.execution.target.TargetEnvironmentConfiguration -import com.intellij.execution.target.TargetEnvironmentType -import com.intellij.execution.target.hasTargetConfiguration -import com.intellij.execution.target.loadTargetConfiguration -import com.intellij.execution.target.saveTargetBasedSdkAdditionalData +import com.intellij.execution.target.* import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.vfs.VirtualFile import com.intellij.remote.RemoteSdkProperties import com.intellij.remote.RemoteSdkPropertiesHolder -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData +import com.jetbrains.python.PYCHARM_HELPERS import com.jetbrains.python.sdk.PyRemoteSdkAdditionalDataMarker import com.jetbrains.python.sdk.PythonSdkAdditionalData import com.jetbrains.python.sdk.flavors.PyFlavorAndData @@ -23,10 +17,6 @@ import org.jdom.Element import org.jetbrains.annotations.ApiStatus import java.nio.file.Path -/** - * Aims to replace [com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase]. - * For the transitional period, both of them are supposed to be used. - */ open class PyTargetAwareAdditionalData private constructor( private val b: RemoteSdkPropertiesHolder, flavorAndData: PyFlavorAndData<*, *>?, @@ -53,7 +43,11 @@ open class PyTargetAwareAdditionalData private constructor( notifyTargetEnvironmentConfigurationChanged() } - constructor(flavorAndData: PyFlavorAndData<*, *>, targetEnvironmentConfiguration: TargetEnvironmentConfiguration? = null) : this(RemoteSdkPropertiesHolder(PyRemoteSdkAdditionalData.PYCHARM_HELPERS), flavorAndData, targetEnvironmentConfiguration) + constructor(flavorAndData: PyFlavorAndData<*, *>, targetEnvironmentConfiguration: TargetEnvironmentConfiguration? = null) : this( + RemoteSdkPropertiesHolder( + PYCHARM_HELPERS), + flavorAndData, + targetEnvironmentConfiguration) override fun save(rootElement: Element) { // store "interpreter paths" (i.e. `PYTHONPATH` elements) super.save(rootElement) // store `INTERPRETER_PATH`, `HELPERS_PATH`, etc @@ -99,13 +93,11 @@ open class PyTargetAwareAdditionalData private constructor( } } - /** - * @see com.jetbrains.python.remote.PyRemoteSdkAdditionalData.setSdkId - */ - override fun setSdkId(sdkId: String?): Unit = throw IllegalStateException("sdkId in this class is constructed based on fields, so it can't be set") + + override fun setSdkId(sdkId: String?): Unit = + throw IllegalStateException("sdkId in this class is constructed based on fields, so it can't be set") /** - * @see com.jetbrains.python.remote.PyRemoteSdkAdditionalData.getSdkId */ // TODO [targets] Review the usages and probably deprecate this property as it does not seem to be sensible override fun getSdkId(): String = targetEnvironmentConfiguration?.displayName + interpreterPath @@ -128,7 +120,6 @@ open class PyTargetAwareAdditionalData private constructor( /** * Loads target data if it exists in xml. Returns `null` otherwise. - * @see com.jetbrains.python.remote.PyRemoteSdkAdditionalData.loadRemote */ @JvmStatic fun loadTargetAwareData(sdk: Sdk, element: Element): PyTargetAwareAdditionalData? { @@ -150,10 +141,9 @@ open class PyTargetAwareAdditionalData private constructor( return data } - private class DummyTargetAwareAdditionalData(base: Element) - : PyTargetAwareAdditionalData(flavorAndData = PyFlavorAndData(PyFlavorData.Empty, UnixPythonSdkFlavor.getInstance())) - , PyRemoteSdkAdditionalDataMarker - { + private class DummyTargetAwareAdditionalData(base: Element) : + PyTargetAwareAdditionalData(flavorAndData = PyFlavorAndData(PyFlavorData.Empty, UnixPythonSdkFlavor.getInstance())), + PyRemoteSdkAdditionalDataMarker { val element: Element = base.clone() override fun save(rootElement: Element) { diff --git a/python/testSrc/com/jetbrains/python/remote/PyProjectSynchronizerProviderTest.kt b/python/testSrc/com/jetbrains/python/remote/PyProjectSynchronizerProviderTest.kt deleted file mode 100644 index e6a9b3ddd0f8..000000000000 --- a/python/testSrc/com/jetbrains/python/remote/PyProjectSynchronizerProviderTest.kt +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2000-2022 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.module.Module -import com.intellij.openapi.project.Project -import com.intellij.openapi.projectRoots.Sdk -import com.intellij.openapi.util.Key -import com.intellij.openapi.util.NlsSafe -import com.intellij.remote.CredentialsType -import com.intellij.remote.ext.RemoteCredentialsHandler -import com.intellij.testFramework.LightPlatformTestCase -import com.intellij.testFramework.TestApplicationManager -import com.jetbrains.python.sdk.PythonSdkAdditionalData -import org.mockito.Mockito.mock -import org.mockito.Mockito.`when` -import java.util.function.Consumer - -class PyProjectSynchronizerProviderTest : LightPlatformTestCase() { - override fun setUp() { - super.setUp() - - TestApplicationManager.getInstance() - } - - fun `test get synchronizer for local SDK`() { - val sdk = mock(Sdk::class.java) - val localSdkAdditionalData = mock(PythonSdkAdditionalData::class.java) - `when`(sdk.sdkAdditionalData).thenReturn(localSdkAdditionalData) - - assertNull(PyProjectSynchronizerProvider.getSynchronizer(sdk)) - } - - fun `test get synchronizer for unsupported remote SDK`() { - val sdk = mock(Sdk::class.java) - val unsupportedRemoteSdkAdditionalData = mock(PyRemoteSdkAdditionalDataBase::class.java) - `when`(unsupportedRemoteSdkAdditionalData.remoteConnectionType).thenReturn(TestCredentialsType.INSTANCE) - `when`(sdk.sdkAdditionalData).thenReturn(unsupportedRemoteSdkAdditionalData) - - assertEquals(PyUnknownProjectSynchronizer.INSTANCE, PyProjectSynchronizerProvider.getSynchronizer(sdk)) - } - - fun `test get synchronizer for supported remote SDK`() { - val sdk = mock(Sdk::class.java) - val unsupportedRemoteSdkAdditionalData = mock(PyRemoteSdkAdditionalDataBase::class.java) - `when`(unsupportedRemoteSdkAdditionalData.remoteConnectionType).thenReturn(TestCredentialsType.INSTANCE) - `when`(sdk.sdkAdditionalData).thenReturn(unsupportedRemoteSdkAdditionalData) - - PyProjectSynchronizerProvider.EP_NAME.point.registerExtension(PyTestProjectSynchronizerProvider(), testRootDisposable) - - assertEquals(PyTestProjectSynchronizer.INSTANCE, PyProjectSynchronizerProvider.getSynchronizer(sdk)) - } - - private class TestCredentialsType private constructor() : CredentialsType(TEST_CREDENTIALS_TYPE_NAME, - TEST_CREDENTIALS_TYPE_PREFIX) { - override fun getCredentialsKey(): Key = throwUnsupportedOperationException() - - override fun getHandler(credentials: TestCredentialsType?): RemoteCredentialsHandler = throwUnsupportedOperationException() - - override fun createCredentials(): TestCredentialsType = throwUnsupportedOperationException() - - companion object { - @NlsSafe - private const val TEST_CREDENTIALS_TYPE_NAME = "Test Credentials Type" - - private const val TEST_CREDENTIALS_TYPE_PREFIX = "test://" - - val INSTANCE = TestCredentialsType() - } - } - - private class PyTestProjectSynchronizerProvider : PyProjectSynchronizerProvider { - override fun getSynchronizer(credsType: CredentialsType<*>, sdk: Sdk): PyProjectSynchronizer? = - if (credsType == TestCredentialsType.INSTANCE) PyTestProjectSynchronizer.INSTANCE else null - } - - private class PyTestProjectSynchronizer private constructor() : PyProjectSynchronizer { - override fun checkSynchronizationAvailable(syncCheckStrategy: PySyncCheckStrategy): String = throwUnsupportedOperationException() - - override fun getDefaultRemotePath(): String = throwUnsupportedOperationException() - - override fun syncProject(module: Module, - syncDirection: PySyncDirection, - callback: Consumer?, - vararg fileNames: String) = throwUnsupportedOperationException() - - override fun mapFilePath(project: Project, direction: PySyncDirection, filePath: String): String = throwUnsupportedOperationException() - - companion object { - val INSTANCE = PyTestProjectSynchronizer() - } - } - - companion object { - private fun throwUnsupportedOperationException(): Nothing = throw UnsupportedOperationException() - } -} \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/sdk/PySdkAdditionalDataTest.kt b/python/testSrc/com/jetbrains/python/sdk/PySdkAdditionalDataTest.kt index 422ce7f8cd04..beb2fcbdd96f 100644 --- a/python/testSrc/com/jetbrains/python/sdk/PySdkAdditionalDataTest.kt +++ b/python/testSrc/com/jetbrains/python/sdk/PySdkAdditionalDataTest.kt @@ -2,7 +2,6 @@ package com.jetbrains.python.sdk import com.intellij.testFramework.ProjectRule -import com.jetbrains.python.remote.PyRemoteSdkAdditionalData import org.jdom.Element import org.junit.Assert @@ -27,11 +26,4 @@ class PySdkAdditionalDataTest { Assert.assertEquals("UUID hasn't been loaded", sut.uuid, loadedSut.uuid) } - @Test - fun remoteAdditionalDataTest() { - var data = PyRemoteSdkAdditionalData("!!!!!") - - data = PyRemoteSdkAdditionalData("sftp://host:22/home/bin/python3") - data = PyRemoteSdkAdditionalData("docker://django:latest/python") - } } \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/sdk/PythonSdkTypePlatformTest.java b/python/testSrc/com/jetbrains/python/sdk/PythonSdkTypePlatformTest.java index 0dbb68ac189d..39a936ad7787 100644 --- a/python/testSrc/com/jetbrains/python/sdk/PythonSdkTypePlatformTest.java +++ b/python/testSrc/com/jetbrains/python/sdk/PythonSdkTypePlatformTest.java @@ -4,7 +4,6 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.remote.ext.CredentialsLanguageContribution; import com.intellij.testFramework.PlatformLiteFixture; -import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; import org.junit.Assert; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -16,7 +15,6 @@ import static org.mockito.Mockito.when; */ public class PythonSdkTypePlatformTest extends PlatformLiteFixture { @Mock private Sdk sdk; - @Mock private PyRemoteSdkAdditionalDataBase remoteSdkAdditionalData; @Mock private SdkAdditionalData sdkAdditionalData; @Mock private CredentialsLanguageContribution credentialsLanguageContribution; @@ -33,8 +31,4 @@ public class PythonSdkTypePlatformTest extends PlatformLiteFixture { Assert.assertFalse(PythonSdkType.hasInvalidRemoteCredentials(sdk)); } - public void testAbsentRemoteSdkCredentials() { - when(sdk.getSdkAdditionalData()).thenReturn(remoteSdkAdditionalData); - Assert.assertFalse(PythonSdkType.hasInvalidRemoteCredentials(sdk)); - } } \ No newline at end of file