# docobject.py # # C. Tismer 990310 """ this module wraps docstring into class instances. Basic sage: create a docfactory instance call it's wrap method with a module, class, function or method docfactory.wrap(thing): wrap a thing's doc docfactory.unwrap(thing): undoes the wrap Advanced usage: Derive a more sophisticated class from the docwrapper class which does something more useful. (docwrapper does nothing) How it works: An object's __doc__ attribute is replaced by a class instance which must be some subclass of a docwrapper. The basic wrapper class is a default of the docfactory init function. Use derived classes for specialized treatment of docstrings. Object traversal: Modules are searched for classes and functions, Classes are searched for methods and functions. Note that imported modules are not modified. """ class docwrapper: """wrapper class which replaces doc strings by instances derived classes can perform all kinds of other operations and publish other properties and methods. """ def __init__(self, docstring): """keep a copy of the docstring""" self.docstring = docstring def __str__(self): """return the true docstring""" return self.docstring import types class docfactory: """basic framework to wrap doc strings.""" inspected_types = { types.ModuleType: (types.ClassType, types.FunctionType), types.ClassType: (types.FunctionType, types.MethodType), types.FunctionType: (), types.MethodType: (), } wrapped_types = inspected_types.keys() wrapped_typenames = map(lambda x:x.__name__, wrapped_types) def __init__(self, wrapper=docwrapper): self .wrapper = wrapper def _transform(self, thing, wrap, debug=0): typ = type(thing) if typ not in self.wrapped_types: raise ValueError, "Object's type is not in "+ repr(self.wrapped_typenames) target = thing if type(thing) is types.MethodType: target = thing.im_func if wrap: if type(thing.__doc__) is types.StringType: target.__doc__ = self.wrapper(target.__doc__) else: if isinstance(thing.__doc__, self.wrapper): target.__doc__ = target.__doc__.docstring subtypes = self.inspected_types[typ] if subtypes: for elem in thing.__dict__.values(): if type(elem) in subtypes: self._transform(elem, wrap) def wrap(self, thing): """wrap a thing's and certain subobject's docstring""" self._transform(thing, 1) def unwrap(self, thing): """unwrap a thing's and certain subobject's docstring""" self._transform(thing, 0) if __name__ == "__main__": f = docfactory() import __main__ f.wrap(__main__) print "wrapped docstring:", docfactory.__doc__ print "kept docstring:", docfactory.__doc__.docstring f.unwrap(__main__) print "undone. type of __doc__=", type(docfactory.__doc__) # eof :-)