title: How to modify class docstrings using classmethods
body: <h1>My Problem:</h1>
  
  <p>I've created a series of nodes that each have a set of attribute objects associated with them.  The attribute objects are initialized with descriptions and names for each attribute.  I'd like these attributes, and their descriptions, to show up in my sphinx documentation without having to maintain the name/description in two places, once in the doc string of the class and once in the initialization of the attribute.</p>
  
  <p>To illustrate the problem, consider the following code:</p>
  
  <pre><code>class Foo(object):
      """My doc string
      """
      @classmethod
      def default_attributes(cls):
          return {'foo':'description of foo attribute',
                  'bar':'description of bar attribute'}
  
      @classmethod
      def attributes_string(cls):
          attributes = cls.default_attributes()
          result = '\nDefault Attributes:\n'
          for key, value in attributes.iteritems():
              result += '%s: %s\n' % (key, value)
          return result
  
  print Foo.__doc__
  </code></pre>
  
  <p>I'd like the result of Foo.attributes_string to show up in the doc string of Foo so that I get this:</p>
  
  <pre><code>My doc string
  
  Default Attributes:
  foo: description of foo attribute
  bar: description of bar attribute
  </code></pre>
  
  <h1>My Solution Attempts:</h1>
  
  <p>First I thought "Hey that's easy! I'll just setup a class decorator!":</p>
  
  <pre><code>def my_decorator(cls):
      doc = getattr(cls, '__doc__', '')
      doc += cls.attributes_string()
      cls.__doc__ = doc
      return cls
  
  @my_decorator
  class Foo(object):
      """My doc string
      """
  </code></pre>
  
  <p>This failed miserably with the following error:</p>
  
  <pre><code>AttributeError: attribute '__doc__' of 'type' objects is not writable
  </code></pre>
  
  <p>So then I thought "Well then I'll just use a metaclass to set __doc__ before the class is created!".  When I went to implement this I immediately ran into a problem: How do you call a classmethod for a class that hasn't been created yet?  </p>
  
  <p>I circumvented that problem with a very hacky workaround that makes me cringe: I create the class twice, once without modifying it so I can call it's classmethod, and then again to create the class with the proper __doc__:</p>
  
  <pre><code>class Meta(type):
      def __new__(meta_cls, name, bases, cls_dict):
          tmpcls = super(Meta, meta_cls).__new__(meta_cls, name, bases, cls_dict)
  
          doc = cls_dict.get('__doc__', '')
          doc += tmpcls.attributes_string()
          cls_dict['__doc__'] = doc
  
          return super(Meta, meta_cls).__new__(meta_cls, name, bases, cls_dict)
  
  class Foo(object):
      """My doc string
      """
      __metaclass__ = Meta
  </code></pre>
  
  <p>This totally works and gives me the result I was looking for:</p>
  
  <pre><code>My doc string
  
  Default Attributes:
  foo: description of foo attribute
  bar: description of bar attribute
  </code></pre>
  
  <p>However, isn't it terribly inefficient to create the class twice?  Does it matter?  Is there a better way?  Is what I'm trying to do really dumb?</p>