Vega strike Python Modules doc  0.5.1
Documentation of the " Modules " folder of Vega strike
 All Data Structures Namespaces Files Functions Variables
pyclbr Namespace Reference

Data Structures

class  Class
 
class  Function
 

Functions

def readmodule
 
def readmodule_ex
 

Variables

list __all__ = ["readmodule"]
 
int TABWIDTH = 8
 
tuple _getnext
 
dictionary _modules = {}
 

Detailed Description

Parse a Python file and retrieve classes and methods.

Parse enough of a Python file to recognize class and method
definitions and to find out the superclasses of a class.

The interface consists of a single function:
readmodule(module, path)
module is the name of a Python module, path is an optional list of
directories where the module is to be searched.  If present, path is
prepended to the system search path sys.path.
The return value is a dictionary.  The keys of the dictionary are
the names of the classes defined in the module (including classes
that are defined via the from XXX import YYY construct).  The values
are class instances of the class Class defined here.

A class is described by the class Class in this module.  Instances
of this class have the following instance variables:
name -- the name of the class
super -- a list of super classes (Class instances)
methods -- a dictionary of methods
file -- the file in which the class was defined
lineno -- the line in the file on which the class statement occurred
The dictionary of methods uses the method names as keys and the line
numbers on which the method was defined as values.
If the name of a super class is not recognized, the corresponding
entry in the list of super classes is not a class instance but a
string giving the name of the super class.  Since import statements
are recognized and imported modules are scanned as well, this
shouldn't happen often.

BUGS
- Continuation lines are not dealt with at all, except inside strings.
- Nested classes and functions can confuse it.
- Code that doesn't pass tabnanny or python -t will confuse it, unless
  you set the module TABWIDTH vrbl (default 8) to the correct tab width
  for the file.

PACKAGE RELATED BUGS
- If you have a package and a module inside that or another package
  with the same name, module caching doesn't work properly since the
  key is the base name of the module/package.
- The only entry that is returned when you readmodule a package is a
  __path__ whose value is a list which confuses certain class browsers.
- When code does:
  from package import subpackage
  class MyClass(subpackage.SuperClass):
    ...
  It can't locate the parent.  It probably needs to have the same
  hairy logic that the import locator already does.  (This logic
  exists coded in Python in the freeze package.)

Function Documentation

def pyclbr.readmodule (   module,
  path = [],
  inpackage = 0 
)
Backwards compatible interface.

Like readmodule_ex() but strips Function objects from the
resulting dictionary.

Definition at line 143 of file pyclbr.py.

References readmodule_ex().

144 def readmodule(module, path=[], inpackage=0):
145  '''Backwards compatible interface.
146 
147  Like readmodule_ex() but strips Function objects from the
148  resulting dictionary.'''
149 
150  dict = readmodule_ex(module, path, inpackage)
151  res = {}
152  for key, value in dict.items():
153  if not isinstance(value, Function):
154  res[key] = value
155  return res
def pyclbr.readmodule_ex (   module,
  path = [],
  inpackage = 0 
)
Read a module file and return a dictionary of classes.

Search for MODULE in PATH and sys.path, read and parse the
module and return a dictionary with one entry for each class
found in the module.

Definition at line 156 of file pyclbr.py.

References _getnext, dospath.split(), and string.strip().

