def namedtuple(typename, fields):
    field_names = [get_field_name(f) for f in fields]
    default_values = []
    default_found = False
    field_types = []
    docstrings = []

    new_fields = []
    for f in fields:
        field_name = get_field_name(f)
        field_key = (typename, field_name)
        field_type = None
        docstring = None
        default_value = None
        if field_key in _docs:
            (field_type, docstring) = _docs[field_key]
        else:
            if len(f) > 1 and f[1]:
                field_type = f[1]
            if len(f) > 2 and f[2]:
                docstring = f[2]

        if isinstance(f[0], tuple):
            default_found = True
            default_value = f[0][1]
            default_values.append(default_value)
        elif default_found:
            raise Exception('Field "%s" must have default value since the '
                            'preceding field does.' % f[0])
        if field_type:
            field_types.append("(%s)" % field_type)
        else:
            field_types.append("")
        if docstring:
            docstrings.append("\n        %s\n" % docstring)
        else:
            docstrings.append("")

        new_fields.append(((field_name, default_value), field_type, docstring))
    
    fields = new_fields

    T = _namedtuple(typename, field_names)
    args = []
    if len(default_values) > 0:
        T.__new__.__defaults__ = tuple(default_values)
        args.extend("%s=%s" % (field_name, '"%s"' % default_val \
                               if isinstance(default_val, basestring) \
                               else default_val) \
                    for (field_name, default_val) in \
                    izip(reversed(field_names), reversed(default_values)))
        args.reverse()
        args = field_names[:len(field_names)-len(default_values)] + args
    else:
        args = field_names
    
    init_docstring = ""
    for (field_name, field_type, docstring) in \
        izip(field_names, field_types, docstrings):
        init_docstring += "    .. py:attribute:: %s %s\n%s\n" % \
                          (field_name, field_type, docstring)

    init_template = "def __init__(self, %s): pass" % ', '.join(args)
    d = {}
    exec init_template in d
    T.__init__ = d['__init__']
    T.__init__.im_func.__doc__ = init_docstring
    T._vistrails_fields = fields

    return T
dataset/ETHPy150Open VisTrails/VisTrails/vistrails/core/modules/config.py/namedtuple/original