5 # Find dependencies between a bunch of Python modules.
8 # pdeps file1.py file2.py ...
11 # Four tables separated by lines like '--- Closure ---':
12 # 1) Direct dependencies, listing which module imports which other modules
13 # 2) The inverse of (1)
14 # 3) Indirect dependencies, or the closure of the above
15 # 4) The inverse of (3)
18 # - command line options to select output type
19 # - option to automatically scan the Python library for referenced modules
20 # - option to limit output to particular modules
33 print 'usage: pdeps file.py file.py ...'
43 print '--- Used By ---'
47 print '--- Closure of Uses ---'
48 reach
= closure(table
)
51 print '--- Closure of Used By ---'
52 invreach
= inverse(reach
)
53 printresults(invreach
)
58 # Compiled regular expressions to search for import statements
60 m_import
= re
.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+')
61 m_from
= re
.compile('^[ \t]*import[ \t]+([^#]+)')
64 # Collect data from one file
66 def process(filename
, table
):
67 fp
= open(filename
, 'r')
68 mod
= os
.path
.basename(filename
)
71 table
[mod
] = list = []
75 while line
[-1:] == '\\':
76 nextline
= fp
.readline()
77 if not nextline
: break
78 line
= line
[:-1] + nextline
79 if m_import
.match(line
) >= 0:
80 (a
, b
), (a1
, b1
) = m_import
.regs
[:2]
81 elif m_from
.match(line
) >= 0:
82 (a
, b
), (a1
, b1
) = m_from
.regs
[:2]
84 words
= line
[a1
:b1
].split(',')
85 # print '#', line, words
92 # Compute closure (this is in fact totally general)
95 modules
= table
.keys()
97 # Initialize reach with a copy of table
101 reach
[mod
] = table
[mod
][:]
103 # Iterate until no more change
109 for mo
in reach
[mod
]:
112 if m
not in reach
[mod
]:
119 # Invert a table (this is again totally general).
120 # All keys of the original table are made keys of the inverse,
121 # so there may be empty lists in the inverse.
125 for key
in table
.keys():
126 if not inv
.has_key(key
):
128 for item
in table
[key
]:
129 store(inv
, item
, key
)
133 # Store "item" in "dict" under "key".
134 # The dictionary maps keys to lists of items.
135 # If there is no list for the key yet, it is created.
137 def store(dict, key
, item
):
138 if dict.has_key(key
):
139 dict[key
].append(item
)
144 # Tabulate results neatly
146 def printresults(table
):
147 modules
= table
.keys()
149 for mod
in modules
: maxlen
= max(maxlen
, len(mod
))
154 print mod
.ljust(maxlen
), ':',
162 # Call main and honor exit status
163 if __name__
== '__main__':
166 except KeyboardInterrupt: