예제 #1
0
def resolve_compound_var_object_fields(var, attrs, user_type_renderers={}):
    """
    Resolve compound variable by its object and attributes

    :param var: an object of variable
    :param attrs: a sequence of variable's attributes separated by \t (i.e.: obj\tattr1\tattr2)
    :param user_type_renderers: a dictionary with user type renderers
    :return: a dictionary of variables's fields
    """
    namespace = var

    offset = get_offset(attrs)

    attrs = attrs.split('\t', 1)[1] if offset else attrs

    attr_list = attrs.split('\t')

    var_expr = ".".join(attr_list)

    for k in attr_list:
        type, _typeName, resolver = get_type(var)
        var = resolver.resolve(var, k)

    try:
        type, _typeName, resolver = get_type(var)

        type_renderer = try_get_type_renderer_for_var(var, user_type_renderers)
        if type_renderer is not None and offset == 0:
            return _resolve_custom_variable_fields(var, var_expr, resolver,
                                                   offset, type_renderer)

        return _resolve_default_variable_fields(var, resolver, offset)
    except:
        traceback.print_exc()
예제 #2
0
def resolve_var(var, attrs):
    attrList = attrs.split('\t')

    for k in attrList:
        type, _typeName, resolver = get_type(var)

        var = resolver.resolve(var, k)

    try:
        type, _typeName, resolver = get_type(var)
        return resolver.get_dictionary(var)
    except:
        traceback.print_exc()
예제 #3
0
def resolve_var(var, attrs):
    attrList = attrs.split('\t')

    for k in attrList:
        type, _typeName, resolver = get_type(var)

        var = resolver.resolve(var, k)

    try:
        type, _typeName, resolver = get_type(var)
        return resolver.get_dictionary(var)
    except:
        traceback.print_exc()
예제 #4
0
def table_like_struct_to_xml(array, name, roffset, coffset, rows, cols, format):
    _, type_name, _ = get_type(array)
    format = format if is_able_to_format_number(format) else '%'
    if type_name in TYPE_TO_XML_CONVERTERS:
        return "<xml>%s</xml>" % TYPE_TO_XML_CONVERTERS[type_name](array, name, roffset, coffset, rows, cols, format)
    else:
        raise VariableError("type %s not supported" % type_name)
예제 #5
0
    def get_children_variables(self, fmt=None):
        _type, _type_name, resolver = get_type(self.value)

        children_variables = []
        if resolver is not None:  # i.e.: it's a container.
            if hasattr(resolver, 'get_contents_debug_adapter_protocol'):
                # The get_contents_debug_adapter_protocol needs to return sorted.
                lst = resolver.get_contents_debug_adapter_protocol(self.value, fmt=fmt)
            else:
                # If there's no special implementation, the default is sorting the keys.
                dct = resolver.get_dictionary(self.value)
                lst = dict_items(dct)
                lst.sort(key=lambda tup: sorted_attributes_key(tup[0]))
                # No evaluate name in this case.
                lst = [(key, value, None) for (key, value) in lst]

            parent_evaluate_name = self.evaluate_name
            if parent_evaluate_name:
                for key, val, evaluate_name in lst:
                    if evaluate_name is not None:
                        if callable(evaluate_name):
                            evaluate_name = evaluate_name(parent_evaluate_name)
                        else:
                            evaluate_name = parent_evaluate_name + evaluate_name
                    variable = _ObjectVariable(
                        key, val, self._register_variable, evaluate_name=evaluate_name, frame=self.frame)
                    children_variables.append(variable)
            else:
                for key, val, evaluate_name in lst:
                    # No evaluate name
                    variable = _ObjectVariable(key, val, self._register_variable, frame=self.frame)
                    children_variables.append(variable)

        return children_variables
예제 #6
0
def resolve_compound_variable_fields(thread_id, frame_id, scope, attrs):
    """
    Resolve compound variable in debugger scopes by its name and attributes

    :param thread_id: id of the variable's thread
    :param frame_id: id of the variable's frame
    :param scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME
    :param attrs: after reaching the proper scope, we have to get the attributes until we find
            the proper location (i.e.: obj\tattr1\tattr2)
    :return: a dictionary of variables's fields
    """

    var = getVariable(thread_id, frame_id, scope, attrs)

    try:
        _type, _typeName, resolver = get_type(var)
        return _typeName, resolver.get_dictionary(var)
    except:
        sys.stderr.write(
            'Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s\n'
            % (
                thread_id,
                frame_id,
                scope,
                attrs,
            ))
        traceback.print_exc()
