import re to_document=sys.argv[1] parts=to_document.split('.') module='.'.join(parts[:-1]) class_name=parts[-1] __import__(module, globals(), locals()) mod=sys.modules[module] the_class=getattr(mod, class_name) print '.. currentmodule:: %s' % module print '' print '.. class:: %s' % class_name class TypedArgument: def __init__(self, name, arg_type): self.name=name self.type=arg_type class Method: def __init__(self, name, rtype, args, optional): self.name=name self.rtype=rtype self.args=args self.opt=optional def to_sphinx(self): if len(self.opt)>0: signature='%s(%s%s)' % (self.name, ', '.join([a.name for a in self.args]), '[, %s]' % ', '.join([a.name for a in self.opt])) else: signature='%s(%s)' % (self.name, ', '.join([a.name for a in self.args])) val=' .. method:: %s\n\n' % signature for arg in self.args+self.opt: val+=' :param %s:\n' % arg.name val+=' :type %s: %s\n' % (arg.name, arg.type) val+=' :rtype: %s\n' % self.rtype return val def parse_signature(signature): arg=re.compile(r'\s*(\((?P<type>\w+)\)(?P<name>\w+),?\s*)*') opt_args=re.compile(r'(?P<args>.*)(:?\[,(?P<kwargs>.*)\])') method=re.compile(r'(?P<name>\w+)\((?P<args>.*)\) -> (?P<rtype>\w+)') method_match=method.match(signature) if method_match: optional=opt_args.match(method_match.groupdict()['args']) opt_args=[] if optional: for opt_arg in optional.groupdict()['kwargs'].split(','): a=arg.match(opt_arg) assert a opt_args.append(TypedArgument(a.groupdict()['name'], a.groupdict()['type'])) arg_string=optional.groupdict()['args'] else: arg_string=method_match.groupdict()['args'] args=[] for aarg in arg_string.split(','): a=arg.match(aarg) assert a args.append(TypedArgument(a.groupdict()['name'], a.groupdict()['type'])) return Method(method_match.groupdict()['name'], method_match.groupdict()['rtype'], args[1:], opt_args) print signature, 'not matched' for m in dir(the_class): if m.startswith('__'): continue member_doc=getattr(the_class, m).__doc__ if member_doc: method=parse_signature(member_doc.split('\n')[1]) print method.to_sphinx()