import sys import os import getopt sys.path.insert(0, '..') _ARGS_ARGS_FLAG = 4 _KW_ARGS_FLAG = 8 def find_methods(klass): methods = [] for name, attr in klass.__dict__.iteritems(): if name.startswith('_'): continue if callable(attr): args = [] code = attr.func_code arg_names = list(code.co_varnames[1:code.co_argcount]) arg_idx = code.co_argcount if code.co_flags & _ARGS_ARGS_FLAG: arg_names.append('*' + code.co_varnames[arg_idx]) arg_idx += 1 if code.co_flags & _KW_ARGS_FLAG: arg_names.append('**' + code.co_varnames[arg_idx]) methods.append((name, arg_names, klass.__name__)) for base in klass.__bases__: methods.extend(find_methods(base)) return methods def combine_methods(methods): combined = [] names = {} for name, arg_names, klass in methods: if names.get(name): continue combined.append((name, arg_names, klass)) names[name] = 1 combined.sort() return combined def method_table(klass): n = find_methods(klass) print r'\begin{longtableii}{l|l}{textrm}{Method}{Mixin}' for name, arg_names, klass in combine_methods(n): args = ', '.join(arg_names) print r'\lineii{\method{%s(%s)}}{\class{%s}}' % (name, args, klass) print r'\end{longtableii}' def usage(): sys.exit('usage: %s [-o filename] module.class' % os.path.basename(sys.argv[0])) if __name__ == '__main__': try: opts, args = getopt.getopt(sys.argv[1:], 'o:', ['output=']) except getopt.GetoptError: usage() for opt, arg in opts: if opt in ('-o', '--output'): sys.stdout = open(arg, 'w') if len(args) != 1: usage() try: mod_name, klass_name = args[0].split('.') except: usage() mod = __import__(mod_name) klass = getattr(mod, klass_name) method_table(klass)