mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	the Modules/ directory. Most of the remaining undocumented modules seem to be living there.
		
			
				
	
	
		
			176 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
	
		
			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 glob
 | 
						|
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)
 | 
						|
    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)
 | 
						|
    fp = os.popen("find Lib -name \*.py -print", "r")
 | 
						|
    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)
 | 
						|
    # load up extension modules:
 | 
						|
    pwd = os.getcwd()
 | 
						|
    try:
 | 
						|
        os.chdir("Modules")
 | 
						|
        dir = "<extension>"
 | 
						|
        for line in glob.glob("*module.c"):
 | 
						|
            name = line[:-8]
 | 
						|
            if ignore(name) or modules_by_name.has_key(name) or name == "xx":
 | 
						|
                continue
 | 
						|
            modules_by_name[name] = dir
 | 
						|
            l = modules_by_dir.get(dir, [])
 | 
						|
            modules_by_dir[dir] = l
 | 
						|
            if name not in l:
 | 
						|
                l.append(name)
 | 
						|
    finally:
 | 
						|
        os.chdir(pwd)
 | 
						|
    #
 | 
						|
    # 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()
 |