Save returned values in dictionary in order to save complex names with dots (PY-19650)

This commit is contained in:
Elizaveta Shashkova
2016-06-28 15:32:23 +03:00
parent be6ea9977b
commit 2a2a175b2d
5 changed files with 28 additions and 16 deletions
@@ -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
@@ -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
@@ -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
<var name="var_name" scope="local" type="type" value="value"/>
"""
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 = ''
@@ -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;
@@ -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);
}