Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Live coding on debugger.

  • Loading branch information...
commit cbefd1aab4571d0c82c9e9c00d9745b7b20bb8e8 1 parent 0c37db1
@fabioz authored
View
6 ...alysis/src/com/python/pydev/analysis/additionalinfo/AbstractAdditionalDependencyInfo.java
@@ -234,7 +234,8 @@ public void updateKeysIfNeededAndSave(PyPublicTreeMap<ModulesKey, ModulesKey> ke
if (hasNew || hasRemoved) {
if (DebugSettings.DEBUG_INTERPRETER_AUTO_UPDATE) {
Log.toLogFile(this,
- org.python.pydev.shared_core.string.StringUtils.format("Additional info modules. Added: %s Removed: %s", newKeys, removedKeys));
+ org.python.pydev.shared_core.string.StringUtils.format(
+ "Additional info modules. Added: %s Removed: %s", newKeys, removedKeys));
}
save();
}
@@ -253,7 +254,8 @@ public void updateKeysIfNeededAndSave(PyPublicTreeMap<ModulesKey, ModulesKey> ke
for (int i = 0; i < token.length(); i++) {
if (!Character.isJavaIdentifierPart(token.charAt(i))) {
- throw new RuntimeException(org.python.pydev.shared_core.string.StringUtils.format("Token: %s is not a valid token to search for.", token));
+ throw new RuntimeException(org.python.pydev.shared_core.string.StringUtils.format(
+ "Token: %s is not a valid token to search for.", token));
}
}
synchronized (lock) {
View
1  plugins/org.python.pydev.debug/src/org/python/pydev/debug/model/AbstractDebugTarget.java
@@ -323,6 +323,7 @@ public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
*/
public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
if (breakpoint instanceof PyBreakpoint) {
+ PyBreakpoint pyBreakpoint = (PyBreakpoint) breakpoint;
breakpointRemoved(breakpoint, null);
breakpointAdded(breakpoint);
}
View
64 plugins/org.python.pydev.debug/src/org/python/pydev/debug/model/PyReloadCode.java
@@ -6,10 +6,22 @@
*/
package org.python.pydev.debug.model;
+import java.io.File;
+import java.util.List;
import java.util.ListResourceBundle;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jface.text.IDocument;
+import org.python.pydev.core.IPythonNature;
+import org.python.pydev.core.MisconfigurationException;
+import org.python.pydev.debug.model.remote.ReloadCodeCommand;
+import org.python.pydev.debug.ui.DebugPrefsPage;
+import org.python.pydev.editor.PyEdit;
+import org.python.pydev.shared_core.callbacks.ICallback;
+import org.python.pydev.shared_core.log.Log;
+import org.python.pydev.shared_core.utils.ArrayUtils;
import org.python.pydev.shared_ui.editor.BaseEditor;
import org.python.pydev.shared_ui.editor.IPyEditListener;
@@ -22,27 +34,39 @@ public void onDispose(BaseEditor baseEditor, IProgressMonitor monitor) {
}
public void onSave(BaseEditor baseEditor, IProgressMonitor monitor) {
+ if (!DebugPrefsPage.getReloadModuleOnChange()) {
+ return;
+ }
+ PyEdit edit = (PyEdit) baseEditor;
+ File file = edit.getEditorFile();
+ if (file != null) {
- //Reloading code removed for now (still too experimental)
-
- // File file = edit.getEditorFile();
- // if(file != null){
- // IAdaptable context = DebugUITools.getDebugContext();
- // if(context instanceof PyStackFrame){
- // PyStackFrame stackFrame = (PyStackFrame) context;
- // try{
- // IPythonNature pythonNature = edit.getPythonNature();
- // if(pythonNature != null){
- // String moduleName = pythonNature.resolveModule(file);
- // stackFrame.getTarget().postCommand(
- // new ReloadCodeCommand(stackFrame.getTarget(), moduleName));
- // }
- // }catch(MisconfigurationException e){
- // PydevPlugin.log(e);
- // }
- //
- // }
- // }
+ IDebugTarget[] debugTargets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets();
+ if (debugTargets.length > 0) {
+ ICallback<Boolean, IDebugTarget> callbackThatFilters = new ICallback<Boolean, IDebugTarget>() {
+
+ @Override
+ public Boolean call(IDebugTarget arg) {
+ return arg instanceof AbstractDebugTarget;
+ }
+ };
+ List<IDebugTarget> filter = ArrayUtils.filter(debugTargets, callbackThatFilters);
+ if (filter.size() > 0) {
+ try {
+ IPythonNature pythonNature = edit.getPythonNature();
+ if (pythonNature != null) {
+ String moduleName = pythonNature.resolveModule(file);
+ for (IDebugTarget iDebugTarget : filter) {
+ AbstractDebugTarget target = (AbstractDebugTarget) iDebugTarget;
+ target.postCommand(new ReloadCodeCommand(target, moduleName));
+ }
+ }
+ } catch (MisconfigurationException e) {
+ Log.log(e);
+ }
+ }
+ }
+ }
}
public void onSetDocument(IDocument document, BaseEditor baseEditor, IProgressMonitor monitor) {
View
9 plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/DebugPrefsPage.java
@@ -12,6 +12,7 @@
import java.util.List;
+import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IntegerFieldEditor;
@@ -21,6 +22,7 @@
import org.python.pydev.core.ExtensionHelper;
import org.python.pydev.editor.preferences.PydevEditorPrefs;
import org.python.pydev.plugin.PydevPlugin;
+import org.python.pydev.plugin.preferences.PydevPrefs;
/**
* Debug preferences.
@@ -50,6 +52,9 @@ protected void createFieldEditors() {
Composite p = getFieldEditorParent();
addField(new IntegerFieldEditor(PydevEditorPrefs.CONNECT_TIMEOUT, "Connect timeout for debugger (ms)", p, 10));
+ addField(new BooleanFieldEditor(PydevEditorPrefs.RELOAD_MODULE_ON_CHANGE,
+ "When file is changed, automatically reload module?", p));
+
List<IDebugPreferencesPageParticipant> participants = ExtensionHelper
.getParticipants(ExtensionHelper.PYDEV_DEBUG_PREFERENCES_PAGE);
for (IDebugPreferencesPageParticipant participant : participants) {
@@ -58,6 +63,10 @@ protected void createFieldEditors() {
}
+ public static boolean getReloadModuleOnChange() {
+ return PydevPrefs.getPreferences().getBoolean(PydevEditorPrefs.RELOAD_MODULE_ON_CHANGE);
+ }
+
/**
* Make it available for extensions
*/
View
32 plugins/org.python.pydev/pysrc/pydevd.py
@@ -52,7 +52,8 @@
PydevdLog, \
StartClient, \
StartServer, \
- InternalSetNextStatementThread
+ InternalSetNextStatementThread, \
+ ReloadCodeCommand
from pydevd_file_utils import NormFileToServer, GetFilenameAndBase
import pydevd_import_class
@@ -340,9 +341,13 @@ def getInternalQueue(self, thread_id):
def postInternalCommand(self, int_cmd, thread_id):
""" if thread_id is *, post to all """
if thread_id == "*":
- for k in self._cmd_queue.keys():
- self._cmd_queue[k].put(int_cmd)
-
+ threads = threadingEnumerate()
+ for t in threads:
+ thread_name = t.getName()
+ if not thread_name.startswith('pydevd.') or thread_name == 'pydevd.CommandThread':
+ thread_id = GetThreadId(t)
+ queue = self.getInternalQueue(thread_id)
+ queue.put(int_cmd)
else:
queue = self.getInternalQueue(thread_id)
queue.put(int_cmd)
@@ -581,20 +586,9 @@ def processNetCommand(self, cmd_id, seq, text):
elif cmd_id == CMD_RELOAD_CODE:
#we received some command to make a reload of a module
module_name = text.strip()
- from pydevd_reload import xreload
- if not DictContains(sys.modules, module_name):
- if '.' in module_name:
- new_module_name = module_name.split('.')[-1]
- if DictContains(sys.modules, new_module_name):
- module_name = new_module_name
-
- if not DictContains(sys.modules, module_name):
- sys.stderr.write('pydev debugger: Unable to find module to reload: "' + module_name + '".\n')
- sys.stderr.write('pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n')
-
- else:
- sys.stderr.write('pydev debugger: Reloading: ' + module_name + '\n')
- xreload(sys.modules[module_name])
+
+ int_cmd = ReloadCodeCommand(module_name)
+ self.postInternalCommand(int_cmd, '*')
elif cmd_id == CMD_CHANGE_VARIABLE:
@@ -678,7 +672,7 @@ def processNetCommand(self, cmd_id, seq, text):
line = int(line)
if DEBUG_TRACE_BREAKPOINTS > 0:
- sys.stderr.write('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name))
+ sys.stderr.write('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name.encode('utf-8')))
if DictContains(self.breakpoints, file):
breakDict = self.breakpoints[file]
View
41 plugins/org.python.pydev/pysrc/pydevd_comm.py
@@ -640,7 +640,48 @@ def canBeExecutedBy(self, thread_id):
def doIt(self, dbg):
raise NotImplementedError("you have to override doIt")
+
+
+class ReloadCodeCommand:
+
+
+ def __init__(self, module_name):
+ self.module_name = module_name
+ self.executed = False
+ self.lock = threading.Lock()
+
+ def canBeExecutedBy(self, thread_id):
+ return True #Any thread can execute it!
+
+
+ def doIt(self, dbg):
+ self.lock.acquire()
+ try:
+ if self.executed:
+ return
+ self.executed = True
+ finally:
+ self.lock.release()
+
+ module_name = self.module_name
+ if not DictContains(sys.modules, module_name):
+ if '.' in module_name:
+ new_module_name = module_name.split('.')[-1]
+ if DictContains(sys.modules, new_module_name):
+ module_name = new_module_name
+
+ if not DictContains(sys.modules, module_name):
+ sys.stderr.write('pydev debugger: Unable to find module to reload: "' + module_name + '".\n')
+ sys.stderr.write('pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n')
+
+ else:
+ sys.stderr.write('pydev debugger: Start reloading module: "' + module_name + '" ... ')
+ import pydevd_reload
+ pydevd_reload.xreload(sys.modules[module_name])
+ sys.stderr.write('reload finished\n')
+
+
#=======================================================================================================================
# InternalTerminateThread
#=======================================================================================================================
View
7 plugins/org.python.pydev/pysrc/pydevd_exec.py
@@ -1,2 +1,5 @@
-def Exec(exp, global_vars, local_vars):
- exec exp in global_vars, local_vars
+def Exec(exp, global_vars, local_vars=None):
+ if local_vars is not None:
+ exec exp in global_vars, local_vars
+ else:
+ exec exp in global_vars
View
7 plugins/org.python.pydev/pysrc/pydevd_exec2.py
@@ -1,2 +1,5 @@
-def Exec(exp, global_vars, local_vars):
- exec(exp, global_vars, local_vars)
+def Exec(exp, global_vars, local_vars=None):
+ if local_vars is not None:
+ exec(exp, global_vars, local_vars)
+ else:
+ exec(exp, global_vars)
View
9 plugins/org.python.pydev/pysrc/pydevd_reload.py
@@ -36,6 +36,7 @@
import imp
import sys
import types
+from pydev_imports import Exec
def xreload(mod):
@@ -54,7 +55,7 @@ def xreload(mod):
# Parse it into package name and module name, e.g. 'foo.bar' and 'whatever'
i = modname.rfind(".")
if i >= 0:
- pkgname, modname = modname[:i], modname[i+1:]
+ pkgname, modname = modname[:i], modname[i + 1:]
else:
pkgname = None
# Compute the search path
@@ -64,7 +65,7 @@ def xreload(mod):
path = pkg.__path__ # Search inside the package
else:
# Search the top-level module path
- pkg = None
+ pkg = None
path = None # Make find_module() uses the default search path
# Find the module; may raise ImportError
(stream, filename, (suffix, mode, kind)) = imp.find_module(modname, path)
@@ -92,7 +93,7 @@ def xreload(mod):
tmpns = modns.copy()
modns.clear()
modns["__name__"] = tmpns["__name__"]
- exec(code, modns)
+ Exec(code, modns)
# Now we get to the hard part
oldnames = set(tmpns)
newnames = set(modns)
@@ -182,7 +183,7 @@ def _update_class(oldclass, newclass):
for name in oldnames - newnames:
delattr(oldclass, name)
for name in oldnames & newnames - set(['__dict__', '__doc__']):
- setattr(oldclass, name, _update(olddict[name], newdict[name]))
+ setattr(oldclass, name, _update(olddict[name], newdict[name]))
return oldclass
View
3  plugins/org.python.pydev/src/org/python/pydev/plugin/preferences/AbstractPydevPrefs.java
@@ -183,6 +183,9 @@
public static final String CONNECT_TIMEOUT = "CONNECT_TIMEOUT";
public static final int DEFAULT_CONNECT_TIMEOUT = 20000;
+ public static final String RELOAD_MODULE_ON_CHANGE = "RELOAD_MODULE_ON_CHANGE";
+ public static final boolean DEFAULT_RELOAD_MODULE_ON_CHANGE = true;
+
//font
public static final String DECORATOR_STYLE = "DECORATOR_STYLE";
public static final int DEFAULT_DECORATOR_STYLE = SWT.ITALIC;
View
1  plugins/org.python.pydev/src/org/python/pydev/plugin/preferences/PydevPrefsInitializer.java
@@ -114,6 +114,7 @@ public void initializeDefaultPreferences() {
//no UI
node.putInt(PydevEditorPrefs.CONNECT_TIMEOUT, PydevEditorPrefs.DEFAULT_CONNECT_TIMEOUT);
+ node.putBoolean(PydevEditorPrefs.RELOAD_MODULE_ON_CHANGE, PydevEditorPrefs.DEFAULT_RELOAD_MODULE_ON_CHANGE);
//pydev todo tasks
node.put(PyTodoPrefPage.PY_TODO_TAGS, PyTodoPrefPage.DEFAULT_PY_TODO_TAGS);
Please sign in to comment.
Something went wrong with that request. Please try again.