コード例 #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_compound_variable_fields(thread_id,
                                     frame_id,
                                     scope,
                                     attrs,
                                     user_type_renderers={}):
    """
    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)
    :param user_type_renderers: a dictionary with user type renderers
    :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)

    var_expr = ".".join(attrs.split('\t'))

    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:
            frame_info = (thread_id, frame_id)
            return _typeName, _resolve_custom_variable_fields(
                var, var_expr, resolver, offset, type_renderer, frame_info)

        return _typeName, _resolve_default_variable_fields(
            var, resolver, offset)

    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()
コード例 #3
0
def var_to_struct(val, name, format='%s', do_trim=True, evaluate_full_value=True, user_type_renderers=None):
    """ single variable or dictionary to Thrift struct representation """

    debug_value = DebugValue()

    try:
        # This should be faster than isinstance (but we have to protect against not having a '__class__' attribute).
        is_exception_on_eval = val.__class__ == ExceptionOnEvaluate
    except:
        is_exception_on_eval = False

    if is_exception_on_eval:
        v = val.result
    else:
        v = val

    if name in DO_NOT_PROCESS_VARS:
        debug_value.name = name
        debug_value.value = val
        return debug_value

    _type, typeName, resolver = get_type(v)
    type_qualifier = getattr(_type, "__module__", "")

    type_renderer = None
    if user_type_renderers is not None:
        type_renderer = try_get_type_renderer_for_var(v, user_type_renderers)

    var_custom_string_repr = None
    value = None
    if not evaluate_full_value:
        value = DEFAULT_VALUES_DICT[LOAD_VALUES_POLICY]
    elif type_renderer is not None:
        var_custom_string_repr = type_renderer.evaluate_var_string_repr(v)
        value = var_custom_string_repr

    if value is None:
        value = _get_default_var_string_representation(v, _type, typeName, format)

    debug_value.name = name
    debug_value.type = typeName

    if type_qualifier:
        debug_value.qualifier = type_qualifier

    # cannot be too big... communication may not handle it.
    if len(value) > MAXIMUM_VARIABLE_REPRESENTATION_SIZE and do_trim:
        value = value[0:MAXIMUM_VARIABLE_REPRESENTATION_SIZE]
        value += '...'

    # fix to work with unicode values
    try:
        if not IS_PY3K:
            if value.__class__ == unicode:  # @UndefinedVariable
                value = value.encode('utf-8')
        else:
            if value.__class__ == bytes:
                value = value.encode('utf-8')
    except TypeError:  # in java, unicode is a function
        pass

    if is_pandas_container(type_qualifier, typeName, v) and var_custom_string_repr is None:
        value = pandas_to_str(v, typeName, value, pydevd_resolver.MAX_ITEMS_TO_HANDLE)
    debug_value.value = value

    try:
        if should_evaluate_shape():
            if hasattr(v, 'shape') and not callable(v.shape):
                debug_value.shape = str(tuple(v.shape))
            elif hasattr(v, '__len__') and not is_string(v):
                debug_value.shape = str(len(v))
    except:
        pass

    if is_exception_on_eval:
        debug_value.isErrorOnEval = True
    else:
        if resolver is not None:
            debug_value.isContainer = True
        else:
            pass

    if type_renderer is not None:
        debug_value.typeRendererId = type_renderer.to_type

    return debug_value
コード例 #4
0
def var_to_xml(val,
               name,
               doTrim=True,
               additional_in_xml='',
               evaluate_full_value=True,
               format='%s',
               user_type_renderers=None):
    """ single variable or dictionary to xml representation """

    if name in DO_NOT_PROCESS_VARS:
        xml = '<var name="%s" ' % (make_valid_xml_value(name))
        return ''.join((xml, ' />\n'))

    try:
        # This should be faster than isinstance (but we have to protect against not having a '__class__' attribute).
        is_exception_on_eval = val.__class__ == ExceptionOnEvaluate
    except:
        is_exception_on_eval = False

    if is_exception_on_eval:
        v = val.result
    else:
        v = val

    _type, typeName, resolver = get_type(v)
    type_qualifier = getattr(_type, "__module__", "")

    type_renderer = None
    if user_type_renderers is not None:
        type_renderer = try_get_type_renderer_for_var(v, user_type_renderers)

    var_custom_string_repr = None
    value = None
    if not evaluate_full_value:
        value = DEFAULT_VALUES_DICT[LOAD_VALUES_POLICY]
    elif type_renderer is not None:
        var_custom_string_repr = type_renderer.evaluate_var_string_repr(v)
        value = var_custom_string_repr

    if value is None:
        value = _get_default_var_string_representation(v, _type, typeName,
                                                       format)

    try:
        name = _do_quote(name)  # TODO: Fix PY-5834 without using quote
    except:
        pass

    xml = '<var name="%s" type="%s" ' % (make_valid_xml_value(name),
                                         make_valid_xml_value(typeName))

    if type_qualifier:
        xml_qualifier = 'qualifier="%s"' % make_valid_xml_value(type_qualifier)
    else:
        xml_qualifier = ''

    # cannot be too big... communication may not handle it.
    if len(value) > MAXIMUM_VARIABLE_REPRESENTATION_SIZE and doTrim:
        value = value[0:MAXIMUM_VARIABLE_REPRESENTATION_SIZE]
        value += '...'

    if is_pandas_container(type_qualifier, typeName,
                           v) and var_custom_string_repr is None:
        value = pandas_to_str(v, typeName, value,
                              pydevd_resolver.MAX_ITEMS_TO_HANDLE)
    xml_value = ' value="%s"' % (make_valid_xml_value(_do_quote(value)))

    xml_shape = ''
    try:
        if should_evaluate_shape():
            if hasattr(v, 'shape') and not callable(v.shape):
                xml_shape = ' shape="%s"' % make_valid_xml_value(
                    str(tuple(v.shape)))
            elif hasattr(v, '__len__') and not is_string(v):
                xml_shape = ' shape="%s"' % make_valid_xml_value(
                    "%s" % str(len(v)))
    except:
        pass

    if is_exception_on_eval:
        xml_container = ' isErrorOnEval="True"'
    else:
        if resolver is not None:
            xml_container = ' isContainer="True"'
        else:
            xml_container = ''

    if type_renderer is not None:
        xml_type_renderer_id = 'typeRendererId="%s"' % make_valid_xml_value(
            type_renderer.to_type)
    else:
        xml_type_renderer_id = ''

    return ''.join((xml, xml_qualifier, xml_value, xml_container, xml_shape,
                    xml_type_renderer_id, additional_in_xml, ' />\n'))