-
Notifications
You must be signed in to change notification settings - Fork 1
/
describe.py
executable file
·154 lines (114 loc) · 3.33 KB
/
describe.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python
# Describe classes, methods and functions in a module.
# Works with user-defined modules, all Python library
# modules, including built-in modules.
import inspect
import os
INDENT=0
def wi(*args):
""" Function to print lines indented according to level """
spaces = ' '*INDENT
print spaces,
for arg in args:
print arg,
print
def indent():
""" Increase indentation """
global INDENT
INDENT += 4
def dedent():
""" Decrease indentation """
global INDENT
INDENT -= 4
def describe_builtin(obj):
""" Describe a builtin function """
wi('Built-in Function: %s' % obj.__name__)
# Built-in functions cannot be inspected by
# inspect.getargspec. We have to try and parse
# the __doc__ attribute of the function.
docstr = obj.__doc__
args = ''
if docstr:
items = docstr.split('\n')
if items:
func_descr = items[0]
s = func_descr.replace(obj.__name__,'')
idx1 = s.find('(')
idx2 = s.find(')',idx1)
if idx1 != -1 and idx2 != -1 and (idx2>idx1+1):
args = s[idx1+1:idx2]
wi('\tMethod Arguments:', args)
if args=='':
wi('\tMethod Arguments: None')
print
def describe_func(obj, method=False):
""" Describe the function object passed as argument.
If this is a method object, the second argument will
be passed as True """
if method:
wi('Method: %s' % obj.__name__)
else:
wi('Function: %s' % obj.__name__)
try:
arginfo = inspect.getargspec(obj)
except TypeError:
print
return
args = arginfo[0]
argsvar = arginfo[1]
if args:
if args[0] == 'self':
wi('\t%s is an instance method' % obj.__name__)
args.pop(0)
wi('\tMethod Arguments:', args)
if arginfo[3]:
dl = len(arginfo[3])
al = len(args)
defargs = args[al-dl:al]
wi('\tDefault arguments:',zip(defargs, arginfo[3]))
if arginfo[1]:
wi('\t Positional Args Param: %s' % arginfo[1])
if arginfo[2]:
wi('\t Keyword Args Param: %s' % arginfo[2])
print
def describe_klass(obj):
""" Describe the class object passed as argument,
including its methods """
wi('Class: %s' % obj.__name__)
indent()
count = 0
for name in obj.__dict__:
item = getattr(obj, name)
if inspect.ismethod(item):
count += 1;describe_func(item, True)
if count==0:
wi('(No members)')
dedent()
print
def describe(module):
""" Describe the module object passed as argument
including its classes and functions """
wi('Module: %s' % module.__name__)
indent()
count = 0
for name in dir(module):
obj = getattr(module, name)
if inspect.isclass(obj):
count += 1; describe_klass(obj)
elif (inspect.ismethod(obj) or inspect.isfunction(obj)):
count +=1 ; describe_func(obj)
elif inspect.isbuiltin(obj):
count += 1; describe_builtin(obj)
if count==0:
wi('(No members)')
dedent()
if __name__ == "__main__":
import sys
print 'test'
if len(sys.argv)<2:
sys.exit('Usage: %s <module>' % sys.argv[0])
module = sys.argv[1].replace('.py','')
print "importing %s" % module
mod = __import__(module)
print "ok so far"
describe(mod)