예제 #7
0
    def get_children_variables(self, fmt=None):
        _type, _type_name, resolver = get_type(self.value)

        children_variables = []
        if resolver is not None:  # i.e.: it's a container.
            if hasattr(resolver, 'get_contents_debug_adapter_protocol'):
                # The get_contents_debug_adapter_protocol needs to return sorted.
                lst = resolver.get_contents_debug_adapter_protocol(self.value, fmt=fmt)
            else:
                # If there's no special implementation, the default is sorting the keys.
                dct = resolver.get_dictionary(self.value)
                lst = dict_items(dct)
                lst.sort(key=lambda tup: sorted_attributes_key(tup[0]))
                # No evaluate name in this case.
                lst = [(key, value, None) for (key, value) in lst]

            parent_evaluate_name = self.evaluate_name
            if parent_evaluate_name:
                for key, val, evaluate_name in lst:
                    if evaluate_name is not None:
                        if callable(evaluate_name):
                            evaluate_name = evaluate_name(parent_evaluate_name)
                        else:
                            evaluate_name = parent_evaluate_name + evaluate_name
                    variable = _ObjectVariable(
                        key, val, self._register_variable, evaluate_name=evaluate_name)
                    children_variables.append(variable)
            else:
                for key, val, evaluate_name in lst:
                    # No evaluate name
                    variable = _ObjectVariable(key, val, self._register_variable)
                    children_variables.append(variable)

        return children_variables
예제 #8
0
def resolve_compound_variable_fields(thread_id, frame_id, scope, attrs):
    """
    Resolve compound variable in debugger scopes by its name and attributes

    :param thread_id: id of the variable's thread
    :param frame_id: id of the variable's frame
    :param scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME
    :param attrs: after reaching the proper scope, we have to get the attributes until we find
            the proper location (i.e.: obj\tattr1\tattr2)
    :return: a dictionary of variables's fields

    :note: PyCharm supports progressive loading of large collections and uses the `attrs`
           parameter to pass the offset, e.g. 300\t\obj\tattr1\tattr2 should return
           the value of attr2 starting from the 300th element. This hack makes it possible
           to add the support of progressive loading without extending of the protocol.
    """
    offset = get_offset(attrs)

    orig_attrs, attrs = attrs, attrs.split('\t', 1)[1] if offset else attrs

    var = getVariable(thread_id, frame_id, scope, attrs)

    try:
        _type, _typeName, resolver = get_type(var)
        return _typeName, resolver.get_dictionary(VariableWithOffset(var, offset) if offset else var)
    except:
        sys.stderr.write('Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s\n' % (
            thread_id, frame_id, scope, orig_attrs,))
        traceback.print_exc()
예제 #9
0
def resolve_compound_variable_fields(thread_id, frame_id, scope, attrs):
    """
    Resolve compound variable in debugger scopes by its name and attributes

    :param thread_id: id of the variable's thread
    :param frame_id: id of the variable's frame
    :param scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME
    :param attrs: after reaching the proper scope, we have to get the attributes until we find
            the proper location (i.e.: obj\tattr1\tattr2)
    :return: a dictionary of variables's fields

    :note: PyCharm supports progressive loading of large collections and uses the `attrs`
           parameter to pass the offset, e.g. 300\t\\obj\tattr1\tattr2 should return
           the value of attr2 starting from the 300th element. This hack makes it possible
           to add the support of progressive loading without extending of the protocol.
    """
    offset = get_offset(attrs)

    orig_attrs, attrs = attrs, attrs.split('\t', 1)[1] if offset else attrs

    var = getVariable(thread_id, frame_id, scope, attrs)

    try:
        _type, _typeName, resolver = get_type(var)
        return _typeName, resolver.get_dictionary(VariableWithOffset(var, offset) if offset else var)
    except:
        sys.stderr.write('Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s\n' % (
            thread_id, frame_id, scope, orig_attrs,))
        traceback.print_exc()
예제 #10
0
def resolve_compound_var_object_fields(var, attrs):
    """
    Resolve compound variable by its object and attributes

    :param var: an object of variable
    :param attrs: a sequence of variable's attributes separated by \t (i.e.: obj\tattr1\tattr2)
    :return: a dictionary of variables's fields
    """
    attr_list = attrs.split('\t')

    for k in attr_list:
        type, _type_name, resolver = get_type(var)
        var = resolver.resolve(var, k)

    try:
        type, _type_name, resolver = get_type(var)
        return resolver.get_dictionary(var)
    except:
        pydev_log.exception()
