mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			159 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #! /usr/bin/env python
 | |
| #  -*- Python -*-
 | |
| #
 | |
| #  This script can be used to identify undocumented modules in the Python
 | |
| #  standard library.  Use it like this:
 | |
| #
 | |
| #  .../Doc/tools/listmodules --ignore-from .../Doc/paper-<paper>/modlib.idx
 | |
| 
 | |
| """%(program)s - list modules in the Python standard library
 | |
| 
 | |
| -a, --annotate	  Annotate the module names with the subdirectory they live in
 | |
| -c, --categorize  Group the modules by subdirectory
 | |
| -i <file>,
 | |
| --ignore-from <file>  Ignore the modules listed in <file>.  <file> may contain
 | |
| 		  a list of module names or a module index file as produced
 | |
|                   when formatting the Python documentation (.idx flavor).
 | |
| 
 | |
| If neither -a nor -c are given, the modules are listed in alphabetical order.
 | |
| 
 | |
| Note that -a and -c are mutually exclusive.
 | |
| 
 | |
| Limitation:  Modules loadable as shared objects are not listed.
 | |
| """
 | |
| 
 | |
| __version__ = '$Revision$'
 | |
| 
 | |
| import getopt
 | |
| import os
 | |
| import re
 | |
| import string
 | |
| import sys
 | |
| 
 | |
| 
 | |
| REMOVE_DIRS = ["dos-8x3", "lib-old", "lib-stdwin", "test"]
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     args = sys.argv[1:]
 | |
|     annotate = 0
 | |
|     builtin = 0
 | |
|     categorize = 0
 | |
|     ignore_dict = {}
 | |
|     ignore = ignore_dict.has_key
 | |
|     try:
 | |
|         opts, args = getopt.getopt(
 | |
|             args, "abchi:",
 | |
|             ["annotate", "built-in", "categorize", "help", "ignore-from="])
 | |
|     except getopt.error, msg:
 | |
|         sys.stdout = sys.stderr
 | |
|         print msg
 | |
|         print
 | |
|         usage()
 | |
|         sys.exit(2)
 | |
|     for opt, arg in opts:
 | |
|         if opt in ("-a", "--annotate"):
 | |
|             annotate = 1
 | |
|         elif opt in ("-b", "--built-in"):
 | |
|             builtin = 1
 | |
|         elif opt in ("-c", "--categorize"):
 | |
|             categorize = 1
 | |
|         elif opt in ("-h", "--help"):
 | |
|             usage()
 | |
|             sys.exit()
 | |
|         elif opt in ("-i", "--ignore-from"):
 | |
|             data = open(arg).read()
 | |
|             if data[:1] == "\\":
 | |
|                 ignore_from_idx(data, ignore_dict)
 | |
|             else:
 | |
|                 ignore_from_modulelist(data, ignore_dict)
 | |
|     if args or (annotate and categorize):
 | |
|         usage()
 | |
|         sys.exit(2)
 | |
|     #
 | |
|     # Populate the database:
 | |
|     #
 | |
|     srcdir = os.path.normpath(os.path.join(
 | |
|         os.path.dirname(sys.argv[0]), os.pardir, os.pardir))
 | |
|     os.chdir(srcdir)
 | |
|     fp = os.popen("find Lib -name \*.py -print", "r")
 | |
|     modules_by_name = {}
 | |
|     modules_by_dir = {}
 | |
|     if builtin:
 | |
|         l = []
 | |
|         modules_by_dir["<builtin>"] = l
 | |
|         for name in sys.builtin_module_names:
 | |
|             if not ignore(name):
 | |
|                 modules_by_name[name] = "<built-in>"
 | |
|                 l.append(name)
 | |
|     rx = re.compile("Lib/plat-[a-z0-9]*/", re.IGNORECASE)
 | |
|     while 1:
 | |
|         line = fp.readline()
 | |
|         if not line:
 | |
|             break
 | |
|         m = rx.match(line)
 | |
|         if m:
 | |
|             line = "Lib/plat-*/" + line[m.end():]
 | |
|         line = line[4:-4]                # strip off 'Lib/' and '.py\n'
 | |
|         dir, name = os.path.split(line)
 | |
|         dir = dir or "<standard>"
 | |
|         if ignore(name):
 | |
|             continue
 | |
|         if dir not in REMOVE_DIRS:
 | |
|             modules_by_name[name] = dir
 | |
|             l = modules_by_dir.get(dir, [])
 | |
|             modules_by_dir[dir] = l
 | |
|             if name not in l:
 | |
|                 l.append(name)
 | |
|     #
 | |
|     # Dump the results:
 | |
|     #
 | |
|     if annotate:
 | |
|         modules = modules_by_name.items()
 | |
|         modules.sort()
 | |
|         width = max(map(len, modules_by_name.keys()))
 | |
|         format = "%%-%ds  %%s" % width
 | |
|         for name, dir in modules:
 | |
|             if dir and dir[0] != "<":
 | |
|                 print format % (name, dir)
 | |
|             else:
 | |
|                 print name
 | |
|     elif categorize:
 | |
|         modules = modules_by_dir.items()
 | |
|         modules.sort()
 | |
|         width = max(map(len, modules_by_dir.keys()))
 | |
|         format = "%%-%ds  %%s" % width
 | |
|         for dir, names in modules:
 | |
|             names.sort()
 | |
|             print format % (dir, names[0])
 | |
|             for name in names[1:]:
 | |
|                 print format % ('', name)
 | |
|             print
 | |
|     else:
 | |
|         modules = modules_by_name.keys()
 | |
|         modules.sort()
 | |
|         print string.join(modules, "\n")
 | |
| 
 | |
| 
 | |
| def ignore_from_modulelist(data, ignore_dict):
 | |
|     for name in string.split(data):
 | |
|         ignore_dict[name] = name
 | |
| 
 | |
| def ignore_from_idx(data, ignore_dict):
 | |
|     data = string.replace(data, r"\hackscore  {}", "_")
 | |
|     rx = re.compile(r"\\indexentry\s*{([^@]*)@")
 | |
|     for line in string.split(data, "\n"):
 | |
|         m = rx.match(line)
 | |
|         if m:
 | |
|             name = m.group(1)
 | |
|             ignore_dict[name] = name
 | |
| 
 | |
| 
 | |
| def usage():
 | |
|     vars = {}
 | |
|     vars["program"] = os.path.basename(sys.argv[0])
 | |
|     print __doc__ % vars
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 | 
