📄 pythonrunner.java
字号:
/*
* Author: atotic
* Created on Mar 18, 2004
* License: Common Public License v1.0
*/
package org.python.pydev.debug.ui.launching;
import java.io.File;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.python.copiedfromeclipsesrc.JDTNotAvailableException;
import org.python.pydev.core.IInterpreterManager;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.debug.core.Constants;
import org.python.pydev.debug.core.PydevDebugPlugin;
import org.python.pydev.debug.model.PyDebugTarget;
import org.python.pydev.debug.model.PySourceLocator;
import org.python.pydev.debug.model.remote.RemoteDebugger;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.plugin.nature.PythonNature;
import org.python.pydev.runners.SimpleRunner;
/**
* Launches Python process, and connects it to Eclipse's debugger.
* Waits for process to complete.
*
* Modelled after org.eclipse.jdt.internal.launching.StandardVMDebugger.
*/
public class PythonRunner {
/**
* @param p
* @param process
* @throws CoreException
*/
private static void checkProcess(Process p, IProcess process) throws CoreException {
if (process == null) {
p.destroy();
throw new CoreException(PydevDebugPlugin.makeStatus(IStatus.ERROR, "Could not register with debug plugin?", null));
}
}
/**
* @param p
* @throws CoreException
*/
private static void checkProcess(Process p) throws CoreException {
if (p == null)
throw new CoreException(PydevDebugPlugin.makeStatus(IStatus.ERROR,"Could not execute python process. Was it cancelled?", null));
}
/**
* Launches the configuration
*
* The code is modeled after Ant launching example.
*/
public static void run(final PythonRunnerConfig config, ILaunch launch, IProgressMonitor monitor) throws CoreException, IOException {
//let's check if the interpreter is valid.
final IInterpreterManager interpreterManager = PythonNature.getPythonNature(config.project).getRelatedInterpreterManager();
if(!interpreterManager.hasInfoOnInterpreter(config.interpreterLocation)){
final Display display = Display.getDefault();
display.syncExec(new Runnable(){
public void run() {
String msg = "The interpreter '%s' is not correctly configured as a '%s' interpreter.\n\n" +
"Reasons: If it is an old interpreter, you can open the run dialog (Menu: run > run) " +
"and choose a new interpreter in the arguments tab.\n\n" +
"Another reason could be that you're running some file from a jython project with a " +
"python interpreter (or vice-versa), so, you have to change the project type in the " +
"project properties.";
MessageDialog.openError(display.getActiveShell(), "Invalid Interpreter",
StringUtils.format(msg, config.interpreterLocation, interpreterManager.getManagerRelatedName()));
}
});
return;
}
try{
if (config.isDebug) {
runDebug(config, launch, monitor);
}else if (config.isUnittest()) {
runUnitTest(config, launch, monitor);
}else { //default - just configured by command line (the others need special attention)
doIt(config, monitor, config.envp, config.getCommandLine(), config.workingDirectory, launch);
}
}catch (final JDTNotAvailableException e) {
PydevPlugin.log(e);
final Display display = Display.getDefault();
display.syncExec(new Runnable(){
public void run() {
MessageDialog.openError(display.getActiveShell(), "Unable to run the selected configuration.", e.getMessage());
}
});
}
}
/**
* Launches the config in the debug mode.
*
* Loosely modeled upon Ant launcher.
* @throws JDTNotAvailableException
*/
private static void runDebug(PythonRunnerConfig config, ILaunch launch, IProgressMonitor monitor) throws CoreException, IOException, JDTNotAvailableException {
if (monitor == null)
monitor = new NullProgressMonitor();
IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 5);
subMonitor.beginTask("Launching python", 1);
// Launch & connect to the debugger
RemoteDebugger debugger = new RemoteDebugger(config);
debugger.startConnect(subMonitor);
subMonitor.subTask("Constructing command_line...");
String[] cmdLine = config.getCommandLine();
Process p = DebugPlugin.exec(cmdLine, config.workingDirectory, config.envp);
checkProcess(p);
IProcess process = registerWithDebugPlugin(config, launch, p);
checkProcess(p, process);
subMonitor.subTask("Waiting for connection...");
try {
boolean userCanceled = debugger.waitForConnect(subMonitor, p, process);
if (userCanceled) {
debugger.dispose();
return;
}
}
catch (Exception ex) {
process.terminate();
p.destroy();
String message = "Unexpected error setting up the debugger";
if (ex instanceof SocketTimeoutException)
message = "Timed out after " + Float.toString(config.acceptTimeout/1000) + " seconds while waiting for python script to connect.";
throw new CoreException(PydevDebugPlugin.makeStatus(IStatus.ERROR, message, ex));
}
subMonitor.subTask("Done");
// hook up debug model, and we are off & running
PyDebugTarget t = new PyDebugTarget(launch, process, config.resource, debugger);
launch.setSourceLocator(new PySourceLocator());
debugger.startTransmission(); // this starts reading/writing from sockets
t.initialize();
t.addConsoleInputListener();
}
private static IProcess doIt(PythonRunnerConfig config, IProgressMonitor monitor, String [] envp, String[] cmdLine, File workingDirectory, ILaunch launch) throws CoreException{
if (monitor == null)
monitor = new NullProgressMonitor();
IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 5);
subMonitor.beginTask("Launching python", 1);
// Launch & connect to the debugger
subMonitor.subTask("Constructing command_line...");
String commandLineAsString = SimpleRunner.getCommandLineAsString(cmdLine);
//System.out.println("running command line: "+commandLineAsString);
Map processAttributes = new HashMap();
processAttributes.put(IProcess.ATTR_CMDLINE, commandLineAsString);
subMonitor.subTask("Exec...");
//it was dying before register, so, I made this faster to see if this fixes it
Process p = DebugPlugin.exec(cmdLine, workingDirectory, envp);
checkProcess(p);
IProcess process;
String label = cmdLine[cmdLine.length-1];
if(config.isJython()) {
if(config.isInteractive){
label = "Interactive session: "+cmdLine[0]+" ... "+config.interpreter.toOSString()+" ("+config.resource.lastSegment()+")"; //java jython.jar
}
process = registerWithDebugPluginForProcessType(label, launch, p, processAttributes, "java");
} else {
if(config.isInteractive){
label = "Interactive session: "+cmdLine[0]+" ("+config.resource.lastSegment()+")"; //c:/bin/python.exe
}
process = registerWithDebugPlugin(label, launch, p, processAttributes);
}
checkProcess(p, process);
// Registered the process with the debug plugin
subMonitor.subTask("Done");
return process;
}
private static void runUnitTest(PythonRunnerConfig config, ILaunch launch, IProgressMonitor monitor) throws CoreException, JDTNotAvailableException{
doIt(config, monitor, config.envp, config.getCommandLine(), config.workingDirectory, launch);
}
/**
* The debug plugin needs to be notified about our process.
* It'll then display the appropriate UI.
* @throws JDTNotAvailableException
*/
private static IProcess registerWithDebugPlugin(PythonRunnerConfig config, ILaunch launch, Process p) throws JDTNotAvailableException {
HashMap processAttributes = new HashMap();
processAttributes.put(IProcess.ATTR_CMDLINE, config.getCommandLineAsString());
return registerWithDebugPlugin(config.resource.lastSegment(), launch,p, processAttributes);
}
/**
* The debug plugin needs to be notified about our process.
* It'll then display the appropriate UI.
*/
private static IProcess registerWithDebugPlugin(String cmdLine, String label, ILaunch launch, Process p) {
HashMap processAttributes = new HashMap();
processAttributes.put(IProcess.ATTR_CMDLINE, cmdLine);
return registerWithDebugPlugin(label, launch,p, processAttributes);
}
/**
* The debug plugin needs to be notified about our process.
* It'll then display the appropriate UI.
*/
private static IProcess registerWithDebugPlugin(String label, ILaunch launch, Process p, Map processAttributes) {
processAttributes.put(IProcess.ATTR_PROCESS_TYPE, Constants.PROCESS_TYPE);
processAttributes.put(IProcess.ATTR_PROCESS_LABEL, label);
processAttributes.put(DebugPlugin.ATTR_CAPTURE_OUTPUT, "true");
return DebugPlugin.newProcess(launch,p, label, processAttributes);
}
/**
* The debug plugin needs to be notified about our process.
* It'll then display the appropriate UI.
*/
private static IProcess registerWithDebugPluginForProcessType(String label, ILaunch launch, Process p, Map processAttributes, String processType) {
processAttributes.put(IProcess.ATTR_PROCESS_TYPE, processType);
processAttributes.put(IProcess.ATTR_PROCESS_LABEL, label);
processAttributes.put(DebugPlugin.ATTR_CAPTURE_OUTPUT, "true");
return DebugPlugin.newProcess(launch,p, label, processAttributes);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -