mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IPython debug console: distinguish between user variables and ipython ones (PY-5171)
Information about IPython hidden variables is taken from the special IPython dict. After that we move these variables to a separate group "IPython Variables".
This commit is contained in:
@@ -1057,8 +1057,10 @@ class InternalGetFrame(InternalThreadCommand):
|
||||
try:
|
||||
frame = pydevd_vars.find_frame(self.thread_id, self.frame_id)
|
||||
if frame is not None:
|
||||
hidden_ns = pydevconsole.get_ipython_hidden_vars_dict()
|
||||
xml = "<xml>"
|
||||
xml += pydevd_xml.frame_vars_to_xml(frame.f_locals)
|
||||
xml += pydevd_vars.frame_vars_to_xml(frame.f_locals, hidden_ns)
|
||||
del frame
|
||||
xml += "</xml>"
|
||||
cmd = dbg.cmd_factory.make_get_frame_message(self.sequence, xml)
|
||||
|
||||
@@ -162,7 +162,16 @@ def return_values_from_dict_to_xml(return_dict):
|
||||
return res
|
||||
|
||||
|
||||
def frame_vars_to_xml(frame_f_locals):
|
||||
def ipython_hidden_values_to_xml(key, val, hidden_ns):
|
||||
res = ""
|
||||
if key in hidden_ns.keys():
|
||||
res += var_to_xml(val, str(key), ipython_hidden=True)
|
||||
else:
|
||||
res += var_to_xml(val, str(key))
|
||||
return res
|
||||
|
||||
|
||||
def frame_vars_to_xml(frame_f_locals, hidden_ns=None):
|
||||
""" dumps frame variables to XML
|
||||
<var name="var_name" scope="local" type="type" value="value"/>
|
||||
"""
|
||||
@@ -180,7 +189,10 @@ def frame_vars_to_xml(frame_f_locals):
|
||||
if k == RETURN_VALUES_DICT:
|
||||
xml += return_values_from_dict_to_xml(v)
|
||||
else:
|
||||
xml += var_to_xml(v, str(k))
|
||||
if hidden_ns is not None:
|
||||
xml += ipython_hidden_values_to_xml(k, v, hidden_ns)
|
||||
else:
|
||||
xml += var_to_xml(v, str(k))
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
pydev_log.error("Unexpected error, recovered safely.\n")
|
||||
@@ -191,7 +203,7 @@ def frame_vars_to_xml(frame_f_locals):
|
||||
def get_type_qualifier(type):
|
||||
return getattr(type, "__module__", "")
|
||||
|
||||
def var_to_xml(val, name, doTrim=True, additionalInXml='', return_value=False):
|
||||
def var_to_xml(val, name, doTrim=True, additionalInXml='', return_value=False, ipython_hidden=False):
|
||||
""" single variable or dictionary to xml representation """
|
||||
|
||||
is_exception_on_eval = isinstance(val, ExceptionOnEvaluate)
|
||||
@@ -256,6 +268,11 @@ def var_to_xml(val, name, doTrim=True, additionalInXml='', return_value=False):
|
||||
else:
|
||||
xmlRetVal = ''
|
||||
|
||||
if ipython_hidden:
|
||||
xmlIPythonHidden = ' isIPythonHidden="True"'
|
||||
else:
|
||||
xmlIPythonHidden = ''
|
||||
|
||||
xml = '<var name="%s" type="%s" ' % (make_valid_xml_value(name), make_valid_xml_value(typeName))
|
||||
|
||||
if type_qualifier:
|
||||
@@ -292,5 +309,5 @@ def var_to_xml(val, name, doTrim=True, additionalInXml='', return_value=False):
|
||||
else:
|
||||
xmlCont = ''
|
||||
|
||||
return ''.join((xml, xmlQualifier, xmlValue, xmlCont, xmlRetVal, additionalInXml, ' />\n'))
|
||||
return ''.join((xml, xmlQualifier, xmlValue, xmlCont, xmlRetVal, xmlIPythonHidden, additionalInXml, ' />\n'))
|
||||
|
||||
|
||||
@@ -355,6 +355,18 @@ def start_server(host, port, client_port):
|
||||
process_exec_queue(interpreter)
|
||||
|
||||
|
||||
def get_ipython_hidden_vars_dict():
|
||||
try:
|
||||
if IPYTHON and hasattr(__builtin__, 'interpreter'):
|
||||
pydev_interpreter = get_interpreter().interpreter
|
||||
if hasattr(pydev_interpreter, 'ipython') and hasattr(pydev_interpreter.ipython, 'user_ns_hidden'):
|
||||
return pydev_interpreter.ipython.user_ns_hidden
|
||||
return None
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return None
|
||||
|
||||
|
||||
def get_interpreter():
|
||||
try:
|
||||
interpreterInterface = getattr(__builtin__, 'interpreter')
|
||||
|
||||
@@ -27,6 +27,7 @@ public class PyDebugValue extends XNamedValue {
|
||||
private final String myValue;
|
||||
private final boolean myContainer;
|
||||
private final boolean myIsReturnedVal;
|
||||
private final boolean myIsIPythonHidden;
|
||||
private final PyDebugValue myParent;
|
||||
private String myId = null;
|
||||
|
||||
@@ -37,18 +38,20 @@ public class PyDebugValue extends XNamedValue {
|
||||
private final boolean myErrorOnEval;
|
||||
|
||||
public PyDebugValue(@NotNull final String name, final String type, String typeQualifier, final String value, final boolean container,
|
||||
boolean isReturnedVal, boolean errorOnEval, final PyFrameAccessor frameAccessor) {
|
||||
this(name, type, typeQualifier, value, container, isReturnedVal, errorOnEval, null, frameAccessor);
|
||||
boolean isReturnedVal, boolean isIPythonHidden, boolean errorOnEval, final PyFrameAccessor frameAccessor) {
|
||||
this(name, type, typeQualifier, value, container, isReturnedVal, isIPythonHidden, errorOnEval, null, frameAccessor);
|
||||
}
|
||||
|
||||
public PyDebugValue(@NotNull final String name, final String type, String typeQualifier, final String value, final boolean container,
|
||||
boolean isReturnedVal, boolean errorOnEval, final PyDebugValue parent, final PyFrameAccessor frameAccessor) {
|
||||
boolean isReturnedVal, boolean isIPythonHidden, boolean errorOnEval, final PyDebugValue parent,
|
||||
final PyFrameAccessor frameAccessor) {
|
||||
super(name);
|
||||
myType = type;
|
||||
myTypeQualifier = Strings.isNullOrEmpty(typeQualifier) ? null : typeQualifier;
|
||||
myValue = value;
|
||||
myContainer = container;
|
||||
myIsReturnedVal = isReturnedVal;
|
||||
myIsIPythonHidden = isIPythonHidden;
|
||||
myErrorOnEval = errorOnEval;
|
||||
myParent = parent;
|
||||
myFrameAccessor = frameAccessor;
|
||||
@@ -78,12 +81,17 @@ public class PyDebugValue extends XNamedValue {
|
||||
return myIsReturnedVal;
|
||||
}
|
||||
|
||||
public boolean isIPythonHidden() {
|
||||
return myIsIPythonHidden;
|
||||
}
|
||||
|
||||
public boolean isErrorOnEval() {
|
||||
return myErrorOnEval;
|
||||
}
|
||||
|
||||
public PyDebugValue setParent(@Nullable PyDebugValue parent) {
|
||||
return new PyDebugValue(myName, myType, myTypeQualifier, myValue, myContainer, myIsReturnedVal, myErrorOnEval, parent, myFrameAccessor);
|
||||
return new PyDebugValue(myName, myType, myTypeQualifier, myValue, myContainer, myIsReturnedVal, myIsIPythonHidden, myErrorOnEval,
|
||||
parent, myFrameAccessor);
|
||||
}
|
||||
|
||||
public PyDebugValue getParent() {
|
||||
@@ -237,8 +245,8 @@ public class PyDebugValue extends XNamedValue {
|
||||
}
|
||||
|
||||
public PyDebugValue setName(String newName) {
|
||||
PyDebugValue value = new PyDebugValue(newName, myType, myTypeQualifier, myValue, myContainer, myIsReturnedVal, myErrorOnEval, myParent,
|
||||
myFrameAccessor);
|
||||
PyDebugValue value = new PyDebugValue(newName, myType, myTypeQualifier, myValue, myContainer, myIsReturnedVal, myIsIPythonHidden,
|
||||
myErrorOnEval, myParent, myFrameAccessor);
|
||||
value.setTempName(myTempName);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class PyReferringObjectsValue extends PyDebugValue {
|
||||
String typeQualifier,
|
||||
String value,
|
||||
boolean container, boolean isReturnedVal, boolean errorOnEval, @NotNull PyFrameAccessor frameAccessor) {
|
||||
super(name, type, typeQualifier, value, container, isReturnedVal, errorOnEval, frameAccessor);
|
||||
super(name, type, typeQualifier, value, container, isReturnedVal, false, errorOnEval, frameAccessor);
|
||||
myReferrersLoader = frameAccessor.getReferrersLoader();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class GetFrameCommand extends AbstractFrameCommand {
|
||||
|
||||
protected PyDebugValue extend(final PyDebugValue value) {
|
||||
return new PyDebugValue(value.getName(), value.getType(), value.getTypeQualifier(), value.getValue(), value.isContainer(),
|
||||
value.isReturnedVal(), value.isErrorOnEval(), null, myDebugProcess);
|
||||
value.isReturnedVal(), value.isIPythonHidden(), value.isErrorOnEval(), null, myDebugProcess);
|
||||
}
|
||||
|
||||
public XValueChildrenList getVariables() {
|
||||
|
||||
@@ -51,7 +51,7 @@ public class GetVariableCommand extends GetFrameCommand {
|
||||
@Override
|
||||
protected PyDebugValue extend(final PyDebugValue value) {
|
||||
return new PyDebugValue(value.getName(), value.getType(), value.getTypeQualifier(), value.getValue(), value.isContainer(),
|
||||
value.isReturnedVal(), value.isErrorOnEval(), myParent,
|
||||
value.isReturnedVal(), value.isIPythonHidden(), value.isErrorOnEval(), myParent,
|
||||
myDebugProcess);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,6 +267,7 @@ public class ProtocolParser {
|
||||
String value = readString(reader, "value", null);
|
||||
final String isContainer = readString(reader, "isContainer", "");
|
||||
final String isReturnedValue = readString(reader, "isRetVal", "");
|
||||
final String isIPythonHidden = readString(reader, "isIPythonHidden", "");
|
||||
final String isErrorOnEval = readString(reader, "isErrorOnEval", "");
|
||||
|
||||
if (value.startsWith(type + ": ")) { // drop unneeded prefix
|
||||
@@ -274,7 +275,7 @@ public class ProtocolParser {
|
||||
}
|
||||
|
||||
return new PyDebugValue(name, type, qualifier, value, "True".equals(isContainer), "True".equals(isReturnedValue),
|
||||
"True".equals(isErrorOnEval), frameAccessor);
|
||||
"True".equals(isIPythonHidden), "True".equals(isErrorOnEval), frameAccessor);
|
||||
}
|
||||
|
||||
public static ArrayChunk parseArrayValues(final String text, final PyFrameAccessor frameAccessor) throws PyDebuggerException {
|
||||
@@ -293,7 +294,7 @@ public class ProtocolParser {
|
||||
result.setType(readString(reader, "type", null));
|
||||
result.setMax(readString(reader, "max", null));
|
||||
result.setMin(readString(reader, "min", null));
|
||||
result.setValue(new PyDebugValue(slice, null, null, null, false, false, false, frameAccessor));
|
||||
result.setValue(new PyDebugValue(slice, null, null, null, false, false, false, false, frameAccessor));
|
||||
reader.moveUp();
|
||||
}
|
||||
if ("headerdata".equals(reader.peekNextChild())) {
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PyDebuggerEvaluator extends XDebuggerEvaluator {
|
||||
|
||||
private static final PyDebugValue NONE = new PyDebugValue("", "NoneType", null, "None", false, false, false, null, null);
|
||||
private static final PyDebugValue NONE = new PyDebugValue("", "NoneType", null, "None", false, false, false, false, null, null);
|
||||
|
||||
private Project myProject;
|
||||
private final PyFrameAccessor myDebugProcess;
|
||||
|
||||
@@ -147,12 +147,16 @@ public class PyStackFrame extends XStackFrame {
|
||||
XValueChildrenList filteredChildren = new XValueChildrenList();
|
||||
final HashMap<String, XValue> returnedValues = new HashMap<>();
|
||||
final HashMap<String, XValue> specialValues = new HashMap<>();
|
||||
final HashMap<String, XValue> ipythonHidden = new HashMap<>();
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
XValue value = children.getValue(i);
|
||||
String name = children.getName(i);
|
||||
if ((value instanceof PyDebugValue) && ((PyDebugValue)value).isReturnedVal()) {
|
||||
returnedValues.put(name, value);
|
||||
}
|
||||
else if ((value instanceof PyDebugValue) && ((PyDebugValue)value).isIPythonHidden()) {
|
||||
ipythonHidden.put(name, value);
|
||||
}
|
||||
else if (name.startsWith(DOUBLE_UNDERSCORE) && (name.endsWith(DOUBLE_UNDERSCORE))) {
|
||||
specialValues.put(name, value);
|
||||
}
|
||||
@@ -160,13 +164,16 @@ public class PyStackFrame extends XStackFrame {
|
||||
filteredChildren.add(name, value);
|
||||
}
|
||||
}
|
||||
node.addChildren(filteredChildren, returnedValues.isEmpty() && specialValues.isEmpty());
|
||||
node.addChildren(filteredChildren, returnedValues.isEmpty() && specialValues.isEmpty() && ipythonHidden.isEmpty());
|
||||
if (!returnedValues.isEmpty()) {
|
||||
addReturnedValuesGroup(node, returnedValues);
|
||||
}
|
||||
if (!specialValues.isEmpty()) {
|
||||
addSpecialValuesGroup(node, specialValues);
|
||||
}
|
||||
if (!ipythonHidden.isEmpty()) {
|
||||
addIPythonVariablesGroup(node, ipythonHidden);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addReturnedValuesGroup(@NotNull final XCompositeNode node, Map<String, XValue> returnedValues) {
|
||||
@@ -211,6 +218,27 @@ public class PyStackFrame extends XStackFrame {
|
||||
node.addChildren(XValueChildrenList.topGroups(group), true);
|
||||
}
|
||||
|
||||
private static void addIPythonVariablesGroup(@NotNull final XCompositeNode node, Map<String, XValue> specialValues) {
|
||||
final ArrayList<XValueGroup> group = Lists.newArrayList();
|
||||
group.add(new XValueGroup("IPython Variables") {
|
||||
@Override
|
||||
public void computeChildren(@NotNull XCompositeNode node) {
|
||||
XValueChildrenList list = new XValueChildrenList();
|
||||
for (Map.Entry<String, XValue> entry : specialValues.entrySet()) {
|
||||
list.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
node.addChildren(list, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return PythonIcons.Python.Debug.SpecialVar;
|
||||
}
|
||||
});
|
||||
node.addChildren(XValueChildrenList.topGroups(group), true);
|
||||
}
|
||||
|
||||
public String getThreadId() {
|
||||
return myFrameInfo.getThreadId();
|
||||
}
|
||||
|
||||
+3
-3
@@ -204,7 +204,7 @@ public abstract class NumericContainerViewTable implements TableChunkDatasource
|
||||
PyDebugValue parent = value.getParent();
|
||||
final PyDebugValue slicedValue =
|
||||
new PyDebugValue(slice, value.getType(), null, value.getValue(), value.isContainer(), value.isReturnedVal(), value.isErrorOnEval(),
|
||||
parent, value.getFrameAccessor());
|
||||
value.isIPythonHidden(), parent, value.getFrameAccessor());
|
||||
|
||||
final String format = getFormat().isEmpty() ? "%" : getFormat();
|
||||
|
||||
@@ -227,8 +227,8 @@ public abstract class NumericContainerViewTable implements TableChunkDatasource
|
||||
public ArrayChunk getChunk(int rowOffset, int colOffset, int rows, int cols) throws PyDebuggerException {
|
||||
final PyDebugValue slicedValue =
|
||||
new PyDebugValue(getSliceText(), myValue.getType(), myValue.getTypeQualifier(), myValue.getValue(), myValue.isContainer(),
|
||||
myValue.isErrorOnEval(), myValue.isReturnedVal(),
|
||||
myValue.getParent(), myValue.getFrameAccessor());
|
||||
myValue.isErrorOnEval(), myValue.isReturnedVal(), myValue.isIPythonHidden(), myValue.getParent(),
|
||||
myValue.getFrameAccessor());
|
||||
|
||||
final String format = getFormat().isEmpty() ? "%" : getFormat();
|
||||
return myValue.getFrameAccessor().getArrayItems(slicedValue, rowOffset, colOffset, rows, cols, format);
|
||||
|
||||
Reference in New Issue
Block a user