Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 00ff433

Browse files
committed
Totally new "freeze" program.
1 parent dbaf332 commit 00ff433

6 files changed

Lines changed: 561 additions & 560 deletions

File tree

Tools/freeze/findmodules.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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.)
7+
8+
import os
9+
import regex
10+
import string
11+
import sys
12+
13+
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.
17+
18+
def findmodules(scriptfile, modules = [], path = sys.path):
19+
todo = {}
20+
todo['__main__'] = scriptfile
21+
for name in modules:
22+
mod = os.path.basename(name)
23+
if mod[-3:] == '.py': mod = mod[:-3]
24+
todo[mod] = name
25+
done = closure(todo)
26+
return done
27+
28+
29+
# Compute the closure of scanfile() and findmodule().
30+
# Return a dictionary mapping module names to filenames.
31+
# Writes to stderr if a file can't be or read.
32+
33+
def closure(todo):
34+
done = {}
35+
while todo:
36+
newtodo = {}
37+
for modname in todo.keys():
38+
if not done.has_key(modname):
39+
filename = todo[modname]
40+
if filename is None:
41+
filename = findmodule(modname)
42+
done[modname] = filename
43+
if filename in ('<builtin>', '<unknown>'):
44+
continue
45+
try:
46+
modules = scanfile(filename)
47+
except IOError, msg:
48+
sys.stderr.write("%s: %s\n" %
49+
(filename, str(msg)))
50+
continue
51+
for m in modules:
52+
if not done.has_key(m):
53+
newtodo[m] = None
54+
todo = newtodo
55+
return done
56+
57+
58+
# Scan a file looking for import statements.
59+
# Return list of module names.
60+
# Can raise IOError.
61+
62+
importstr = '\(^\|:\)[ \t]*import[ \t]+\([a-zA-Z0-9_, \t]+\)'
63+
fromstr = '\(^\|:\)[ \t]*from[ \t]+\([a-zA-Z0-9_]+\)[ \t]+import[ \t]+'
64+
isimport = regex.compile(importstr)
65+
isfrom = regex.compile(fromstr)
66+
67+
def scanfile(filename):
68+
allmodules = {}
69+
f = open(filename, 'r')
70+
try:
71+
while 1:
72+
line = f.readline()
73+
if not line: break # EOF
74+
while line[-2:] == '\\\n': # Continuation line
75+
line = line[:-2] + ' '
76+
line = line + f.readline()
77+
if isimport.search(line) >= 0:
78+
rawmodules = isimport.group(2)
79+
modules = string.splitfields(rawmodules, ',')
80+
for i in range(len(modules)):
81+
modules[i] = string.strip(modules[i])
82+
elif isfrom.search(line) >= 0:
83+
modules = [isfrom.group(2)]
84+
else:
85+
continue
86+
for mod in modules:
87+
allmodules[mod] = None
88+
finally:
89+
f.close()
90+
return allmodules.keys()
91+
92+
93+
# Find the file containing a module, given its name.
94+
# Return filename, or '<builtin>', or '<unknown>'.
95+
96+
builtins = sys.builtin_module_names
97+
if 'sys' not in builtins: builtins.append('sys')
98+
# XXX this table may have to be changed depending on your platform:
99+
tails = ['.so', 'module.so', '.py', '.pyc']
100+
101+
def findmodule(modname, path = sys.path):
102+
if modname in builtins: return '<builtin>'
103+
for dirname in path:
104+
for tail in tails:
105+
fullname = os.path.join(dirname, modname + tail)
106+
try:
107+
f = open(fullname, 'r')
108+
except IOError:
109+
continue
110+
f.close()
111+
return fullname
112+
return '<unknown>'
113+
114+
115+
# Test the above functions.
116+
117+
def test():
118+
if not sys.argv[1:]:
119+
print 'usage: python findmodules.py scriptfile [morefiles ...]'
120+
sys.exit(2)
121+
done = findmodules(sys.argv[1], sys.argv[2:])
122+
items = done.items()
123+
items.sort()
124+
for mod, file in [('Module', 'File')] + items:
125+
print "%-15s %s" % (mod, file)
126+
127+
if __name__ == '__main__':
128+
test()

0 commit comments

Comments
 (0)