157 def readmodule_ex(module, path=[], inpackage=0):
158  '''Read a module file and return a dictionary of classes.
159 
160  Search for MODULE in PATH and sys.path, read and parse the
161  module and return a dictionary with one entry for each class
162  found in the module.'''
163 
164  dict = {}
165 
166  i = module.rfind('.')
167  if i >= 0:
168  # Dotted module name
169  package = module[:i].strip()
170  submodule = module[i+1:].strip()
171  parent = readmodule_ex(package, path, inpackage)
172  child = readmodule_ex(submodule, parent['__path__'], 1)
173  return child
174 
175  if _modules.has_key(module):
176  # we've seen this module before...
177  return _modules[module]
178  if module in sys.builtin_module_names:
179  # this is a built-in module
180  _modules[module] = dict
181  return dict
182 
183  # search the path for the module
184  f = None
185  if inpackage:
186  try:
187  f, file, (suff, mode, type) = \
188  imp.find_module(module, path)
189  except ImportError:
190  f = None
191  if f is None:
192  fullpath = list(path) + sys.path
193  f, file, (suff, mode, type) = imp.find_module(module, fullpath)
194  if type == imp.PKG_DIRECTORY:
195  dict['__path__'] = [file]
196  _modules[module] = dict
197  path = [file] + path
198  f, file, (suff, mode, type) = \
199  imp.find_module('__init__', [file])
200  if type != imp.PY_SOURCE:
201  # not Python source, can't do anything with this module
202  f.close()
203  _modules[module] = dict
204  return dict
205 
206  _modules[module] = dict
207  classstack = [] # stack of (class, indent) pairs
208  src = f.read()
209  f.close()
210 
211  # To avoid having to stop the regexp at each newline, instead
212  # when we need a line number we simply string.count the number of
213  # newlines in the string since the last time we did this; i.e.,
214  # lineno = lineno + \
215  # string.count(src, '\n', last_lineno_pos, here)
216  # last_lineno_pos = here
217  countnl = string.count
218  lineno, last_lineno_pos = 1, 0
219  i = 0
220  while 1:
221  m = _getnext(src, i)
222  if not m:
223  break
224  start, i = m.span()
225 
226  if m.start("Method") >= 0:
227  # found a method definition or function
228  thisindent = _indent(m.group("MethodIndent"))
229  meth_name = m.group("MethodName")
230  lineno = lineno + \
231  countnl(src, '\n',
232  last_lineno_pos, start)
233  last_lineno_pos = start
234  # close all classes indented at least as much
235  while classstack and \
236  classstack[-1][1] >= thisindent:
237  del classstack[-1]
238  if classstack:
239  # it's a class method
240  cur_class = classstack[-1][0]
241  cur_class._addmethod(meth_name, lineno)
242  else:
243  # it's a function
244  f = Function(module, meth_name,
245  file, lineno)
246  dict[meth_name] = f
247 
248  elif m.start("String") >= 0:
249  pass
250 
251  elif m.start("Class") >= 0:
252  # we found a class definition
253  thisindent = _indent(m.group("ClassIndent"))
254  # close all classes indented at least as much
255  while classstack and \
256  classstack[-1][1] >= thisindent:
257  del classstack[-1]
258  lineno = lineno + \
259  countnl(src, '\n', last_lineno_pos, start)
260  last_lineno_pos = start
261  class_name = m.group("ClassName")
262  inherit = m.group("ClassSupers")
263  if inherit:
264  # the class inherits from other classes
265  inherit = inherit[1:-1].strip()
266  names = []
267  for n in inherit.split(','):
268  n = n.strip()
269  if dict.has_key(n):
270  # we know this super class
271  n = dict[n]
272  else:
273  c = n.split('.')
274  if len(c) > 1:
275  # super class
276  # is of the
277  # form module.class:
278  # look in
279  # module for class
280  m = c[-2]
281  c = c[-1]
282  if _modules.has_key(m):
283  d = _modules[m]
284  if d.has_key(c):
285  n = d[c]
286  names.append(n)
287  inherit = names
288  # remember this class
289  cur_class = Class(module, class_name, inherit,
290  file, lineno)
291  dict[class_name] = cur_class
292  classstack.append((cur_class, thisindent))
293 
294  elif m.start("Import") >= 0:
295  # import module
296  for n in m.group("ImportList").split(','):
297  n = n.strip()
298  try:
299  # recursively read the imported module
300  d = readmodule_ex(n, path, inpackage)
301  except:
302  ##print 'module', n, 'not found'
303  pass
304 
305  elif m.start("ImportFrom") >= 0:
306  # from module import stuff
307  mod = m.group("ImportFromPath")
308  names = m.group("ImportFromList").split(',')
309  try:
310  # recursively read the imported module
311  d = readmodule_ex(mod, path, inpackage)
312  except:
313  ##print 'module', mod, 'not found'
314  continue
315  # add any classes that were defined in the
316  # imported module to our name space if they
317  # were mentioned in the list
318  for n in names:
319  n = n.strip()
320  if d.has_key(n):
321  dict[n] = d[n]
322  elif n == '*':
323  # only add a name if not
324  # already there (to mimic what
325  # Python does internally)
326  # also don't add names that
327  # start with _
328  for n in d.keys():
329  if n[0] != '_' and \
330  not dict.has_key(n):
331  dict[n] = d[n]
332  else:
333  assert 0, "regexp _getnext found something unexpected"
334 
335  return dict

Variable Documentation

list __all__ = ["readmodule"]

Definition at line 58 of file pyclbr.py.

tuple _getnext
Initial value:
1 = re.compile(r""" (?P<String> \""" [^"\\]* (?:
2  (?: \\. | "(?!"") ) [^"\\]*
3  )*
4  \""" | ''' [^'\\]* (?: (?: \\. | '(?!'') ) [^'\\]* )* ''' | " [^"\\\n]* (?: \\. [^"\\\n]*)* " | ' [^'\\\n]* (?: \\. [^'\\\n]*)* ' )| (?P<Method> ^ (?P<MethodIndent> [ \t]* ) def [ \t]+ (?P<MethodName> [a-zA-Z_] \w* ) [ \t]* \( )| (?P<Class> ^ (?P<ClassIndent> [ \t]* ) class [ \t]+ (?P<ClassName> [a-zA-Z_] \w* ) [ \t]* (?P<ClassSupers> \( [^)\n]* \) )? [ \t]* : )| (?P<Import> ^ import [ \t]+ (?P<ImportList> [^#;\n]+ ) )| (?P<ImportFrom> ^ from [ \t]+ (?P<ImportFromPath> [a-zA-Z_] \w* (?: [ \t]* \. [ \t]* [a-zA-Z_] \w* )* ) [ \t]+ import [ \t]+ (?P<ImportFromList> [^#;\n]+ ) )""", re.VERBOSE | re.DOTALL | re.MULTILINE)

Definition at line 62 of file pyclbr.py.

dictionary _modules = {}

Definition at line 118 of file pyclbr.py.

int TABWIDTH = 8

Definition at line 60 of file pyclbr.py.