예제 #11
0
def resolve_compound_var_object_fields(var, attrs):
    """
    Resolve compound variable by its object and attributes

    :param var: an object of variable
    :param attrs: a sequence of variable's attributes separated by \t (i.e.: obj\tattr1\tattr2)
    :return: a dictionary of variables's fields
    """
    attr_list = attrs.split('\t')

    for k in attr_list:
        type, _typeName, resolver = get_type(var)
        var = resolver.resolve(var, k)

    try:
        type, _typeName, resolver = get_type(var)
        return resolver.get_dictionary(var)
    except:
        traceback.print_exc()
예제 #12
0
def resolve_compound_variable(thread_id, frame_id, scope, attrs):
    """ returns the value of the compound variable as a dictionary"""

    var = getVariable(thread_id, frame_id, scope, attrs)

    try:
        _type, _typeName, resolver = get_type(var)
        return resolver.get_dictionary(var)
    except:
        sys.stderr.write('Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s\n' % (
            thread_id, frame_id, scope, attrs,))
        traceback.print_exc()
예제 #13
0
def resolve_compound_variable(thread_id, frame_id, scope, attrs):
    """ returns the value of the compound variable as a dictionary"""

    var = getVariable(thread_id, frame_id, scope, attrs)

    try:
        _type, _typeName, resolver = get_type(var)
        return _typeName, resolver.get_dictionary(var)
    except:
        sys.stderr.write('Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s\n' % (
            thread_id, frame_id, scope, attrs,))
        traceback.print_exc()
예제 #14
0
def resolve_compound_var_object_fields(var, attrs):
    """
    Resolve compound variable by its object and attributes

    :param var: an object of variable
    :param attrs: a sequence of variable's attributes separated by \t (i.e.: obj\tattr1\tattr2)
    :return: a dictionary of variables's fields
    """
    offset = get_offset(attrs)

    attrs = attrs.split('\t', 1)[1] if offset else attrs

    attr_list = attrs.split('\t')

    for k in attr_list:
        type, _typeName, resolver = get_type(var)
        var = resolver.resolve(var, k)

    try:
        type, _typeName, resolver = get_type(var)
        return resolver.get_dictionary(VariableWithOffset(var, offset) if offset else var)
    except:
        traceback.print_exc()
예제 #15
0
def test_object_resolver_hasattr_error():
    from _pydevd_bundle.pydevd_resolver import DefaultResolver
    from _pydevd_bundle.pydevd_xml import get_type
    default_resolver = DefaultResolver()

    class MyObject(object):
        def __getattribute__(self, attr_name):
            raise RuntimeError()

    obj = MyObject()
    dictionary = default_resolver.get_dictionary(obj)
    assert dictionary == {}

    _type_object, type_name, _resolver = get_type(obj)
    assert type_name == 'MyObject'
예제 #16
0
def table_like_struct_to_xml(array, name, roffset, coffset, rows, cols, format):
    _, type_name, _ = get_type(array)
    if type_name == 'ndarray':
        array, metaxml, r, c, f = array_to_meta_xml(array, name, format)
        xml = metaxml
        format = '%' + f
        if rows == -1 and cols == -1:
            rows = r
            cols = c
        xml += array_to_xml(array, roffset, coffset, rows, cols, format)
    elif type_name == 'DataFrame':
        xml = dataframe_to_xml(array, name, roffset, coffset, rows, cols, format)
    else:
        raise VariableError("Do not know how to convert type %s to table" % (type_name))

    return "<xml>%s</xml>" % xml
예제 #17
0
def resolve_var_object(var, attrs):
    """
    Resolve variable's attribute

    :param var: an object of variable
    :param attrs: a sequence of variable's attributes separated by \t (i.e.: obj\tattr1\tattr2)
    :return: a value of resolved variable's attribute
    """
    if attrs is not None:
        attr_list = attrs.split('\t')
    else:
        attr_list = []
    for k in attr_list:
        type, _typeName, resolver = get_type(var)
        var = resolver.resolve(var, k)
    return var
예제 #18
0
def resolve_var_object(var, attrs):
    """
    Resolve variable's attribute

    :param var: an object of variable
    :param attrs: a sequence of variable's attributes separated by \t (i.e.: obj\tattr1\tattr2)
    :return: a value of resolved variable's attribute
    """
    if attrs is not None:
        attr_list = attrs.split('\t')
    else:
        attr_list = []
    for k in attr_list:
        type, _type_name, resolver = get_type(var)
        var = resolver.resolve(var, k)
    return var
