4 # This script can be used to identify undocumented modules in the Python
5 # standard library. Use it like this:
7 # .../Doc/tools/listmodules --ignore-from .../Doc/paper-<paper>/modlib.idx
9 """%(program)s - list modules in the Python standard library
11 -a, --annotate Annotate the module names with the subdirectory they
13 -c, --categorize Group the modules by subdirectory
16 --ignore-from <file> Ignore the modules listed in <file>. <file> may
17 contain a list of module names or a module index file
18 as produced when formatting the Python documentation
19 (.idx or .html flavor).
21 If neither -a nor -c are given, the modules are listed in alphabetical
24 Note that -a and -c are mutually exclusive.
26 Limitation: Modules loadable as shared objects may not be listed,
27 though this script attempts to locate such modules.
31 __version__
= '$Revision: 1.1 $'
41 REMOVE_DIRS
= ["dos-8x3", "encodings", "distutils",
42 "lib-old", "lib-stdwin", "test"]
51 ignore
= ignore_dict
.has_key
53 opts
, args
= getopt
.getopt(
55 ["annotate", "built-in", "categorize", "help", "ignore-from="])
56 except getopt
.error
, msg
:
57 sys
.stdout
= sys
.stderr
63 if opt
in ("-a", "--annotate"):
65 elif opt
in ("-b", "--built-in"):
67 elif opt
in ("-c", "--categorize"):
69 elif opt
in ("-h", "--help"):
72 elif opt
in ("-i", "--ignore-from"):
73 data
= open(arg
).read()
75 ignore_from_idx(data
, ignore_dict
)
77 ignore_from_modulelist(data
, ignore_dict
)
78 if args
or (annotate
and categorize
):
82 # Populate the database:
84 srcdir
= os
.path
.normpath(os
.path
.join(
85 os
.path
.dirname(sys
.argv
[0]), os
.pardir
, os
.pardir
))
91 modules_by_dir
["<builtin>"] = l
92 for name
in sys
.builtin_module_names
:
94 modules_by_name
[name
] = "<built-in>"
96 rx
= re
.compile("Lib/plat-[a-zA-Z0-9]*/")
97 fp
= os
.popen("find Lib -name \*.py -print", "r")
104 line
= "Lib/plat-*/" + line
[m
.end():]
105 line
= line
[4:-4] # strip off 'Lib/' and '.py\n'
106 dir, name
= os
.path
.split(line
)
107 dir = dir or "<standard>"
110 if dir not in REMOVE_DIRS
:
111 modules_by_name
[name
] = dir
112 l
= modules_by_dir
.get(dir, [])
113 modules_by_dir
[dir] = l
116 # load up extension modules:
121 for line
in glob
.glob("*module.c"):
123 if ignore(name
) or modules_by_name
.has_key(name
) or name
== "xx":
125 modules_by_name
[name
] = dir
126 l
= modules_by_dir
.get(dir, [])
127 modules_by_dir
[dir] = l
136 modules
= modules_by_name
.items()
138 width
= max(map(len, modules_by_name
.keys()))
139 format
= "%%-%ds %%s" % width
140 for name
, dir in modules
:
141 if dir and dir[0] != "<":
142 print format
% (name
, dir)
146 modules
= modules_by_dir
.items()
148 width
= max(map(len, modules_by_dir
.keys()))
149 format
= "%%-%ds %%s" % width
150 for dir, names
in modules
:
152 print format
% (dir, names
[0])
153 for name
in names
[1:]:
154 print format
% ('', name
)
157 modules
= modules_by_name
.keys()
159 print string
.join(modules
, "\n")
162 def ignore_from_modulelist(data
, ignore_dict
):
163 for name
in string
.split(data
):
164 ignore_dict
[name
] = name
166 def ignore_from_idx(data
, ignore_dict
):
167 data
= string
.replace(data
, r
"\hackscore {}", "_")
168 rx
= re
.compile(r
"\\indexentry\s*{([^@]*)@")
169 for line
in string
.split(data
, "\n"):
173 ignore_dict
[name
] = name
178 vars["program"] = os
.path
.basename(sys
.argv
[0])
182 if __name__
== "__main__":