mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
	
	
		
			129 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
		
		
			
		
	
	
			129 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
|   | #!/usr/bin/env python | ||
|  | 
 | ||
|  | # Released to the public domain by Skip Montanaro, 28 March 2002 | ||
|  | 
 | ||
|  | """ | ||
|  | findsyms.py - try to identify undocumented symbols exported by modules | ||
|  | 
 | ||
|  | Usage:    findsyms.py librefdir | ||
|  | 
 | ||
|  | For each lib*.tex file in the libref manual source directory, identify which | ||
|  | module is documented, import the module if possible, then search the LaTeX | ||
|  | source for the symbols global to that module.  Report any that don't seem to | ||
|  | be documented. | ||
|  | 
 | ||
|  | Certain exceptions are made to the list of undocumented symbols: | ||
|  | 
 | ||
|  |     * don't mention symbols in which all letters are upper case on the | ||
|  |       assumption they are manifest constants | ||
|  | 
 | ||
|  |     * don't mention symbols that are themselves modules | ||
|  | 
 | ||
|  |     * don't mention symbols that match those exported by os, math, string, | ||
|  |       types, or __builtin__ modules | ||
|  | 
 | ||
|  | Finally, if a name is exported by the module but fails a getattr() lookup, | ||
|  | that anomaly is reported. | ||
|  | """ | ||
|  | 
 | ||
|  | import __builtin__ | ||
|  | import getopt | ||
|  | import glob | ||
|  | import math | ||
|  | import os | ||
|  | import re | ||
|  | import string | ||
|  | import sys | ||
|  | import types | ||
|  | import warnings | ||
|  | 
 | ||
|  | def usage(): | ||
|  |     print >> sys.stderr, """ | ||
|  | usage: %s dir | ||
|  | where 'dir' is the Library Reference Manual source directory. | ||
|  | """ % os.path.basename(sys.argv[0]) | ||
|  |      | ||
|  | def main(): | ||
|  |     try: | ||
|  |         opts, args = getopt.getopt(sys.argv[1:], "") | ||
|  |     except getopt.error: | ||
|  |         usage() | ||
|  |         return | ||
|  | 
 | ||
|  |     if not args: | ||
|  |         usage() | ||
|  |         return | ||
|  | 
 | ||
|  |     libdir = args[0] | ||
|  |      | ||
|  |     warnings.filterwarnings("error") | ||
|  | 
 | ||
|  |     pat = re.compile(r"\\declaremodule\s*{[^}]*}\s*{([^}]*)}") | ||
|  | 
 | ||
|  |     missing = [] | ||
|  |     filelist = glob.glob(os.path.join(libdir, "lib*.tex")) | ||
|  |     filelist.sort() | ||
|  |     for f in filelist: | ||
|  |         mod = f[3:-4] | ||
|  |         if not mod: continue | ||
|  |         data = open(f).read() | ||
|  |         mods = re.findall(pat, data) | ||
|  |         if not mods: | ||
|  |             print "No module declarations found in", f | ||
|  |             continue | ||
|  |         for modname in mods: | ||
|  |             # skip special modules | ||
|  |             if modname.startswith("__"): | ||
|  |                 continue | ||
|  |             try: | ||
|  |                 mod = __import__(modname) | ||
|  |             except ImportError: | ||
|  |                 missing.append(modname) | ||
|  |                 continue | ||
|  |             except DeprecationWarning: | ||
|  |                 print "Deprecated module:", modname | ||
|  |                 continue | ||
|  |             if hasattr(mod, "__all__"): | ||
|  |                 all = mod.__all__ | ||
|  |             else: | ||
|  |                 all = [k for k in dir(mod) if k[0] != "_"] | ||
|  |             mentioned = 0 | ||
|  |             all.sort() | ||
|  |             for name in all: | ||
|  |                 if data.find(name) == -1: | ||
|  |                     # certain names are predominantly used for testing | ||
|  |                     if name in ("main","test","_test"): | ||
|  |                         continue | ||
|  |                     # is it some sort of manifest constant? | ||
|  |                     if name.upper() == name: | ||
|  |                         continue | ||
|  |                     try: | ||
|  |                         item = getattr(mod, name) | ||
|  |                     except AttributeError: | ||
|  |                         print "  ", name, "exposed, but not an attribute" | ||
|  |                         continue | ||
|  |                     # don't care about modules that might be exposed | ||
|  |                     if type(item) == types.ModuleType: | ||
|  |                         continue | ||
|  |                     # check a few modules which tend to be import *'d | ||
|  |                     isglobal = 0 | ||
|  |                     for m in (os, math, string, __builtin__, types): | ||
|  |                         if hasattr(m, name) and item == getattr(m, name): | ||
|  |                             isglobal = 1 | ||
|  |                             break | ||
|  |                     if isglobal: continue | ||
|  |                     if not mentioned: | ||
|  |                         print "Not mentioned in", modname, "docs:" | ||
|  |                         mentioned = 1 | ||
|  |                     print "  ", name | ||
|  |     if missing: | ||
|  |         missing.sort() | ||
|  |         print "Could not import:" | ||
|  |         print "  ", ", ".join(missing) | ||
|  | 
 | ||
|  | if __name__ == "__main__": | ||
|  |     try: | ||
|  |         main() | ||
|  |     except KeyboardInterrupt: | ||
|  |         pass |