diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py
index d66c72c4e346..7ce1af7ecf5b 100644
--- a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py
+++ b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py
@@ -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 += pydevd_xml.frame_vars_to_xml(frame.f_locals)
+ xml += pydevd_vars.frame_vars_to_xml(frame.f_locals, hidden_ns)
del frame
xml += ""
cmd = dbg.cmd_factory.make_get_frame_message(self.sequence, xml)
diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py b/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py
index 7c1a87b3c891..35c6c242288c 100644
--- a/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py
+++ b/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py
@@ -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
"""
@@ -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 = '\n'))
+ return ''.join((xml, xmlQualifier, xmlValue, xmlCont, xmlRetVal, xmlIPythonHidden, additionalInXml, ' />\n'))
diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py
index aa0f44107e42..05a2584b3c71 100644
--- a/python/helpers/pydev/pydevconsole.py
+++ b/python/helpers/pydev/pydevconsole.py
@@ -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')
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java
index d4191713c53a..5737592904ed 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java
@@ -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;
}
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java b/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java
index 0225e8fb7538..b834ad74f8c1 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java
@@ -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();
}
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetFrameCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetFrameCommand.java
index 96f687b46bd0..e9ac6b810f01 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetFrameCommand.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetFrameCommand.java
@@ -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() {
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetVariableCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetVariableCommand.java
index 0a62af8eee80..6acf73d8dd0a 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetVariableCommand.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/GetVariableCommand.java
@@ -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);
}
}
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java
index fc6635826465..f22ed618c0f9 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java
@@ -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())) {
diff --git a/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java b/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java
index ab732a6807c6..989dee3fa1a9 100644
--- a/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java
+++ b/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java
@@ -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;
diff --git a/python/src/com/jetbrains/python/debugger/PyStackFrame.java b/python/src/com/jetbrains/python/debugger/PyStackFrame.java
index 549ab26263bc..cfe71ec79a7b 100644
--- a/python/src/com/jetbrains/python/debugger/PyStackFrame.java
+++ b/python/src/com/jetbrains/python/debugger/PyStackFrame.java
@@ -147,12 +147,16 @@ public class PyStackFrame extends XStackFrame {
XValueChildrenList filteredChildren = new XValueChildrenList();
final HashMap returnedValues = new HashMap<>();
final HashMap specialValues = new HashMap<>();
+ final HashMap 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 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 specialValues) {
+ final ArrayList group = Lists.newArrayList();
+ group.add(new XValueGroup("IPython Variables") {
+ @Override
+ public void computeChildren(@NotNull XCompositeNode node) {
+ XValueChildrenList list = new XValueChildrenList();
+ for (Map.Entry 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();
}
diff --git a/python/src/com/jetbrains/python/debugger/containerview/NumericContainerViewTable.java b/python/src/com/jetbrains/python/debugger/containerview/NumericContainerViewTable.java
index 263b69daf670..8fd33a7035cc 100644
--- a/python/src/com/jetbrains/python/debugger/containerview/NumericContainerViewTable.java
+++ b/python/src/com/jetbrains/python/debugger/containerview/NumericContainerViewTable.java
@@ -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);