diff --git a/python/src/META-INF/python-core-common.xml b/python/src/META-INF/python-core-common.xml
index 7c2d825b4d07..847c415fe0fa 100644
--- a/python/src/META-INF/python-core-common.xml
+++ b/python/src/META-INF/python-core-common.xml
@@ -630,6 +630,7 @@
+
diff --git a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java
index 4418b39b293a..8ffa7a88e38f 100644
--- a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java
+++ b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java
@@ -33,6 +33,7 @@ import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.remote.RemoteSdkAdditionalData;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugProcessStarter;
import com.intellij.xdebugger.XDebugSession;
@@ -69,6 +70,7 @@ public class PyDebugRunner extends GenericProgramRunner {
public static final String PORT_PARAM = "--port";
public static final String FILE_PARAM = "--file";
public static final String MODULE_PARAM = "--module";
+ public static final String MULTIPROCESS_PARAM = "--multiprocess";
public static final String IDE_PROJECT_ROOTS = "IDE_PROJECT_ROOTS";
public static final String LIBRARY_ROOTS = "LIBRARY_ROOTS";
public static final String PYTHON_ASYNCIO_DEBUG = "PYTHONASYNCIODEBUG";
@@ -121,6 +123,16 @@ public class PyDebugRunner extends GenericProgramRunner {
FileDocumentManager.getInstance().saveAllDocuments();
final PythonCommandLineState pyState = (PythonCommandLineState)state;
+
+ Sdk sdk = pyState.getSdk();
+ if (sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData) {
+ RemoteSdkAdditionalData remoteSdkAdditionalData = (RemoteSdkAdditionalData)sdk.getSdkAdditionalData();
+ PyRemoteDebugSessionCreator sessionCreator = PyRemoteDebugSessionCreator.findExtension(remoteSdkAdditionalData);
+ if (sessionCreator != null) {
+ return sessionCreator.createSession(this, pyState, environment);
+ }
+ }
+
final ServerSocket serverSocket = PythonCommandLineState.createServerSocket();
final int serverLocalPort = serverSocket.getLocalPort();
RunProfile profile = environment.getRunProfile();
@@ -215,7 +227,7 @@ public class PyDebugRunner extends GenericProgramRunner {
}
@Nullable
- private static CommandLinePatcher createRunConfigPatcher(RunProfileState state, RunProfile profile) {
+ public static CommandLinePatcher createRunConfigPatcher(RunProfileState state, RunProfile profile) {
CommandLinePatcher runConfigPatcher = null;
if (state instanceof PythonCommandLineState && profile instanceof AbstractPythonRunConfiguration) {
runConfigPatcher = (AbstractPythonRunConfiguration)profile;
@@ -283,10 +295,10 @@ public class PyDebugRunner extends GenericProgramRunner {
}
private void fillDebugParameters(@NotNull Project project,
- @NotNull ParamsGroup debugParams,
- int serverLocalPort,
- @NotNull PythonCommandLineState pyState,
- @NotNull GeneralCommandLine cmd) {
+ @NotNull ParamsGroup debugParams,
+ int serverLocalPort,
+ @NotNull PythonCommandLineState pyState,
+ @NotNull GeneralCommandLine cmd) {
PythonHelper.DEBUGGER.addToGroup(debugParams, cmd);
configureDebugParameters(project, debugParams, pyState, cmd);
@@ -294,14 +306,7 @@ public class PyDebugRunner extends GenericProgramRunner {
configureDebugEnvironment(project, cmd.getEnvironment());
- final String[] debuggerArgs = new String[]{
- CLIENT_PARAM, "127.0.0.1",
- PORT_PARAM, String.valueOf(serverLocalPort),
- FILE_PARAM
- };
- for (String s : debuggerArgs) {
- debugParams.addParameter(s);
- }
+ configureDebugConnectionParameters(debugParams, serverLocalPort);
}
public static void configureDebugEnvironment(@NotNull Project project, Map environment) {
@@ -324,14 +329,19 @@ public class PyDebugRunner extends GenericProgramRunner {
}
protected void configureDebugParameters(@NotNull Project project,
- @NotNull ParamsGroup debugParams,
- @NotNull PythonCommandLineState pyState,
- @NotNull GeneralCommandLine cmd) {
+ @NotNull ParamsGroup debugParams,
+ @NotNull PythonCommandLineState pyState,
+ @NotNull GeneralCommandLine cmd) {
if (pyState.isMultiprocessDebug()) {
//noinspection SpellCheckingInspection
debugParams.addParameter("--multiproc");
}
+ configureCommonDebugParameters(project, debugParams);
+ }
+
+ public static void configureCommonDebugParameters(@NotNull Project project,
+ @NotNull ParamsGroup debugParams) {
if (isModule) {
debugParams.addParameter("--module");
}
@@ -349,6 +359,17 @@ public class PyDebugRunner extends GenericProgramRunner {
}
}
+ private static void configureDebugConnectionParameters(@NotNull ParamsGroup debugParams, int serverLocalPort) {
+ final String[] debuggerArgs = new String[]{
+ CLIENT_PARAM, "127.0.0.1",
+ PORT_PARAM, String.valueOf(serverLocalPort),
+ FILE_PARAM
+ };
+ for (String s : debuggerArgs) {
+ debugParams.addParameter(s);
+ }
+ }
+
private static void addProjectRootsToEnv(@NotNull Project project, @NotNull Map environment) {
List roots = Lists.newArrayList();
diff --git a/python/src/com/jetbrains/python/debugger/PyRemoteDebugSessionCreator.java b/python/src/com/jetbrains/python/debugger/PyRemoteDebugSessionCreator.java
new file mode 100644
index 000000000000..3c9c6c8640b4
--- /dev/null
+++ b/python/src/com/jetbrains/python/debugger/PyRemoteDebugSessionCreator.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.debugger;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.remote.RemoteSdkAdditionalData;
+import com.intellij.xdebugger.XDebugSession;
+import com.jetbrains.python.run.PythonCommandLineState;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Alexander Koshevoy
+ */
+public abstract class PyRemoteDebugSessionCreator {
+ public static final ExtensionPointName EP_NAME
+ = ExtensionPointName.create("Pythonid.pyRemoteDebugSessionCreator");
+
+ protected abstract boolean appliesTo(@NotNull RemoteSdkAdditionalData remoteSdkAdditionalData);
+
+ @NotNull
+ public abstract XDebugSession createSession(@NotNull PyDebugRunner runner,
+ @NotNull PythonCommandLineState state,
+ @NotNull ExecutionEnvironment environment)
+ throws ExecutionException;
+
+ @Contract("null -> null")
+ @Nullable
+ public static PyRemoteDebugSessionCreator findExtension(@Nullable RemoteSdkAdditionalData remoteSdkAdditionalData) {
+ if (remoteSdkAdditionalData == null) {
+ return null;
+ }
+ for (PyRemoteDebugSessionCreator sessionCreator : EP_NAME.getExtensions()) {
+ if (sessionCreator.appliesTo(remoteSdkAdditionalData)) {
+ return sessionCreator;
+ }
+ }
+ return null;
+ }
+}