From ad85d8d74429d3a4bd9a39bff5a7ca9bcd6d27ed Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 30 May 2019 19:26:46 +0300 Subject: [PATCH] IDEA-CR-48239: PY-33794 Jupyter Inline Values GitOrigin-RevId: bb4427cd03b8f30676dfc77a0f6a4859b047b221 --- .../pydev/_pydevd_bundle/pydevd_xml.py | 11 +++++++- .../python/debugger/PyDebugValue.java | 28 +++++++++++++++++-- .../debugger/PyReferringObjectsValue.java | 10 +++++-- .../python/debugger/pydev/ProtocolParser.java | 7 +++-- .../console/PydevConsoleCommunicationUtil.kt | 4 +-- .../python/debugger/PyDebuggerEvaluator.java | 2 +- 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py b/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py index 4ab5a8f81d22..69b604a108a1 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py @@ -244,6 +244,10 @@ def is_numpy(x): or 'float' in type_name or 'complex' in type_name +def is_numeric_container(var_type): + return var_type in ("ndarray", "DataFrame", "Series") + + def should_evaluate_full_value(val): return LOAD_VALUES_POLICY == ValuesPolicy.SYNC or ((is_builtin(type(val)) or is_numpy(type(val))) and not isinstance(val, (list, tuple, dict, set, frozenset))) @@ -376,6 +380,11 @@ def var_to_xml(val, name, doTrim=True, additional_in_xml='', evaluate_full_value else: xml_value = '' + if is_numeric_container(typeName): + xml_shape = ' shape="%s"' % make_valid_xml_value(str(v.shape)) + else: + xml_shape = '' + if is_exception_on_eval: xml_container = ' isErrorOnEval="True"' else: @@ -384,5 +393,5 @@ def var_to_xml(val, name, doTrim=True, additional_in_xml='', evaluate_full_value else: xml_container = '' - return ''.join((xml, xml_qualifier, xml_value, xml_container, additional_in_xml, ' />\n')) + return ''.join((xml, xml_qualifier, xml_value, xml_container, xml_shape, additional_in_xml, ' />\n')) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java index 7fafd384f24d..d4785551b1ae 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java @@ -36,6 +36,7 @@ public class PyDebugValue extends XNamedValue { private final @Nullable String myTypeQualifier; private @Nullable String myValue; private final boolean myContainer; + private final @Nullable String myShape; private final boolean myIsReturnedVal; private final boolean myIsIPythonHidden; private @Nullable PyDebugValue myParent; @@ -64,18 +65,35 @@ public class PyDebugValue extends XNamedValue { @Nullable String typeQualifier, @Nullable final String value, final boolean container, + @Nullable String shape, boolean isReturnedVal, boolean isIPythonHidden, boolean errorOnEval, @NotNull final PyFrameAccessor frameAccessor) { - this(name, type, typeQualifier, value, container, isReturnedVal, isIPythonHidden, errorOnEval, null, frameAccessor); + this(name, type, typeQualifier, value, container, shape, isReturnedVal, isIPythonHidden, errorOnEval, null, frameAccessor); } + /** + * Represents instance of a Python variable available at runtime. Used in Debugger and various Variable Viewers + * + * @param name variable name + * @param type variable type + * @param typeQualifier type qualifier + * @param value string representation of a value + * @param container does variable have fields for expanding + * @param shape variable's shape field (available for numeric containers) + * @param isReturnedVal is value was returned from a function during debug session + * @param isIPythonHidden does value belong to IPython util variables group + * @param errorOnEval did an error occur during evaluation + * @param parent parent variable in Variables tree + * @param frameAccessor frame accessor used for evaluation + */ public PyDebugValue(@NotNull final String name, @Nullable final String type, @Nullable String typeQualifier, @Nullable final String value, final boolean container, + @Nullable String shape, boolean isReturnedVal, boolean isIPythonHidden, boolean errorOnEval, @@ -86,6 +104,7 @@ public class PyDebugValue extends XNamedValue { myTypeQualifier = Strings.isNullOrEmpty(typeQualifier) ? null : typeQualifier; myValue = value; myContainer = container; + myShape = shape; myIsReturnedVal = isReturnedVal; myIsIPythonHidden = isIPythonHidden; myErrorOnEval = errorOnEval; @@ -99,7 +118,7 @@ public class PyDebugValue extends XNamedValue { } public PyDebugValue(@NotNull PyDebugValue value, @NotNull String newName) { - this(newName, value.getType(), value.getTypeQualifier(), value.getValue(), value.isContainer(), value.isReturnedVal(), + this(newName, value.getType(), value.getTypeQualifier(), value.getValue(), value.isContainer(), value.getShape(), value.isReturnedVal(), value.isIPythonHidden(), value.isErrorOnEval(), value.getParent(), value.getFrameAccessor()); myOffset = value.getOffset(); setLoadValuePolicy(value.getLoadValuePolicy()); @@ -137,6 +156,11 @@ public class PyDebugValue extends XNamedValue { return myContainer; } + @Nullable + public String getShape() { + return myShape; + } + public boolean isReturnedVal() { return myIsReturnedVal; } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java b/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java index b834ad74f8c1..6527f29ed3d7 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PyReferringObjectsValue.java @@ -30,14 +30,18 @@ public class PyReferringObjectsValue extends PyDebugValue { String type, String typeQualifier, String value, - boolean container, boolean isReturnedVal, boolean errorOnEval, @NotNull PyFrameAccessor frameAccessor) { - super(name, type, typeQualifier, value, container, isReturnedVal, false, errorOnEval, frameAccessor); + boolean container, + String shape, + boolean isReturnedVal, + boolean errorOnEval, + @NotNull PyFrameAccessor frameAccessor) { + super(name, type, typeQualifier, value, container, shape, isReturnedVal, false, errorOnEval, frameAccessor); myReferrersLoader = frameAccessor.getReferrersLoader(); } public PyReferringObjectsValue(PyDebugValue debugValue) { this(debugValue.getName(), debugValue.getType(), debugValue.getTypeQualifier(), debugValue.getValue(), debugValue.isContainer(), - debugValue.isReturnedVal(), debugValue.isErrorOnEval(), debugValue.getFrameAccessor()); + debugValue.getShape(), debugValue.isReturnedVal(), debugValue.isErrorOnEval(), debugValue.getFrameAccessor()); } @Override diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java index d6f467f37e47..8e8a164bf6b8 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java @@ -276,12 +276,13 @@ public class ProtocolParser { final String isReturnedValue = readString(reader, "isRetVal", ""); final String isIPythonHidden = readString(reader, "isIPythonHidden", ""); final String isErrorOnEval = readString(reader, "isErrorOnEval", ""); + String shape = readString(reader, "shape", ""); if (value.startsWith(type + ": ")) { // drop unneeded prefix value = value.substring(type.length() + 2); } - - return new PyDebugValue(name, type, qualifier, value, "True".equals(isContainer), "True".equals(isReturnedValue), + if (shape.isEmpty()) shape = null; + return new PyDebugValue(name, type, qualifier, value, "True".equals(isContainer), shape, "True".equals(isReturnedValue), "True".equals(isIPythonHidden), "True".equals(isErrorOnEval), frameAccessor); } @@ -301,7 +302,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, false, frameAccessor)); + result.setValue(new PyDebugValue(slice, null, null, null, false, null, false, false, false, frameAccessor)); reader.moveUp(); } if ("headerdata".equals(reader.peekNextChild())) { diff --git a/python/src/com/jetbrains/python/console/PydevConsoleCommunicationUtil.kt b/python/src/com/jetbrains/python/console/PydevConsoleCommunicationUtil.kt index ae96de77f9c7..f1230b977dec 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleCommunicationUtil.kt +++ b/python/src/com/jetbrains/python/console/PydevConsoleCommunicationUtil.kt @@ -25,7 +25,7 @@ fun parseVars(vars: List, parent: PyDebugValue?, frameAccessor: PyFr fun createPyDebugValue(value: DebugValue, frameAccessor: PyFrameAccessor) = PyDebugValue(value.name, value.type, value.qualifier, value.value ?: "", - value.isContainer, value.isReturnedValue, value.isIPythonHidden, value.isErrorOnEval, + value.isContainer, null, value.isReturnedValue, value.isIPythonHidden, value.isErrorOnEval, frameAccessor) fun createArrayChunk(response: GetArrayResponse, frameAccessor: PyFrameAccessor): ArrayChunk { @@ -40,7 +40,7 @@ fun createArrayChunk(response: GetArrayResponse, frameAccessor: PyFrameAccessor) result.setType(response.type) result.setMax(response.max) result.setMin(response.min) - result.setValue(PyDebugValue(response.slice, null, null, null, false, false, false, false, frameAccessor)) + result.setValue(PyDebugValue(response.slice, null, null, null, false, null, false, false, false, frameAccessor)) // `parseArrayHeaderData()` diff --git a/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java b/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java index f1ffb867525c..b8d3b9f5a7f6 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java +++ b/python/src/com/jetbrains/python/debugger/PyDebuggerEvaluator.java @@ -42,7 +42,7 @@ public class PyDebuggerEvaluator extends XDebuggerEvaluator { } private PyDebugValue getNone() { - return new PyDebugValue("", "NoneType", null, "None", false, false, false, false, null, myDebugProcess); + return new PyDebugValue("", "NoneType", null, "None", false, null, false, false, false, null, myDebugProcess); } private void doEvaluate(final String expr, final XEvaluationCallback callback, final boolean doTrunc) {