def _dict_attribute_help(object_name, path, parent_object_names, attribute):
    help_dict = {
        'object_name': object_name,
        'path_string': '[' + ']['.join(repr(k) for k in path) + ']',
        'parent_object_names': parent_object_names,
        'attribute': attribute
    }

    valid_attributes = graph_reference.get_valid_attributes(
        object_name, parent_object_names
    )

    help_string = (
        "Current path: {path_string}\n"
        "Current parent object_names: {parent_object_names}\n\n")

    if attribute not in valid_attributes:
        help_string += "'{attribute}' is not allowed here.\n"
        return help_string.format(**help_dict)

    attributes_dicts = graph_reference.get_attributes_dicts(
        object_name, parent_object_names
    )

    attribute_definitions = []
    additional_definition = None
    meta_keys = graph_reference.GRAPH_REFERENCE['defs']['metaKeys']
    trace_names = graph_reference.TRACE_NAMES
    for key, attribute_dict in attributes_dicts.items():
        if attribute in attribute_dict:
            if object_name in trace_names and attribute == 'type':
                d = {'role': 'info'}
            else:
                d = {k: v for k, v in attribute_dict[attribute].items()
                     if k in meta_keys and not k.startswith('_')}
        elif attribute in attribute_dict.get('_deprecated', {}):
            deprecate_attribute_dict = attribute_dict['_deprecated'][attribute]
            d = {k: v for k, v in deprecate_attribute_dict.items()
                 if k in meta_keys and not k.startswith('_')}
            d['deprecated'] = True
        else:
            continue

        if key == 'additional_attributes':
            additional_definition = d
            continue

        new_definition = True
        for item in attribute_definitions:
            if item['definition'] == d:
                item['paths'].append(key)
                new_definition = False
        if new_definition:
            attribute_definitions.append({'paths': [key], 'definition': d})

    if attribute_definitions:
        help_string += ("With the current parents, '{attribute}' can be "
                        "used as follows:\n\n")

    help_string = help_string.format(**help_dict)

    for item in attribute_definitions:
        valid_parents_objects_names = [
            graph_reference.attribute_path_to_object_names(definition_path)
            for definition_path in item['paths']
        ]

        if len(valid_parents_objects_names) == 1:
            valid_parent_objects_names = valid_parents_objects_names[0]
            help_string += 'Under {}:\n\n'.format(
                str(valid_parent_objects_names)
            )
        else:
            help_string += 'Under any of:\n\t\t* {}\n\n'.format(
                '\n\t\t* '.join(str(tup) for tup in valid_parents_objects_names)
            )

        for meta_key, val in sorted(item['definition'].items()):
            help_string += '\t{}: '.format(meta_key)
            if meta_key == 'description':

                # TODO: https://github.com/plotly/streambed/issues/3950
                if isinstance(val, list) and attribute == 'showline':
                    val = val[0]

                lines = textwrap.wrap(val, width=LINE_SIZE)
                help_string += '\n\t\t'.join(lines)
            else:
                help_string += '{}'.format(val)
            help_string += '\n'
        help_string += '\n\n'

    if additional_definition:
        help_string += 'Additionally:\n\n'
        for item in sorted(additional_definition.items()):
            help_string += '\t{}: {}\n'.format(*item)
        help_string += '\n'

    return help_string
Get general help information or information on a specific attribute.
dataset/ETHPy150Open plotly/plotly.py/plotly/graph_objs/graph_objs_tools.py/_dict_attribute_help