From 2a2a175b2d5b71d0f8e10021cb628540d70582a8 Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 23 Jun 2016 15:35:22 +0300 Subject: [PATCH] Save returned values in dictionary in order to save complex names with dots (PY-19650) --- .../pydev/_pydevd_bundle/pydevd_constants.py | 2 +- .../pydev/_pydevd_bundle/pydevd_frame.py | 16 +++++++------- .../pydev/_pydevd_bundle/pydevd_xml.py | 21 ++++++++++++++----- .../python/debugger/PyDebugValue.java | 2 +- .../python/debugger/PyDebugProcess.java | 3 ++- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py index fcc06feeaa61..a2473e3456be 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py @@ -38,7 +38,7 @@ except AttributeError: #this value was raised from 200 to 1000. MAXIMUM_VARIABLE_REPRESENTATION_SIZE = 1000 # Prefix for saving functions return values in locals -RETURN_VALUES_PREFIX = '__pydevd_ret_val_' +RETURN_VALUES_DICT = '__pydevd_ret_val_dict' import os diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_frame.py b/python/helpers/pydev/_pydevd_bundle/pydevd_frame.py index b34c9f33b29d..214ad78cf08a 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_frame.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_frame.py @@ -11,7 +11,7 @@ from _pydevd_bundle.pydevd_breakpoints import get_exception_breakpoint from _pydevd_bundle.pydevd_comm import CMD_STEP_CAUGHT_EXCEPTION, CMD_STEP_RETURN, CMD_STEP_OVER, CMD_SET_BREAK, \ CMD_STEP_INTO, CMD_SMART_STEP_INTO, CMD_RUN_TO_LINE, CMD_SET_NEXT_STATEMENT, CMD_STEP_INTO_MY_CODE from _pydevd_bundle.pydevd_constants import STATE_SUSPEND, dict_contains, get_thread_id, STATE_RUN, dict_iter_values, IS_PY3K, \ - dict_keys, dict_pop, RETURN_VALUES_PREFIX + dict_keys, dict_pop, RETURN_VALUES_DICT from _pydevd_bundle.pydevd_dont_trace_files import DONT_TRACE, PYDEV_FILE from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame, just_raised from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame @@ -271,17 +271,17 @@ class PyDBFrame: # No longer cdef because object was dying when only a reference if event == "return" and hasattr(frame, "f_code") and hasattr(frame.f_code, "co_name"): name = frame.f_code.co_name if hasattr(frame, "f_back") and hasattr(frame.f_back, "f_locals"): - frame.f_back.f_locals[RETURN_VALUES_PREFIX + name] = arg + if RETURN_VALUES_DICT not in dict_keys(frame.f_back.f_locals): + frame.f_back.f_locals[RETURN_VALUES_DICT] = {} + frame.f_back.f_locals[RETURN_VALUES_DICT][name] = arg if main_debugger.remove_return_values_flag: # Showing return values was turned off, we should remove them from locals dict. # The values can be in the current frame or in the back one - for var_name in dict_keys(frame.f_locals): - if var_name.startswith(RETURN_VALUES_PREFIX): - dict_pop(frame.f_locals, var_name) + if RETURN_VALUES_DICT in dict_keys(frame.f_locals): + dict_pop(frame.f_locals, RETURN_VALUES_DICT) if hasattr(frame, "f_back") and hasattr(frame.f_back, "f_locals"): - for var_name in dict_keys(frame.f_back.f_locals): - if var_name.startswith(RETURN_VALUES_PREFIX): - dict_pop(frame.f_back.f_locals, var_name) + if RETURN_VALUES_DICT in dict_keys(frame.f_back.f_locals): + dict_pop(frame.f_back.f_locals, RETURN_VALUES_DICT) main_debugger.remove_return_values_flag = False except: main_debugger.remove_return_values_flag = False diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py b/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py index 263047cfa085..284ab1bac3d4 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py @@ -153,13 +153,22 @@ def get_type(o): #no match return default return (type_object, type_name, pydevd_resolver.defaultResolver) + +def return_values_from_dict_to_xml(return_dict): + res = "" + for name in dict_keys(return_dict): + val = return_dict[name] + res += var_to_xml(val, name, return_value=True) + return res + + def frame_vars_to_xml(frame_f_locals): """ dumps frame variables to XML """ xml = "" - keys = frame_f_locals.keys() + keys = dict_keys(frame_f_locals) if hasattr(keys, 'sort'): keys.sort() #Python 3.0 does not have it else: @@ -168,7 +177,10 @@ def frame_vars_to_xml(frame_f_locals): for k in keys: try: v = frame_f_locals[k] - xml += var_to_xml(v, str(k)) + if k == RETURN_VALUES_DICT: + xml += return_values_from_dict_to_xml(v) + else: + xml += var_to_xml(v, str(k)) except Exception: traceback.print_exc() pydev_log.error("Unexpected error, recovered safely.\n") @@ -179,7 +191,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=''): +def var_to_xml(val, name, doTrim=True, additionalInXml='', return_value=False): """ single variable or dictionary to xml representation """ is_exception_on_eval = isinstance(val, ExceptionOnEvaluate) @@ -239,8 +251,7 @@ def var_to_xml(val, name, doTrim=True, additionalInXml=''): except: pass - if name.startswith(RETURN_VALUES_PREFIX): - name = name.split(RETURN_VALUES_PREFIX)[1] + if return_value: xmlRetVal = ' isRetVal="True"' else: xmlRetVal = '' diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java index b2a23241e35e..d4ee75be0f91 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java @@ -19,7 +19,7 @@ public class PyDebugValue extends XNamedValue { private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.pydev.PyDebugValue"); public static final int MAX_VALUE = 256; - public static final String RETURN_VALUES_PREFIX = "__pydevd_ret_val_"; + public static final String RETURN_VALUES_PREFIX = "__pydevd_ret_val_dict"; private String myTempName = null; private final String myType; diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index 3570746593d0..040c8f52eacf 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -685,7 +685,8 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr final PyStackFrame frame = currentFrame(); PyDebugValue debugValue = var; if (var.isReturnedVal()) { - debugValue = var.setName(PyDebugValue.RETURN_VALUES_PREFIX + var.getName()); + // return values are saved in dictionary on Python side, so the variable's name should be transformed + debugValue = var.setName(PyDebugValue.RETURN_VALUES_PREFIX + "[\"" + var.getName() + "\"]"); } return myDebugger.loadVariable(frame.getThreadId(), frame.getFrameId(), debugValue); }