1 # Determine the names and filenames of the modules imported by a
2 # script, recursively. This is done by scanning for lines containing
3 # import statements. (The scanning has only superficial knowledge of
4 # Python syntax and no knowledge of semantics, so in theory the result
5 # may be incorrect -- however this is quite unlikely if you don't
6 # intentionally obscure your Python code.)
14 # Top-level interface.
15 # First argument is the main program (script).
16 # Second optional argument is list of modules to be searched as well.
18 def findmodules(scriptfile
, modules
= [], path
= sys
.path
):
20 todo
['__main__'] = scriptfile
22 mod
= os
.path
.basename(name
)
23 if mod
[-3:] == '.py': mod
= mod
[:-3]
24 elif mod
[-4:] == '.pyc': mod
= mod
[:-4]
30 # Compute the closure of scanfile() and findmodule().
31 # Return a dictionary mapping module names to filenames.
32 # Writes to stderr if a file can't be or read.
38 for modname
in todo
.keys():
39 if not done
.has_key(modname
):
40 filename
= todo
[modname
]
42 filename
= findmodule(modname
)
43 done
[modname
] = filename
44 if filename
in ('<builtin>', '<unknown>'):
47 modules
= scanfile(filename
)
49 sys
.stderr
.write("%s: %s\n" %
53 if not done
.has_key(m
):
59 # Scan a file looking for import statements.
60 # Return list of module names.
63 importstr
= '\(^\|:\)[ \t]*import[ \t]+\([a-zA-Z0-9_, \t]+\)'
64 fromstr
= '\(^\|:\)[ \t]*from[ \t]+\([a-zA-Z0-9_]+\)[ \t]+import[ \t]+'
65 isimport
= regex
.compile(importstr
)
66 isfrom
= regex
.compile(fromstr
)
68 def scanfile(filename
):
70 f
= open(filename
, 'r')
74 if not line
: break # EOF
75 while line
[-2:] == '\\\n': # Continuation line
76 line
= line
[:-2] + ' '
77 line
= line
+ f
.readline()
78 if isimport
.search(line
) >= 0:
79 rawmodules
= isimport
.group(2)
80 modules
= string
.splitfields(rawmodules
, ',')
81 for i
in range(len(modules
)):
82 modules
[i
] = string
.strip(modules
[i
])
83 elif isfrom
.search(line
) >= 0:
84 modules
= [isfrom
.group(2)]
88 allmodules
[mod
] = None
91 return allmodules
.keys()
94 # Find the file containing a module, given its name.
95 # Return filename, or '<builtin>', or '<unknown>'.
97 builtins
= sys
.builtin_module_names
98 tails
= ['.py', '.pyc']
100 def findmodule(modname
, path
= sys
.path
):
101 if modname
in builtins
: return '<builtin>'
104 fullname
= os
.path
.join(dirname
, modname
+ tail
)
106 f
= open(fullname
, 'r')
114 # Test the above functions.
118 print 'usage: python findmodules.py scriptfile [morefiles ...]'
120 done
= findmodules(sys
.argv
[1], sys
.argv
[2:])
123 for mod
, file in [('Module', 'File')] + items
:
124 print "%-15s %s" % (mod
, file)
126 if __name__
== '__main__':