diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py
index 544e8d4acfcd..444839c62168 100644
--- a/python/helpers/pydev/pydevd.py
+++ b/python/helpers/pydev/pydevd.py
@@ -25,6 +25,7 @@ from pydevd_comm import CMD_CHANGE_VARIABLE, \
CMD_CONSOLE_EXEC, \
CMD_ADD_EXCEPTION_BREAK, \
CMD_REMOVE_EXCEPTION_BREAK, \
+ CMD_LOAD_SOURCE, \
GetGlobalDebugger, \
InternalChangeVariable, \
InternalGetCompletions, \
@@ -633,6 +634,17 @@ class PyDB:
always_exception_set.remove(exc_type)
update_exception_hook()
+ elif cmd_id == CMD_LOAD_SOURCE:
+ path = text
+ try:
+ print path
+ f = open(path, 'r')
+ source = f.read()
+ print source
+ self.cmdFactory.makeLoadSourceMessage(seq, source, self)
+ except:
+ return self.cmdFactory.makeErrorMessage(seq, GetExceptionTracebackStr())
+
else:
#I have no idea what this is all about
cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(cmd_id))
diff --git a/python/helpers/pydev/pydevd_comm.py b/python/helpers/pydev/pydevd_comm.py
index d141297100de..e6868cfd485b 100644
--- a/python/helpers/pydev/pydevd_comm.py
+++ b/python/helpers/pydev/pydevd_comm.py
@@ -103,7 +103,8 @@ CMD_RELOAD_CODE = 119
CMD_GET_COMPLETIONS = 120
CMD_CONSOLE_EXEC = 121
CMD_ADD_EXCEPTION_BREAK = 122
-CMD_REMOVE_EXCEPTION_BREAK = 122
+CMD_REMOVE_EXCEPTION_BREAK = 123
+CMD_LOAD_SOURCE = 124
CMD_VERSION = 501
CMD_RETURN = 502
CMD_ERROR = 901
@@ -545,6 +546,14 @@ class NetCommandFactory:
except Exception:
return self.makeErrorMessage(seq, GetExceptionTracebackStr())
+ def makeLoadSourceMessage(self, seq, source, dbg=None):
+ try:
+ net = NetCommand(str(CMD_LOAD_SOURCE), seq, '%s' % source)
+ if dbg:
+ dbg.writer.addCommand(net)
+ except:
+ return self.makeErrorMessage(0, GetExceptionTracebackStr())
+
INTERNAL_TERMINATE_THREAD = 1
INTERNAL_SUSPEND_THREAD = 2
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java
index 3a4cfad16b35..569eb5095923 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java
@@ -2,7 +2,6 @@ package com.jetbrains.python.debugger.pydev;
import com.jetbrains.python.debugger.PyDebuggerException;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public abstract class AbstractCommand {
@@ -27,6 +26,7 @@ public abstract class AbstractCommand {
public static final int CONSOLE_EXEC = 121;
public static final int ADD_EXCEPTION_BREAKPOINT = 122;
public static final int REMOVE_EXCEPTION_BREAKPOINT = 123;
+ public static final int LOAD_SOURCE = 124;
public static final int VERSION = 501;
public static final String NEW_LINE_CHAR = "@_@NEW_LINE_CHAR@_@";
public static final String TAB_CHAR = "@_@TAB_CHAR@_@";
@@ -39,7 +39,7 @@ public abstract class AbstractCommand {
myCommandCode = commandCode;
}
- @Nullable
+ @NotNull
public final String getPayload() {
Payload payload = new Payload();
buildPayload(payload);
@@ -52,7 +52,6 @@ public abstract class AbstractCommand {
return false;
}
- // todo: pass debugger to constructor(?)
public void execute() throws PyDebuggerException {
int sequence = myDebugger.getNextSequence();
if (isResponseExpected()) {
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/LoadSourceCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/LoadSourceCommand.java
new file mode 100644
index 000000000000..cdafeae93a52
--- /dev/null
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/LoadSourceCommand.java
@@ -0,0 +1,39 @@
+package com.jetbrains.python.debugger.pydev;
+
+import com.jetbrains.python.debugger.PyDebuggerException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author traff
+ */
+public class LoadSourceCommand extends AbstractCommand {
+ private final String myPath;
+
+ private String myContent = null;
+
+ protected LoadSourceCommand(@NotNull final RemoteDebugger debugger, String path) {
+ super(debugger, LOAD_SOURCE);
+ myPath = path;
+ }
+
+ public boolean isResponseExpected() {
+ return true;
+ }
+
+ @Override
+ protected void processResponse(final ProtocolFrame response) throws PyDebuggerException {
+ super.processResponse(response);
+ myContent = ProtocolParser.parseSourceContent(response.getPayload());
+ }
+
+ @Override
+ protected void buildPayload(Payload payload) {
+ payload.add(myPath);
+ }
+
+ @Nullable
+ public String getContent() {
+ return myContent;
+ }
+}
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java
index 69cd30e6ab41..b8b7a782af78 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java
@@ -17,6 +17,10 @@ public class ProtocolParser {
private ProtocolParser() {
}
+ public static String parseSourceContent(String payload) throws PyDebuggerException {
+ return payload;
+ }
+
public static String decode(final String value) throws PyDebuggerException {
try {
return URLDecoder.decode(value, "UTF-8");
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
index b527b4601968..8ec59c8d6666 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
@@ -150,6 +150,18 @@ public class RemoteDebugger {
return command.getNewValue();
}
+ @Nullable
+ public String loadSource(String path) {
+ LoadSourceCommand command = new LoadSourceCommand(this, path);
+ try {
+ command.execute();
+ return command.getContent();
+ }
+ catch (PyDebuggerException e) {
+ return "print 1";
+ }
+ }
+
private static String composeName(final PyDebugValue var) {
final StringBuilder sb = new StringBuilder(var.getTempName());
PyDebugValue p = var;
@@ -472,7 +484,7 @@ public class RemoteDebugger {
}
private void fireCloseEvent() {
- for (RemoteDebuggerCloseListener listener: myCloseListeners) {
+ for (RemoteDebuggerCloseListener listener : myCloseListeners) {
listener.closed();
}
}
diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml
index c22e48211487..9b707368905b 100644
--- a/python/src/META-INF/python-plugin-common.xml
+++ b/python/src/META-INF/python-plugin-common.xml
@@ -88,6 +88,7 @@
+
com.jetbrains.python.codeInsight.intentions.ImportToImportFromIntention
diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index e4c7b441424e..c987bf642a4b 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -519,7 +519,7 @@ run.configuration.type.description=Starts server for remote debug
remote.debug.info=Info
remote.debug.server.hint=Run this remote debug configuration to start debug server.
-remote.debug.server.hint2=Then copy \\helpers\\pydev package from your PyCharm distribution to location of your python script.
+remote.debug.server.hint2=Add pycharm-debug.egg from PyCharm distribution to python path of your script.
remote.debug.server.hint3=Use the following command in your script to connect to debug server:
remote.debug.settings=Settings
remote.debug.remote.host=Remote host
@@ -527,3 +527,5 @@ remote.debug.port=Port
remote.debug.remote.root.folder=Remote root folder
remote.debug.local.root.folder=Local root folder
remote.debug.server.hint4=If you want to enable stdout and stderr redirection to PyCharm console, use following command in your script:
+remote.debug.local.host=Local host name
+remote.debug.redirect.output=Redirect output to console
diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
index d0dd5fd8e824..6388b5b000ef 100644
--- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
+++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
@@ -41,8 +41,6 @@ import static javax.swing.SwingUtilities.invokeLater;
// todo: pydevd supports module reloading - look for a way to use the feature
// todo: smart step into
public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, ProcessListener {
-
- private final PyPositionConverter myPositionConverter;
private final RemoteDebugger myDebugger;
private final XBreakpointHandler[] myBreakpointHandlers;
private final PyDebuggerEditorsProvider myEditorsProvider;
@@ -58,18 +56,12 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
private boolean myClosing = false;
- public PyDebugProcess(@NotNull XDebugSession session,
- @NotNull final ServerSocket serverSocket,
- @NotNull final ExecutionConsole executionConsole,
- @Nullable final ProcessHandler processHandler) {
- this(session, serverSocket, executionConsole, processHandler, new PyLocalPositionConverter());
- }
-
+ private PyPositionConverter myPositionConverter;
public PyDebugProcess(final @NotNull XDebugSession session,
@NotNull final ServerSocket serverSocket,
@NotNull final ExecutionConsole executionConsole,
- @Nullable final ProcessHandler processHandler, @NotNull PyPositionConverter positionConverter) {
+ @Nullable final ProcessHandler processHandler) {
super(session);
session.setPauseActionSupported(true);
myDebugger = new RemoteDebugger(this, serverSocket, 10);
@@ -80,7 +72,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
if (myProcessHandler != null) {
myProcessHandler.addProcessListener(this);
}
- myPositionConverter = positionConverter;
+ myPositionConverter = new PyLocalPositionConverter();
myDebugger.addCloseListener(new RemoteDebuggerCloseListener() {
@Override
public void closed() {
@@ -89,6 +81,11 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
});
}
+ public void setPositionConverter(PyPositionConverter positionConverter) {
+ myPositionConverter = positionConverter;
+ }
+
+
@Override
public PyPositionConverter getPositionConverter() {
return myPositionConverter;
@@ -272,6 +269,11 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
myNewVariableValue.put(frame.getThreadFrameId(), newValue);
}
+ @Nullable
+ public String loadSource(String path) {
+ return myDebugger.loadSource(path);
+ }
+
@Override
public boolean isVariable(String name) {
final Project project = getSession().getProject();
@@ -411,4 +413,8 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
}
+
+ public PyStackFrame createStackFrame(PyStackFrameInfo frameInfo) {
+ return new PyStackFrame(this, frameInfo);
+ }
}
diff --git a/python/src/com/jetbrains/python/debugger/PyExecutionStack.java b/python/src/com/jetbrains/python/debugger/PyExecutionStack.java
index 599183114d9a..c8da6847ef84 100644
--- a/python/src/com/jetbrains/python/debugger/PyExecutionStack.java
+++ b/python/src/com/jetbrains/python/debugger/PyExecutionStack.java
@@ -53,7 +53,7 @@ public class PyExecutionStack extends XExecutionStack {
}
private static PyStackFrame convert(final PyDebugProcess debugProcess, final PyStackFrameInfo frameInfo) {
- return new PyStackFrame(debugProcess, frameInfo);
+ return debugProcess.createStackFrame(frameInfo);
}
@Override
diff --git a/python/src/com/jetbrains/python/debugger/PyLocalPositionConverter.java b/python/src/com/jetbrains/python/debugger/PyLocalPositionConverter.java
index d46b79b3f631..8707120cd245 100644
--- a/python/src/com/jetbrains/python/debugger/PyLocalPositionConverter.java
+++ b/python/src/com/jetbrains/python/debugger/PyLocalPositionConverter.java
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
public class PyLocalPositionConverter implements PyPositionConverter {
protected static class PyLocalSourcePosition extends PySourcePosition {
- PyLocalSourcePosition(final String file, final int line) {
+ public PyLocalSourcePosition(final String file, final int line) {
super(file, line);
}
}
diff --git a/python/src/com/jetbrains/python/debugger/PyRemotePositionConverter.java b/python/src/com/jetbrains/python/debugger/PyRemotePositionConverter.java
deleted file mode 100644
index 58b02ffb66e8..000000000000
--- a/python/src/com/jetbrains/python/debugger/PyRemotePositionConverter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.jetbrains.python.debugger;
-
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.xdebugger.XSourcePosition;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author traff
- */
-public class PyRemotePositionConverter extends PyLocalPositionConverter {
- private final String myLocalRoot;
- private final String myRemoteRoot;
-
- public PyRemotePositionConverter(final String localRoot, final String remoteRoot) {
- myLocalRoot = FileUtil.toSystemIndependentName(localRoot);
- myRemoteRoot = FileUtil.toSystemIndependentName(remoteRoot);
- }
-
- @NotNull
- @Override
- public PySourcePosition convert(@NotNull XSourcePosition position) {
- String path = FileUtil.toSystemIndependentName(position.getFile().getPath());
- if (myLocalRoot.length() > 0) {
- path = path.replace(myLocalRoot, myRemoteRoot);
- }
- return new PyLocalSourcePosition(path, position.getLine() + 1);
- }
-
- @Override
- public XSourcePosition convert(@NotNull PySourcePosition position) {
- String path = FileUtil.toSystemIndependentName(position.getFile());
- if (myRemoteRoot.length() > 0) {
- path = path.replace(myRemoteRoot, myLocalRoot);
- }
- final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path);
- return createXSourcePosition(file, position.getLine());
- }
-}
diff --git a/python/src/com/jetbrains/python/debugger/PyStackFrame.java b/python/src/com/jetbrains/python/debugger/PyStackFrame.java
index 91554bf7f0f3..46ac0f47a241 100644
--- a/python/src/com/jetbrains/python/debugger/PyStackFrame.java
+++ b/python/src/com/jetbrains/python/debugger/PyStackFrame.java
@@ -110,4 +110,8 @@ public class PyStackFrame extends XStackFrame {
return myFrameInfo.getThreadId() + ":" + myFrameInfo.getId();
}
+ protected XSourcePosition getPosition() {
+ return myPosition;
+ }
+
}
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
index 25d558abab00..e822f6f1feaa 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
@@ -707,7 +707,7 @@ public class PythonSdkType extends SdkType {
}
@Nullable
- public static Sdk findPythonSdk(Module module) {
+ public static Sdk findPythonSdk(@Nullable Module module) {
if (module == null) return null;
final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.getSdkType() instanceof PythonSdkType) return sdk;