Minor cleanups:

* Avoid creating unused local variables where we can.  Where we can't prefix
  the unused variables with '_'.
* Avoid shadowing builtins where it won't change the external interface of a
  function.
* Use None as default path arg to readmodule and readmodule_ex.
This commit is contained in:
Skip Montanaro 2008-04-28 02:57:23 +00:00
parent 798099279d
commit fe1372c7d5
1 changed files with 37 additions and 35 deletions

View File

@ -41,8 +41,8 @@ Instances of this class have the following instance variables:
import sys import sys
import imp import imp
import tokenize # Python tokenizer import tokenize
from token import NAME, DEDENT, NEWLINE, OP from token import NAME, DEDENT, OP
from operator import itemgetter from operator import itemgetter
__all__ = ["readmodule", "readmodule_ex", "Class", "Function"] __all__ = ["readmodule", "readmodule_ex", "Class", "Function"]
@ -73,37 +73,37 @@ class Function:
self.file = file self.file = file
self.lineno = lineno self.lineno = lineno
def readmodule(module, path=[]): def readmodule(module, path=None):
'''Backwards compatible interface. '''Backwards compatible interface.
Call readmodule_ex() and then only keep Class objects from the Call readmodule_ex() and then only keep Class objects from the
resulting dictionary.''' resulting dictionary.'''
dict = _readmodule(module, path)
res = {} res = {}
for key, value in dict.items(): for key, value in _readmodule(module, path or []).items():
if isinstance(value, Class): if isinstance(value, Class):
res[key] = value res[key] = value
return res return res
def readmodule_ex(module, path=[]): def readmodule_ex(module, path=None):
'''Read a module file and return a dictionary of classes. '''Read a module file and return a dictionary of classes.
Search for MODULE in PATH and sys.path, read and parse the Search for MODULE in PATH and sys.path, read and parse the
module and return a dictionary with one entry for each class module and return a dictionary with one entry for each class
found in the module. found in the module.
'''
return _readmodule(module, path or [])
If INPACKAGE is true, it must be the dotted name of the package in def _readmodule(module, path, inpackage=None):
'''Do the hard work for readmodule[_ex].
If INPACKAGE is given, it must be the dotted name of the package in
which we are searching for a submodule, and then PATH must be the which we are searching for a submodule, and then PATH must be the
package search path; otherwise, we are searching for a top-level package search path; otherwise, we are searching for a top-level
module, and PATH is combined with sys.path. module, and PATH is combined with sys.path.
''' '''
return _readmodule(module, path)
def _readmodule(module, path, inpackage=None):
'''Do the hard work for readmodule[_ex].'''
# Compute the full module name (prepending inpackage if set) # Compute the full module name (prepending inpackage if set)
if inpackage: if inpackage is not None:
fullmodule = "%s.%s" % (inpackage, module) fullmodule = "%s.%s" % (inpackage, module)
else: else:
fullmodule = module fullmodule = module
@ -116,7 +116,7 @@ def _readmodule(module, path, inpackage=None):
dict = {} dict = {}
# Check if it is a built-in module; we don't do much for these # Check if it is a built-in module; we don't do much for these
if module in sys.builtin_module_names and not inpackage: if module in sys.builtin_module_names and inpackage is None:
_modules[module] = dict _modules[module] = dict
return dict return dict
@ -126,22 +126,22 @@ def _readmodule(module, path, inpackage=None):
package = module[:i] package = module[:i]
submodule = module[i+1:] submodule = module[i+1:]
parent = _readmodule(package, path, inpackage) parent = _readmodule(package, path, inpackage)
if inpackage: if inpackage is not None:
package = "%s.%s" % (inpackage, package) package = "%s.%s" % (inpackage, package)
return _readmodule(submodule, parent['__path__'], package) return _readmodule(submodule, parent['__path__'], package)
# Search the path for the module # Search the path for the module
f = None f = None
if inpackage: if inpackage is not None:
f, file, (suff, mode, type) = imp.find_module(module, path) f, fname, (_s, _m, ty) = imp.find_module(module, path)
else: else:
f, file, (suff, mode, type) = imp.find_module(module, path + sys.path) f, fname, (_s, _m, ty) = imp.find_module(module, path + sys.path)
if type == imp.PKG_DIRECTORY: if ty == imp.PKG_DIRECTORY:
dict['__path__'] = [file] dict['__path__'] = [fname]
path = [file] + path path = [fname] + path
f, file, (suff, mode, type) = imp.find_module('__init__', [file]) f, fname, (_s, _m, ty) = imp.find_module('__init__', [fname])
_modules[fullmodule] = dict _modules[fullmodule] = dict
if type != imp.PY_SOURCE: if ty != imp.PY_SOURCE:
# not Python source, can't do anything with this module # not Python source, can't do anything with this module
f.close() f.close()
return dict return dict
@ -150,7 +150,7 @@ def _readmodule(module, path, inpackage=None):
g = tokenize.generate_tokens(f.readline) g = tokenize.generate_tokens(f.readline)
try: try:
for tokentype, token, start, end, line in g: for tokentype, token, start, _end, _line in g:
if tokentype == DEDENT: if tokentype == DEDENT:
lineno, thisindent = start lineno, thisindent = start
# close nested classes and defs # close nested classes and defs
@ -161,7 +161,7 @@ def _readmodule(module, path, inpackage=None):
# close previous nested classes and defs # close previous nested classes and defs
while stack and stack[-1][1] >= thisindent: while stack and stack[-1][1] >= thisindent:
del stack[-1] del stack[-1]
tokentype, meth_name, start, end, line = g.next() tokentype, meth_name, start = g.next()[0:3]
if tokentype != NAME: if tokentype != NAME:
continue # Syntax error continue # Syntax error
if stack: if stack:
@ -172,18 +172,19 @@ def _readmodule(module, path, inpackage=None):
# else it's a nested def # else it's a nested def
else: else:
# it's a function # it's a function
dict[meth_name] = Function(fullmodule, meth_name, file, lineno) dict[meth_name] = Function(fullmodule, meth_name,
fname, lineno)
stack.append((None, thisindent)) # Marker for nested fns stack.append((None, thisindent)) # Marker for nested fns
elif token == 'class': elif token == 'class':
lineno, thisindent = start lineno, thisindent = start
# close previous nested classes and defs # close previous nested classes and defs
while stack and stack[-1][1] >= thisindent: while stack and stack[-1][1] >= thisindent:
del stack[-1] del stack[-1]
tokentype, class_name, start, end, line = g.next() tokentype, class_name, start = g.next()[0:3]
if tokentype != NAME: if tokentype != NAME:
continue # Syntax error continue # Syntax error
# parse what follows the class name # parse what follows the class name
tokentype, token, start, end, line = g.next() tokentype, token, start = g.next()[0:3]
inherit = None inherit = None
if token == '(': if token == '(':
names = [] # List of superclasses names = [] # List of superclasses
@ -191,7 +192,7 @@ def _readmodule(module, path, inpackage=None):
level = 1 level = 1
super = [] # Tokens making up current superclass super = [] # Tokens making up current superclass
while True: while True:
tokentype, token, start, end, line = g.next() tokentype, token, start = g.next()[0:3]
if token in (')', ',') and level == 1: if token in (')', ',') and level == 1:
n = "".join(super) n = "".join(super)
if n in dict: if n in dict:
@ -224,16 +225,17 @@ def _readmodule(module, path, inpackage=None):
super.append(token) super.append(token)
# expressions in the base list are not supported # expressions in the base list are not supported
inherit = names inherit = names
cur_class = Class(fullmodule, class_name, inherit, file, lineno) cur_class = Class(fullmodule, class_name, inherit,
fname, lineno)
if not stack: if not stack:
dict[class_name] = cur_class dict[class_name] = cur_class
stack.append((cur_class, thisindent)) stack.append((cur_class, thisindent))
elif token == 'import' and start[1] == 0: elif token == 'import' and start[1] == 0:
modules = _getnamelist(g) modules = _getnamelist(g)
for mod, mod2 in modules: for mod, _mod2 in modules:
try: try:
# Recursively read the imported module # Recursively read the imported module
if not inpackage: if inpackage is None:
_readmodule(mod, path) _readmodule(mod, path)
else: else:
try: try:
@ -287,7 +289,7 @@ def _getnamelist(g):
name2 = None name2 = None
names.append((name, name2)) names.append((name, name2))
while token != "," and "\n" not in token: while token != "," and "\n" not in token:
tokentype, token, start, end, line = g.next() token = g.next()[1]
if token != ",": if token != ",":
break break
return names return names
@ -297,15 +299,15 @@ def _getname(g):
# name is the dotted name, or None if there was no dotted name, # name is the dotted name, or None if there was no dotted name,
# and token is the next input token. # and token is the next input token.
parts = [] parts = []
tokentype, token, start, end, line = g.next() tokentype, token = g.next()[0:2]
if tokentype != NAME and token != '*': if tokentype != NAME and token != '*':
return (None, token) return (None, token)
parts.append(token) parts.append(token)
while True: while True:
tokentype, token, start, end, line = g.next() tokentype, token = g.next()[0:2]
if token != '.': if token != '.':
break break
tokentype, token, start, end, line = g.next() tokentype, token = g.next()[0:2]
if tokentype != NAME: if tokentype != NAME:
break break
parts.append(token) parts.append(token)