import collections


def tf_namedtuple(name, fieldnames_and_docs):
  """A `namedtuple` class factory that supports field-docstrings.

  ```
  cls = tf_namedtuple("MyNamedTuple",[("a", "Docs for a"),
                                      ("b", "Docs for b")])
  cls.a.__doc__  # ==> "Docs for a"
  ```

  Args:
    name: The name of the new class.
    fieldnames_and_docs: A sequence of `(fieldname, docstring)` pairs. The
      fieldnames are passed to `collections.namedtuple`.

  Returns:
    A namedtuple class.
  """
  fieldnames_and_docs = list(fieldnames_and_docs)
  fieldnames = [fieldname for fieldname, doc in fieldnames_and_docs]
  cls = collections.namedtuple(name, fieldnames)

  for fieldname, doc in fieldnames_and_docs:
    old_prop = getattr(cls, fieldname)
    new_prop = property(fget=old_prop.fget, fset=old_prop.fset,
                        fdel=old_prop.fdel, doc=doc)
    setattr(cls, fieldname, new_prop)

  return cls