예제 #19
0
def table_like_struct_to_xml(array, name, roffset, coffset, rows, cols, format):
    _, type_name, _ = get_type(array)
    if type_name == 'ndarray':
        array, metaxml, r, c, f = array_to_meta_xml(array, name, format)
        xml = metaxml
        format = '%' + f
        if rows == -1 and cols == -1:
            rows = r
            cols = c
        xml += array_to_xml(array, roffset, coffset, rows, cols, format)
    elif type_name == 'DataFrame':
        xml = dataframe_to_xml(array, name, roffset, coffset, rows, cols, format)
    else:
        raise VariableError("Do not know how to convert type %s to table" % (type_name))

    return "<xml>%s</xml>" % xml
    def change_variable(self, name, value, py_db, fmt=None):

        children_variable = self.get_child_variable_named(name)
        if children_variable is None:
            return None

        var_data = children_variable.get_var_data()
        evaluate_name = var_data.get('evaluateName')

        if not evaluate_name:
            # Note: right now we only pass control to the resolver in the cases where
            # there's no evaluate name (the idea being that if we can evaluate it,
            # we can use that evaluation to set the value too -- if in the future
            # a case where this isn't true is found this logic may need to be changed).
            _type, _type_name, container_resolver = get_type(self.value)
            if hasattr(container_resolver, 'change_var_from_name'):
                try:
                    new_value = eval(value)
                except:
                    return None
                new_key = container_resolver.change_var_from_name(
                    self.value, name, new_value)
                if new_key is not None:
                    return _ObjectVariable(self.py_db,
                                           new_key,
                                           new_value,
                                           self._register_variable,
                                           evaluate_name=None,
                                           frame=self.frame)

                return None
            else:
                return None

        frame = self.frame
        if frame is None:
            return None

        try:
            # This handles the simple cases (such as dict, list, object)
            Exec('%s=%s' % (evaluate_name, value), frame.f_globals,
                 frame.f_locals)
        except:
            return None

        return self.get_child_variable_named(name, fmt=fmt)
예제 #21
0
def resolve_compound_variable_fields(thread_id, frame_id, scope, attrs):
    """
    Resolve compound variable in debugger scopes by its name and attributes

    :param thread_id: id of the variable's thread
    :param frame_id: id of the variable's frame
    :param scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME
    :param attrs: after reaching the proper scope, we have to get the attributes until we find
            the proper location (i.e.: obj\tattr1\tattr2)
    :return: a dictionary of variables's fields
    """

    var = getVariable(thread_id, frame_id, scope, attrs)

    try:
        _type, _typeName, resolver = get_type(var)
        return _typeName, resolver.get_dictionary(var)
    except:
        sys.stderr.write('Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s\n' % (
            thread_id, frame_id, scope, attrs,))
        traceback.print_exc()
    def change_variable(self, name, value, py_db, fmt=None):

        children_variable = self.get_child_variable_named(name)
        if children_variable is None:
            return None

        var_data = children_variable.get_var_data()
        evaluate_name = var_data.get('evaluateName')

        if not evaluate_name:
            # Note: right now we only pass control to the resolver in the cases where
            # there's no evaluate name (the idea being that if we can evaluate it,
            # we can use that evaluation to set the value too -- if in the future
            # a case where this isn't true is found this logic may need to be changed).
            _type, _type_name, container_resolver = get_type(self.value)
            if hasattr(container_resolver, 'change_var_from_name'):
                try:
                    new_value = eval(value)
                except:
                    return None
                new_key = container_resolver.change_var_from_name(self.value, name, new_value)
                if new_key is not None:
                    return _ObjectVariable(
                        new_key, new_value, self._register_variable, evaluate_name=None, frame=self.frame)

                return None
            else:
                return None

        frame = self.frame
        if frame is None:
            return None

        try:
            # This handles the simple cases (such as dict, list, object)
            Exec('%s=%s' % (evaluate_name, value), frame.f_globals, frame.f_locals)
        except:
            return None

        return self.get_child_variable_named(name, fmt=fmt)
예제 #23
0
def getVariable(thread_id, frame_id, scope, attrs):
    """
    returns the value of a variable

    :scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME

    BY_ID means we'll traverse the list of all objects alive to get the object.

    :attrs: after reaching the proper scope, we have to get the attributes until we find
            the proper location (i.e.: obj\tattr1\tattr2)

    :note: when BY_ID is used, the frame_id is considered the id of the object to find and
           not the frame (as we don't care about the frame in this case).
    """
    if scope == 'BY_ID':
        if thread_id != get_thread_id(threading.currentThread()):
            raise VariableError("getVariable: must execute on same thread")

        try:
            import gc
            objects = gc.get_objects()
        except:
            pass  # Not all python variants have it.
        else:
            frame_id = int(frame_id)
            for var in objects:
                if id(var) == frame_id:
                    if attrs is not None:
                        attrList = attrs.split('\t')
                        for k in attrList:
                            _type, _typeName, resolver = get_type(var)
                            var = resolver.resolve(var, k)

                    return var

        # If it didn't return previously, we coudn't find it by id (i.e.: alrceady garbage collected).
        sys.stderr.write('Unable to find object with id: %s\n' % (frame_id,))
        return None

    frame = find_frame(thread_id, frame_id)
    if frame is None:
        return {}

    if attrs is not None:
        attrList = attrs.split('\t')
    else:
        attrList = []

    for attr in attrList:
        attr.replace("@_@TAB_CHAR@_@", '\t')

    if scope == 'EXPRESSION':
        for count in xrange(len(attrList)):
            if count == 0:
                # An Expression can be in any scope (globals/locals), therefore it needs to evaluated as an expression
                var = evaluate_expression(thread_id, frame_id, attrList[count], False)
            else:
                _type, _typeName, resolver = get_type(var)
                var = resolver.resolve(var, attrList[count])
    else:
        if scope == "GLOBAL":
            var = frame.f_globals
            del attrList[0]  # globals are special, and they get a single dummy unused attribute
        else:
            # in a frame access both locals and globals as Python does
            var = {}
            var.update(frame.f_globals)
            var.update(frame.f_locals)

        for k in attrList:
            _type, _typeName, resolver = get_type(var)
            var = resolver.resolve(var, k)

    return var
예제 #24
0
def getVariable(dbg, thread_id, frame_id, scope, attrs):
    """
    returns the value of a variable

    :scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME

    BY_ID means we'll traverse the list of all objects alive to get the object.

    :attrs: after reaching the proper scope, we have to get the attributes until we find
            the proper location (i.e.: obj\tattr1\tattr2)

    :note: when BY_ID is used, the frame_id is considered the id of the object to find and
           not the frame (as we don't care about the frame in this case).
    """
    if scope == 'BY_ID':
        if thread_id != get_current_thread_id(threading.current_thread()):
            raise VariableError("getVariable: must execute on same thread")

        try:
            import gc
            objects = gc.get_objects()
        except:
            pass  # Not all python variants have it.
        else:
            frame_id = int(frame_id)
            for var in objects:
                if id(var) == frame_id:
                    if attrs is not None:
                        attrList = attrs.split('\t')
                        for k in attrList:
                            _type, _type_name, resolver = get_type(var)
                            var = resolver.resolve(var, k)

                    return var

        # If it didn't return previously, we coudn't find it by id (i.e.: alrceady garbage collected).
        sys.stderr.write('Unable to find object with id: %s\n' % (frame_id, ))
        return None

    frame = dbg.find_frame(thread_id, frame_id)
    if frame is None:
        return {}

    if attrs is not None:
        attrList = attrs.split('\t')
    else:
        attrList = []

    for attr in attrList:
        attr.replace("@_@TAB_CHAR@_@", '\t')

    if scope == 'EXPRESSION':
        for count in range(len(attrList)):
            if count == 0:
                # An Expression can be in any scope (globals/locals), therefore it needs to evaluated as an expression
                var = evaluate_expression(dbg, frame, attrList[count], False)
            else:
                _type, _type_name, resolver = get_type(var)
                var = resolver.resolve(var, attrList[count])
    else:
        if scope == "GLOBAL":
            var = frame.f_globals
            del attrList[
                0]  # globals are special, and they get a single dummy unused attribute
        else:
            # in a frame access both locals and globals as Python does
            var = {}
            var.update(frame.f_globals)
            var.update(frame.f_locals)

        for k in attrList:
            _type, _type_name, resolver = get_type(var)
            var = resolver.resolve(var, k)

    return var
def table_like_struct_to_xml(array, name, roffset, coffset, rows, cols, format):
    _, type_name, _ = get_type(array)
    if type_name in TYPE_TO_XML_CONVERTERS:
        return "<xml>%s</xml>" % TYPE_TO_XML_CONVERTERS[type_name](array, name, roffset, coffset, rows, cols, format)
    else:
        raise VariableError("type %s not supported" % type_name)