Package epydoc :: Module apidoc
[hide private]
[frames] | no frames]

Source Code for Module epydoc.apidoc

   1  # epydoc -- API Documentation Classes 
   2  # 
   3  # Copyright (C) 2005 Edward Loper 
   4  # Author: Edward Loper <[email protected]> 
   5  # URL: <http://epydoc.sf.net> 
   6  # 
   7  # $Id: apidoc.py 1553 2007-02-27 00:07:56Z edloper $ 
   8   
   9  """ 
  10  Classes for encoding API documentation about Python programs. 
  11  These classes are used as a common representation for combining 
  12  information derived from introspection and from parsing. 
  13   
  14  The API documentation for a Python program is encoded using a graph of 
  15  L{APIDoc} objects, each of which encodes information about a single 
  16  Python variable or value.  C{APIDoc} has two direct subclasses: 
  17  L{VariableDoc}, for documenting variables; and L{ValueDoc}, for 
  18  documenting values.  The C{ValueDoc} class is subclassed further, to 
  19  define the different pieces of information that should be recorded 
  20  about each value type: 
  21   
  22  G{classtree: APIDoc} 
  23   
  24  The distinction between variables and values is intentionally made 
  25  explicit.  This allows us to distinguish information about a variable 
  26  itself (such as whether it should be considered 'public' in its 
  27  containing namespace) from information about the value it contains 
  28  (such as what type the value has).  This distinction is also important 
  29  because several variables can contain the same value: each variable 
  30  should be described by a separate C{VariableDoc}; but we only need one 
  31  C{ValueDoc}, since they share a single value. 
  32   
  33  @todo: Add a cache to canonical name lookup? 
  34  """ 
  35  __docformat__ = 'epytext en' 
  36   
  37  ###################################################################### 
  38  ## Imports 
  39  ###################################################################### 
  40   
  41  import types, re, os.path, pickle 
  42  from epydoc import log 
  43  import epydoc 
  44  import __builtin__ 
  45  from epydoc.compat import * # Backwards compatibility 
  46  from epydoc.util import decode_with_backslashreplace, py_src_filename 
  47  import epydoc.markup.pyval_repr 
  48   
  49  ###################################################################### 
  50  # Dotted Names 
  51  ###################################################################### 
  52   
53 -class DottedName:
54 """ 55 A sequence of identifiers, separated by periods, used to name a 56 Python variable, value, or argument. The identifiers that make up 57 a dotted name can be accessed using the indexing operator: 58 59 >>> name = DottedName('epydoc', 'api_doc', 'DottedName') 60 >>> print name 61 epydoc.apidoc.DottedName 62 >>> name[1] 63 'api_doc' 64 """ 65 UNREACHABLE = "??" 66 _IDENTIFIER_RE = re.compile("""(?x) 67 (%s | # UNREACHABLE marker, or.. 68 (script-)? # Prefix: script (not a module) 69 \w+ # Identifier (yes, identifiers starting with a 70 # digit are allowed. See SF bug #1649347) 71 '?) # Suffix: submodule that is shadowed by a var 72 (-\d+)? # Suffix: unreachable vals with the same name 73 $""" 74 % re.escape(UNREACHABLE)) 75
76 - class InvalidDottedName(ValueError):
77 """ 78 An exception raised by the DottedName constructor when one of 79 its arguments is not a valid dotted name. 80 """
81 82 _ok_identifiers = set() 83 """A cache of identifier strings that have been checked against 84 _IDENTIFIER_RE and found to be acceptable.""" 85
86 - def __init__(self, *pieces):
87 """ 88 Construct a new dotted name from the given sequence of pieces, 89 each of which can be either a C{string} or a C{DottedName}. 90 Each piece is divided into a sequence of identifiers, and 91 these sequences are combined together (in order) to form the 92 identifier sequence for the new C{DottedName}. If a piece 93 contains a string, then it is divided into substrings by 94 splitting on periods, and each substring is checked to see if 95 it is a valid identifier. 96 97 As an optimization, C{pieces} may also contain a single tuple 98 of values. In that case, that tuple will be used as the 99 C{DottedName}'s identifiers; it will I{not} be checked to 100 see if it's valid. 101 """ 102 if len(pieces) == 1 and isinstance(pieces[0], tuple): 103 self._identifiers = pieces[0] # Optimization 104 return 105 if len(pieces) == 0: 106 raise DottedName.InvalidDottedName('Empty DottedName') 107 self._identifiers = [] 108 for piece in pieces: 109 if isinstance(piece, DottedName): 110 self._identifiers += piece._identifiers 111 elif isinstance(piece, basestring): 112 for subpiece in piece.split('.'): 113 if piece not in self._ok_identifiers: 114 if self._IDENTIFIER_RE.match(subpiece): 115 self._ok_identifiers.add(piece) 116 else: 117 raise DottedName.InvalidDottedName( 118 'Bad identifier %r' % (piece,)) 119 self._identifiers.append(subpiece) 120 else: 121 raise TypeError('Bad identifier %r: expected ' 122 'DottedName or str' % (piece,)) 123 self._identifiers = tuple(self._identifiers)
124
125 - def __repr__(self):
126 idents = [`ident` for ident in self._identifiers] 127 return 'DottedName(' + ', '.join(idents) + ')'
128
129 - def __str__(self):
130 """ 131 Return the dotted name as a string formed by joining its 132 identifiers with periods: 133 134 >>> print DottedName('epydoc', 'api_doc', DottedName') 135 epydoc.apidoc.DottedName 136 """ 137 return '.'.join(self._identifiers)
138
139 - def __add__(self, other):
140 """ 141 Return a new C{DottedName} whose identifier sequence is formed 142 by adding C{other}'s identifier sequence to C{self}'s. 143 """ 144 if isinstance(other, (basestring, DottedName)): 145 return DottedName(self, other) 146 else: 147 return DottedName(self, *other)
148
149 - def __radd__(self, other):
150 """ 151 Return a new C{DottedName} whose identifier sequence is formed 152 by adding C{self}'s identifier sequence to C{other}'s. 153 """ 154 if isinstance(other, (basestring, DottedName)): 155 return DottedName(other, self) 156 else: 157 return DottedName(*(list(other)+[self]))
158
159 - def __getitem__(self, i):
160 """ 161 Return the C{i}th identifier in this C{DottedName}. If C{i} is 162 a non-empty slice, then return a C{DottedName} built from the 163 identifiers selected by the slice. If C{i} is an empty slice, 164 return an empty list (since empty C{DottedName}s are not valid). 165 """ 166 if isinstance(i, types.SliceType): 167 pieces = self._identifiers[i.start:i.stop] 168 if pieces: return DottedName(pieces) 169 else: return [] 170 else: 171 return self._identifiers[i]
172
173 - def __hash__(self):
174 return hash(self._identifiers)
175
176 - def __cmp__(self, other):
177 """ 178 Compare this dotted name to C{other}. Two dotted names are 179 considered equal if their identifier subsequences are equal. 180 Ordering between dotted names is lexicographic, in order of 181 identifier from left to right. 182 """ 183 if not isinstance(other, DottedName): 184 return -1 185 return cmp(self._identifiers, other._identifiers)
186
187 - def __len__(self):
188 """ 189 Return the number of identifiers in this dotted name. 190 """ 191 return len(self._identifiers)
192
193 - def container(self):
194 """ 195 Return the DottedName formed by removing the last identifier 196 from this dotted name's identifier sequence. If this dotted 197 name only has one name in its identifier sequence, return 198 C{None} instead. 199 """ 200 if len(self._identifiers) == 1: 201 return None 202 else: 203 return DottedName(*self._identifiers[:-1])
204
205 - def dominates(self, name, strict=False):
206 """ 207 Return true if this dotted name is equal to a prefix of 208 C{name}. If C{strict} is true, then also require that 209 C{self!=name}. 210 211 >>> DottedName('a.b').dominates(DottedName('a.b.c.d')) 212 True 213 """ 214 len_self = len(self._identifiers) 215 len_name = len(name._identifiers) 216 217 if (len_self > len_name) or (strict and len_self == len_name): 218 return False 219 # The following is redundant (the first clause is implied by 220 # the second), but is done as an optimization. 221 return ((self._identifiers[0] == name._identifiers[0]) and 222 self._identifiers == name._identifiers[:len_self])
223
224 - def contextualize(self, context):
225 """ 226 If C{self} and C{context} share a common ancestor, then return 227 a name for C{self}, relative to that ancestor. If they do not 228 share a common ancestor (or if C{context} is C{UNKNOWN}), then 229 simply return C{self}. 230 231 This is used to generate shorter versions of dotted names in 232 cases where users can infer the intended target from the 233 context. 234 235 @type context: L{DottedName} 236 @rtype: L{DottedName} 237 """ 238 if context is UNKNOWN or not context or len(self) <= 1: 239 return self 240 if self[0] == context[0]: 241 return self[1:].contextualize(context[1:]) 242 else: 243 return self 244 245 # Find the first index where self & context differ. 246 for i in range(min(len(context), len(self))): 247 if self._identifiers[i] != context._identifiers[i]: 248 first_difference = i 249 break 250 else: 251 first_difference = i+1 252 253 # Strip off anything before that index. 254 if first_difference == 0: 255 return self 256 elif first_difference == len(self): 257 return self[-1:] 258 else: 259 return self[first_difference:]
260 261 ###################################################################### 262 # UNKNOWN Value 263 ###################################################################### 264
265 -class _Sentinel:
266 """ 267 A unique value that won't compare equal to any other value. This 268 class is used to create L{UNKNOWN}. 269 """
270 - def __init__(self, name):
271 self.name = name
272 - def __repr__(self):
273 return '<%s>' % self.name
274 - def __nonzero__(self):
275 raise ValueError('Sentinel value <%s> can not be used as a boolean' % 276 self.name)
277 278 UNKNOWN = _Sentinel('UNKNOWN') 279 """A special value used to indicate that a given piece of 280 information about an object is unknown. This is used as the 281 default value for all instance variables.""" 282 283 ###################################################################### 284 # API Documentation Objects: Abstract Base Classes 285 ###################################################################### 286
287 -class APIDoc(object):
288 """ 289 API documentation information for a single element of a Python 290 program. C{APIDoc} itself is an abstract base class; subclasses 291 are used to specify what information should be recorded about each 292 type of program element. In particular, C{APIDoc} has two direct 293 subclasses, C{VariableDoc} for documenting variables and 294 C{ValueDoc} for documenting values; and the C{ValueDoc} class is 295 subclassed further for different value types. 296 297 Each C{APIDoc} subclass specifies the set of attributes that 298 should be used to record information about the corresponding 299 program element type. The default value for each attribute is 300 stored in the class; these default values can then be overridden 301 with instance variables. Most attributes use the special value 302 L{UNKNOWN} as their default value, to indicate that the correct 303 value for that attribute has not yet been determined. This makes 304 it easier to merge two C{APIDoc} objects that are documenting the 305 same element (in particular, to merge information about an element 306 that was derived from parsing with information that was derived 307 from introspection). 308 309 For all attributes with boolean values, use only the constants 310 C{True} and C{False} to designate true and false. In particular, 311 do I{not} use other values that evaluate as true or false, such as 312 C{2} or C{()}. This restriction makes it easier to handle 313 C{UNKNOWN} values. For example, to test if a boolean attribute is 314 C{True} or C{UNKNOWN}, use 'C{attrib in (True, UNKNOWN)}' or 315 'C{attrib is not False}'. 316 317 Two C{APIDoc} objects describing the same object can be X{merged}, 318 using the method L{merge_and_overwrite(other)}. After two 319 C{APIDoc}s are merged, any changes to one will be reflected in the 320 other. This is accomplished by setting the two C{APIDoc} objects 321 to use a shared instance dictionary. See the documentation for 322 L{merge_and_overwrite} for more information, and some important 323 caveats about hashing. 324 """ 325 #{ Docstrings 326 docstring = UNKNOWN 327 """@ivar: The documented item's docstring. 328 @type: C{string} or C{None}""" 329 330 docstring_lineno = UNKNOWN 331 """@ivar: The line number on which the documented item's docstring 332 begins. 333 @type: C{int}""" 334 #} end of "docstrings" group 335 336 #{ Information Extracted from Docstrings 337 descr = UNKNOWN 338 """@ivar: A description of the documented item, extracted from its 339 docstring. 340 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 341 342 summary = UNKNOWN 343 """@ivar: A summary description of the documented item, extracted from 344 its docstring. 345 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 346 347 other_docs = UNKNOWN 348 """@ivar: A flag indicating if the entire L{docstring} body (except tags 349 if any) is entirely included in the L{summary}. 350 @type: C{bool}""" 351 352 metadata = UNKNOWN 353 """@ivar: Metadata about the documented item, extracted from fields in 354 its docstring. I{Currently} this is encoded as a list of tuples 355 C{(field, arg, descr)}. But that may change. 356 @type: C{(str, str, L{ParsedDocstring<markup.ParsedDocstring>})}""" 357 358 extra_docstring_fields = UNKNOWN 359 """@ivar: A list of new docstring fields tags that are defined by the 360 documented item's docstring. These new field tags can be used by 361 this item or by any item it contains. 362 @type: L{DocstringField <epydoc.docstringparser.DocstringField>}""" 363 #} end of "information extracted from docstrings" group 364 365 #{ Source Information 366 docs_extracted_by = UNKNOWN # 'parser' or 'introspecter' or 'both' 367 """@ivar: Information about where the information contained by this 368 C{APIDoc} came from. Can be one of C{'parser'}, 369 C{'introspector'}, or C{'both'}. 370 @type: C{str}""" 371 #} end of "source information" group 372
373 - def __init__(self, **kwargs):
374 """ 375 Construct a new C{APIDoc} object. Keyword arguments may be 376 used to initialize the new C{APIDoc}'s attributes. 377 378 @raise TypeError: If a keyword argument is specified that does 379 not correspond to a valid attribute for this (sub)class of 380 C{APIDoc}. 381 """ 382 if epydoc.DEBUG: 383 for key in kwargs: 384 if key[0] != '_' and not hasattr(self.__class__, key): 385 raise TypeError('%s got unexpected arg %r' % 386 (self.__class__.__name__, key)) 387 self.__dict__.update(kwargs)
388
389 - def _debug_setattr(self, attr, val):
390 """ 391 Modify an C{APIDoc}'s attribute. This is used when 392 L{epydoc.DEBUG} is true, to make sure we don't accidentally 393 set any inappropriate attributes on C{APIDoc} objects. 394 395 @raise AttributeError: If C{attr} is not a valid attribute for 396 this (sub)class of C{APIDoc}. (C{attr} is considered a 397 valid attribute iff C{self.__class__} defines an attribute 398 with that name.) 399 """ 400 # Don't intercept special assignments like __class__, or 401 # assignments to private variables. 402 if attr.startswith('_'): 403 return object.__setattr__(self, attr, val) 404 if not hasattr(self, attr): 405 raise AttributeError('%s does not define attribute %r' % 406 (self.__class__.__name__, attr)) 407 self.__dict__[attr] = val
408 409 if epydoc.DEBUG: 410 __setattr__ = _debug_setattr 411
412 - def __repr__(self):
413 return '<%s>' % self.__class__.__name__
414
415 - def pp(self, doublespace=0, depth=5, exclude=(), include=()):
416 """ 417 Return a pretty-printed string representation for the 418 information contained in this C{APIDoc}. 419 """ 420 return pp_apidoc(self, doublespace, depth, exclude, include)
421 __str__ = pp 422
423 - def specialize_to(self, cls):
424 """ 425 Change C{self}'s class to C{cls}. C{cls} must be a subclass 426 of C{self}'s current class. For example, if a generic 427 C{ValueDoc} was created for a value, and it is determined that 428 the value is a routine, you can update its class with: 429 430 >>> valdoc.specialize_to(RoutineDoc) 431 """ 432 if not issubclass(cls, self.__class__): 433 raise ValueError('Can not specialize to %r' % cls) 434 # Update the class. 435 self.__class__ = cls 436 # Update the class of any other apidoc's in the mergeset. 437 if self.__mergeset is not None: 438 for apidoc in self.__mergeset: 439 apidoc.__class__ = cls 440 # Re-initialize self, in case the subclass constructor does 441 # any special processing on its arguments. 442 self.__init__(**self.__dict__)
443 444 __has_been_hashed = False 445 """True iff L{self.__hash__()} has ever been called.""" 446
447 - def __hash__(self):
448 self.__has_been_hashed = True 449 return id(self.__dict__)
450
451 - def __cmp__(self, other):
452 if not isinstance(other, APIDoc): return -1 453 if self.__dict__ is other.__dict__: return 0 454 name_cmp = cmp(self.canonical_name, other.canonical_name) 455 if name_cmp == 0: return -1 456 else: return name_cmp
457
458 - def is_detailed(self):
459 """ 460 Does this object deserve a box with extra details? 461 462 @return: True if the object needs extra details, else False. 463 @rtype: C{bool} 464 """ 465 if self.other_docs is True: 466 return True 467 468 if self.metadata is not UNKNOWN: 469 return bool(self.metadata)
470 471 __mergeset = None 472 """The set of all C{APIDoc} objects that have been merged with 473 this C{APIDoc} (using L{merge_and_overwrite()}). Each C{APIDoc} 474 in this set shares a common instance dictionary (C{__dict__}).""" 475
476 - def merge_and_overwrite(self, other, ignore_hash_conflict=False):
477 """ 478 Combine C{self} and C{other} into a X{merged object}, such 479 that any changes made to one will affect the other. Any 480 attributes that C{other} had before merging will be discarded. 481 This is accomplished by copying C{self.__dict__} over 482 C{other.__dict__} and C{self.__class__} over C{other.__class__}. 483 484 Care must be taken with this method, since it modifies the 485 hash value of C{other}. To help avoid the problems that this 486 can cause, C{merge_and_overwrite} will raise an exception if 487 C{other} has ever been hashed, unless C{ignore_hash_conflict} 488 is True. Note that adding C{other} to a dictionary, set, or 489 similar data structure will implicitly cause it to be hashed. 490 If you do set C{ignore_hash_conflict} to True, then any 491 existing data structures that rely on C{other}'s hash staying 492 constant may become corrupted. 493 494 @return: C{self} 495 @raise ValueError: If C{other} has ever been hashed. 496 """ 497 # If we're already merged, then there's nothing to do. 498 if (self.__dict__ is other.__dict__ and 499 self.__class__ is other.__class__): return self 500 501 if other.__has_been_hashed and not ignore_hash_conflict: 502 raise ValueError("%r has already been hashed! Merging it " 503 "would cause its has value to change." % other) 504 505 # If other was itself already merged with anything, 506 # then we need to merge those too. 507 a,b = (self.__mergeset, other.__mergeset) 508 mergeset = (self.__mergeset or [self]) + (other.__mergeset or [other]) 509 other.__dict__.clear() 510 for apidoc in mergeset: 511 #if apidoc is self: pass 512 apidoc.__class__ = self.__class__ 513 apidoc.__dict__ = self.__dict__ 514 self.__mergeset = mergeset 515 # Sanity chacks. 516 assert self in mergeset and other in mergeset 517 for apidoc in mergeset: 518 assert apidoc.__dict__ is self.__dict__ 519 # Return self. 520 return self
521
543
544 -def reachable_valdocs(root, **filters):
545 """ 546 Return a list of all C{ValueDoc}s that can be reached, directly or 547 indirectly from the given root list of C{ValueDoc}s. 548 549 @param filters: A set of filters that can be used to prevent 550 C{reachable_valdocs} from following specific link types when 551 looking for C{ValueDoc}s that can be reached from the root 552 set. See C{APIDoc.apidoc_links} for a more complete 553 description. 554 """ 555 apidoc_queue = list(root) 556 val_set = set() 557 var_set = set() 558 while apidoc_queue: 559 api_doc = apidoc_queue.pop() 560 if isinstance(api_doc, ValueDoc): 561 val_set.add(api_doc) 562 else: 563 var_set.add(api_doc) 564 apidoc_queue.extend([v for v in api_doc.apidoc_links(**filters) 565 if v not in val_set and v not in var_set]) 566 return val_set
567 568 ###################################################################### 569 # Variable Documentation Objects 570 ###################################################################### 571
572 -class VariableDoc(APIDoc):
573 """ 574 API documentation information about a single Python variable. 575 576 @note: The only time a C{VariableDoc} will have its own docstring 577 is if that variable was created using an assignment statement, and 578 that assignment statement had a docstring-comment or was followed 579 by a pseudo-docstring. 580 """ 581 #{ Basic Variable Information 582 name = UNKNOWN 583 """@ivar: The name of this variable in its containing namespace. 584 @type: C{str}""" 585 586 container = UNKNOWN 587 """@ivar: API documentation for the namespace that contains this 588 variable. 589 @type: L{ValueDoc}""" 590 591 canonical_name = UNKNOWN 592 """@ivar: A dotted name that serves as a unique identifier for 593 this C{VariableDoc}. It should be formed by concatenating 594 the C{VariableDoc}'s C{container} with its C{name}. 595 @type: L{DottedName}""" 596 597 value = UNKNOWN 598 """@ivar: The API documentation for this variable's value. 599 @type: L{ValueDoc}""" 600 #} 601 602 #{ Information Extracted from Docstrings 603 type_descr = UNKNOWN 604 """@ivar: A description of the variable's expected type, extracted from 605 its docstring. 606 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 607 #} end of "information extracted from docstrings" group 608 609 #{ Information about Imported Variables 610 imported_from = UNKNOWN 611 """@ivar: The fully qualified dotted name of the variable that this 612 variable's value was imported from. This attribute should only 613 be defined if C{is_instvar} is true. 614 @type: L{DottedName}""" 615 616 is_imported = UNKNOWN 617 """@ivar: Was this variable's value imported from another module? 618 (Exception: variables that are explicitly included in __all__ have 619 C{is_imported} set to C{False}, even if they are in fact 620 imported.) 621 @type: C{bool}""" 622 #} end of "information about imported variables" group 623 624 #{ Information about Variables in Classes 625 is_instvar = UNKNOWN 626 """@ivar: If true, then this variable is an instance variable; if false, 627 then this variable is a class variable. This attribute should 628 only be defined if the containing namespace is a class 629 @type: C{bool}""" 630 631 overrides = UNKNOWN # [XXX] rename -- don't use a verb. 632 """@ivar: The API documentation for the variable that is overridden by 633 this variable. This attribute should only be defined if the 634 containing namespace is a class. 635 @type: L{VariableDoc}""" 636 #} end of "information about variables in classes" group 637 638 #{ Flags 639 is_alias = UNKNOWN 640 """@ivar: Is this variable an alias for another variable with the same 641 value? If so, then this variable will be dispreferred when 642 assigning canonical names. 643 @type: C{bool}""" 644 645 is_public = UNKNOWN 646 """@ivar: Is this variable part of its container's public API? 647 @type: C{bool}""" 648 #} end of "flags" group 649
650 - def __init__(self, **kwargs):
651 APIDoc.__init__(self, **kwargs) 652 if self.is_public is UNKNOWN and self.name is not UNKNOWN: 653 self.is_public = (not self.name.startswith('_') or 654 self.name.endswith('_'))
655
656 - def __repr__(self):
657 if self.canonical_name is not UNKNOWN: 658 return '<%s %s>' % (self.__class__.__name__, self.canonical_name) 659 if self.name is not UNKNOWN: 660 return '<%s %s>' % (self.__class__.__name__, self.name) 661 else: 662 return '<%s>' % self.__class__.__name__
663
664 - def _get_defining_module(self):
665 if self.container is UNKNOWN: 666 return UNKNOWN 667 return self.container.defining_module
668 defining_module = property(_get_defining_module, doc=""" 669 A read-only property that can be used to get the variable's 670 defining module. This is defined as the defining module 671 of the variable's container.""") 672 678
679 - def is_detailed(self):
680 pval = super(VariableDoc, self).is_detailed() 681 if pval or self.value in (None, UNKNOWN): 682 return pval 683 684 if (self.overrides not in (None, UNKNOWN) and 685 isinstance(self.value, RoutineDoc)): 686 return True 687 688 if isinstance(self.value, GenericValueDoc): 689 # [XX] This is a little hackish -- we assume that the 690 # summary lines will have SUMMARY_REPR_LINELEN chars, 691 # that len(name) of those will be taken up by the name, 692 # and that 3 of those will be taken up by " = " between 693 # the name & val. Note that if any docwriter uses a 694 # different formula for maxlen for this, then it will 695 # not get the right value for is_detailed(). 696 maxlen = self.value.SUMMARY_REPR_LINELEN-3-len(self.name) 697 return (not self.value.summary_pyval_repr(maxlen).is_complete) 698 else: 699 return self.value.is_detailed()
700 701 ###################################################################### 702 # Value Documentation Objects 703 ###################################################################### 704
705 -class ValueDoc(APIDoc):
706 """ 707 API documentation information about a single Python value. 708 """ 709 canonical_name = UNKNOWN 710 """@ivar: A dotted name that serves as a unique identifier for 711 this C{ValueDoc}'s value. If the value can be reached using a 712 single sequence of identifiers (given the appropriate imports), 713 then that sequence of identifiers is used as its canonical name. 714 If the value can be reached by multiple sequences of identifiers 715 (i.e., if it has multiple aliases), then one of those sequences of 716 identifiers is used. If the value cannot be reached by any 717 sequence of identifiers (e.g., if it was used as a base class but 718 then its variable was deleted), then its canonical name will start 719 with C{'??'}. If necessary, a dash followed by a number will be 720 appended to the end of a non-reachable identifier to make its 721 canonical name unique. 722 723 When possible, canonical names are chosen when new C{ValueDoc}s 724 are created. However, this is sometimes not possible. If a 725 canonical name can not be chosen when the C{ValueDoc} is created, 726 then one will be assigned by L{assign_canonical_names() 727 <docbuilder.assign_canonical_names>}. 728 729 @type: L{DottedName}""" 730 731 #{ Value Representation 732 pyval = UNKNOWN 733 """@ivar: A pointer to the actual Python object described by this 734 C{ValueDoc}. This is used to display the value (e.g., when 735 describing a variable.) Use L{pyval_repr()} to generate a 736 plaintext string representation of this value. 737 @type: Python object""" 738 739 parse_repr = UNKNOWN 740 """@ivar: A text representation of this value, extracted from 741 parsing its source code. This representation may not accurately 742 reflect the actual value (e.g., if the value was modified after 743 the initial assignment). 744 @type: C{unicode}""" 745 746 REPR_MAXLINES = 5 747 """@cvar: The maximum number of lines of text that should be 748 generated by L{pyval_repr()}. If the string representation does 749 not fit in this number of lines, an ellpsis marker (...) will 750 be placed at the end of the formatted representation.""" 751 752 REPR_LINELEN = 75 753 """@cvar: The maximum number of characters for lines of text that 754 should be generated by L{pyval_repr()}. Any lines that exceed 755 this number of characters will be line-wrappped; The S{crarr} 756 symbol will be used to indicate that the line was wrapped.""" 757 758 SUMMARY_REPR_LINELEN = 75 759 """@cvar: The maximum number of characters for the single-line 760 text representation generated by L{summary_pyval_repr()}. If 761 the value's representation does not fit in this number of 762 characters, an ellipsis marker (...) will be placed at the end 763 of the formatted representation.""" 764 765 REPR_MIN_SCORE = 0 766 """@cvar: The minimum score that a value representation based on 767 L{pyval} should have in order to be used instead of L{parse_repr} 768 as the canonical representation for this C{ValueDoc}'s value. 769 @see: L{epydoc.markup.pyval_repr}""" 770 #} end of "value representation" group 771 772 #{ Context 773 defining_module = UNKNOWN 774 """@ivar: The documentation for the module that defines this 775 value. This is used, e.g., to lookup the appropriate markup 776 language for docstrings. For a C{ModuleDoc}, 777 C{defining_module} should be C{self}. 778 @type: L{ModuleDoc}""" 779 #} end of "context group" 780 781 #{ Information about Imported Variables 782 proxy_for = None # [xx] in progress. 783 """@ivar: If C{proxy_for} is not None, then this value was 784 imported from another file. C{proxy_for} is the dotted name of 785 the variable that this value was imported from. If that 786 variable is documented, then its C{value} may contain more 787 complete API documentation about this value. The C{proxy_for} 788 attribute is used by the source code parser to link imported 789 values to their source values (in particular, for base 790 classes). When possible, these proxy C{ValueDoc}s are replaced 791 by the imported value's C{ValueDoc} by 792 L{link_imports()<docbuilder.link_imports>}. 793 @type: L{DottedName}""" 794 #} end of "information about imported variables" group 795 796 #: @ivar: 797 #: This is currently used to extract values from __all__, etc, in 798 #: the docparser module; maybe I should specialize 799 #: process_assignment and extract it there? Although, for __all__, 800 #: it's not clear where I'd put the value, since I just use it to 801 #: set private/public/imported attribs on other vars (that might not 802 #: exist yet at the time.) 803 toktree = UNKNOWN 804
805 - def __repr__(self):
806 if self.canonical_name is not UNKNOWN: 807 return '<%s %s>' % (self.__class__.__name__, self.canonical_name) 808 else: 809 return '<%s %s>' % (self.__class__.__name__, 810 self.summary_pyval_repr().to_plaintext(None))
811
812 - def __setstate__(self, state):
813 self.__dict__ = state
814
815 - def __getstate__(self):
816 """ 817 State serializer for the pickle module. This is necessary 818 because sometimes the C{pyval} attribute contains an 819 un-pickleable value. 820 """ 821 # Construct our pickled dictionary. Maintain this dictionary 822 # as a private attribute, so we can reuse it later, since 823 # merged objects need to share a single dictionary. 824 if not hasattr(self, '_ValueDoc__pickle_state'): 825 # Make sure __pyval_repr & __summary_pyval_repr are cached: 826 self.pyval_repr(), self.summary_pyval_repr() 827 # Construct the dictionary; leave out 'pyval'. 828 self.__pickle_state = self.__dict__.copy() 829 self.__pickle_state['pyval'] = UNKNOWN 830 831 if not isinstance(self, GenericValueDoc): 832 assert self.__pickle_state != {} 833 # Return the pickle state. 834 return self.__pickle_state
835 836 #{ Value Representation
837 - def pyval_repr(self):
838 """ 839 Return a formatted representation of the Python object 840 described by this C{ValueDoc}. This representation may 841 include data from introspection or parsing, and is authorative 842 as 'the best way to represent a Python value.' Any lines that 843 go beyond L{REPR_LINELEN} characters will be wrapped; and if 844 the representation as a whole takes more than L{REPR_MAXLINES} 845 lines, then it will be truncated (with an ellipsis marker). 846 This function will never return L{UNKNOWN} or C{None}. 847 848 @rtype: L{ColorizedPyvalRepr} 849 """ 850 # Use self.__pyval_repr to cache the result. 851 if not hasattr(self, '_ValueDoc__pyval_repr'): 852 self.__pyval_repr = epydoc.markup.pyval_repr.colorize_pyval( 853 self.pyval, self.parse_repr, self.REPR_MIN_SCORE, 854 self.REPR_LINELEN, self.REPR_MAXLINES, linebreakok=True) 855 return self.__pyval_repr
856
857 - def summary_pyval_repr(self, max_len=None):
858 """ 859 Return a single-line formatted representation of the Python 860 object described by this C{ValueDoc}. This representation may 861 include data from introspection or parsing, and is authorative 862 as 'the best way to summarize a Python value.' If the 863 representation takes more then L{SUMMARY_REPR_LINELEN} 864 characters, then it will be truncated (with an ellipsis 865 marker). This function will never return L{UNKNOWN} or 866 C{None}. 867 868 @rtype: L{ColorizedPyvalRepr} 869 """ 870 # If max_len is specified, then do *not* cache the result. 871 if max_len is not None: 872 return epydoc.markup.pyval_repr.colorize_pyval( 873 self.pyval, self.parse_repr, self.REPR_MIN_SCORE, 874 max_len, maxlines=1, linebreakok=False) 875 876 # Use self.__summary_pyval_repr to cache the result. 877 if not hasattr(self, '_ValueDoc__summary_pyval_repr'): 878 self.__summary_pyval_repr = epydoc.markup.pyval_repr.colorize_pyval( 879 self.pyval, self.parse_repr, self.REPR_MIN_SCORE, 880 self.SUMMARY_REPR_LINELEN, maxlines=1, linebreakok=False) 881 return self.__summary_pyval_repr
882 #} end of "value representation" group 883
886
887 -class GenericValueDoc(ValueDoc):
888 """ 889 API documentation about a 'generic' value, i.e., one that does not 890 have its own docstring or any information other than its value and 891 parse representation. C{GenericValueDoc}s do not get assigned 892 cannonical names. 893 """ 894 canonical_name = None 895
896 - def is_detailed(self):
897 return (not self.summary_pyval_repr().is_complete)
898
899 -class NamespaceDoc(ValueDoc):
900 """ 901 API documentation information about a singe Python namespace 902 value. (I.e., a module or a class). 903 """ 904 #{ Information about Variables 905 variables = UNKNOWN 906 """@ivar: The contents of the namespace, encoded as a 907 dictionary mapping from identifiers to C{VariableDoc}s. This 908 dictionary contains all names defined by the namespace, 909 including imported variables, aliased variables, and variables 910 inherited from base classes (once L{inherit_docs() 911 <epydoc.docbuilder.inherit_docs>} has added them). 912 @type: C{dict} from C{string} to L{VariableDoc}""" 913 sorted_variables = UNKNOWN 914 """@ivar: A list of all variables defined by this 915 namespace, in sorted order. The elements of this list should 916 exactly match the values of L{variables}. The sort order for 917 this list is defined as follows: 918 - Any variables listed in a C{@sort} docstring field are 919 listed in the order given by that field. 920 - These are followed by any variables that were found while 921 parsing the source code, in the order in which they were 922 defined in the source file. 923 - Finally, any remaining variables are listed in 924 alphabetical order. 925 @type: C{list} of L{VariableDoc}""" 926 sort_spec = UNKNOWN 927 """@ivar: The order in which variables should be listed, 928 encoded as a list of names. Any variables whose names are not 929 included in this list should be listed alphabetically, 930 following the variables that are included. 931 @type: C{list} of C{str}""" 932 group_specs = UNKNOWN 933 """@ivar: The groups that are defined by this namespace's 934 docstrings. C{group_specs} is encoded as an ordered list of 935 tuples C{(group_name, elt_names)}, where C{group_name} is the 936 937 name of a group and C{elt_names} is a list of element names in 938 that group. (An element can be a variable or a submodule.) A 939 '*' in an element name will match any string of characters. 940 @type: C{list} of C{(str,list)}""" 941 variable_groups = UNKNOWN 942 """@ivar: A dictionary specifying what group each 943 variable belongs to. The keys of the dictionary are group 944 names, and the values are lists of C{VariableDoc}s. The order 945 that groups should be listed in should be taken from 946 L{group_specs}. 947 @type: C{dict} from C{str} to C{list} of L{VariableDoc}""" 948 #} end of group "information about variables" 949
950 - def __init__(self, **kwargs):
951 kwargs.setdefault('variables', {}) 952 APIDoc.__init__(self, **kwargs) 953 assert self.variables is not UNKNOWN
954
955 - def is_detailed(self):
956 return True
957 976
977 - def init_sorted_variables(self):
978 """ 979 Initialize the L{sorted_variables} attribute, based on the 980 L{variables} and L{sort_spec} attributes. This should usually 981 be called after all variables have been added to C{variables} 982 (including any inherited variables for classes). 983 """ 984 unsorted = self.variables.copy() 985 self.sorted_variables = [] 986 987 # Add any variables that are listed in sort_spec 988 if self.sort_spec is not UNKNOWN: 989 for ident in self.sort_spec: 990 if ident in unsorted: 991 self.sorted_variables.append(unsorted[ident]) 992 del unsorted[ident] 993 elif '*' in ident: 994 regexp = re.compile('^%s$' % ident.replace('*', '(.*)')) 995 # sort within matching group? 996 for name, var_doc in unsorted.items(): 997 if regexp.match(name): 998 self.sorted_variables.append(var_doc) 999 unsorted.remove(var_doc) 1000 1001 # Add any remaining variables in alphabetical order. 1002 var_docs = unsorted.items() 1003 var_docs.sort() 1004 for name, var_doc in var_docs: 1005 self.sorted_variables.append(var_doc)
1006
1007 - def init_variable_groups(self):
1008 """ 1009 Initialize the L{variable_groups} attribute, based on the 1010 L{sorted_variables} and L{group_specs} attributes. 1011 """ 1012 if self.sorted_variables is UNKNOWN: 1013 self.init_sorted_variables 1014 assert len(self.sorted_variables) == len(self.variables) 1015 1016 elts = [(v.name, v) for v in self.sorted_variables] 1017 self.variable_groups = self._init_grouping(elts)
1018
1019 - def group_names(self):
1020 """ 1021 Return a list of the group names defined by this namespace, in 1022 the order in which they should be listed, with no duplicates. 1023 """ 1024 name_list = [''] 1025 name_set = set() 1026 for name, spec in self.group_specs: 1027 if name not in name_set: 1028 name_set.add(name) 1029 name_list.append(name) 1030 return name_list
1031
1032 - def _init_grouping(self, elts):
1033 """ 1034 Divide a given a list of APIDoc objects into groups, as 1035 specified by L{self.group_specs}. 1036 1037 @param elts: A list of tuples C{(name, apidoc)}. 1038 1039 @return: A list of tuples C{(groupname, elts)}, where 1040 C{groupname} is the name of a group and C{elts} is a list of 1041 C{APIDoc}s in that group. The first tuple has name C{''}, and 1042 is used for ungrouped elements. The remaining tuples are 1043 listed in the order that they appear in C{self.group_specs}. 1044 Within each tuple, the elements are listed in the order that 1045 they appear in C{api_docs}. 1046 """ 1047 # Make the common case fast. 1048 if len(self.group_specs) == 0: 1049 return {'': [elt[1] for elt in elts]} 1050 1051 ungrouped = set([elt_doc for (elt_name, elt_doc) in elts]) 1052 groups = {} 1053 for (group_name, elt_names) in self.group_specs: 1054 group_re = re.compile('|'.join([n.replace('*','.*')+'$' 1055 for n in elt_names])) 1056 group = groups.get(group_name, []) 1057 for elt_name, elt_doc in list(elts): 1058 if group_re.match(elt_name): 1059 group.append(elt_doc) 1060 if elt_doc in ungrouped: 1061 ungrouped.remove(elt_doc) 1062 else: 1063 # [xx] might just be listed in the same group twice! 1064 log.warning("%s.%s is in multiple groups" % 1065 (self.canonical_name, elt_name)) 1066 groups[group_name] = group 1067 1068 # Convert ungrouped from an unordered set to an ordered list. 1069 groups[''] = [elt_doc for (elt_name, elt_doc) in elts 1070 if elt_doc in ungrouped] 1071 return groups
1072
1073 -class ModuleDoc(NamespaceDoc):
1074 """ 1075 API documentation information about a single module. 1076 """ 1077 #{ Information about the Module 1078 filename = UNKNOWN 1079 """@ivar: The name of the file that defines the module. 1080 @type: C{string}""" 1081 docformat = UNKNOWN 1082 """@ivar: The markup language used by docstrings in this module. 1083 @type: C{string}""" 1084 #{ Information about Submodules 1085 submodules = UNKNOWN 1086 """@ivar: Modules contained by this module (if this module 1087 is a package). (Note: on rare occasions, a module may have a 1088 submodule that is shadowed by a variable with the same name.) 1089 @type: C{list} of L{ModuleDoc}""" 1090 submodule_groups = UNKNOWN 1091 """@ivar: A dictionary specifying what group each 1092 submodule belongs to. The keys of the dictionary are group 1093 names, and the values are lists of C{ModuleDoc}s. The order 1094 that groups should be listed in should be taken from 1095 L{group_specs}. 1096 @type: C{dict} from C{str} to C{list} of L{ModuleDoc}""" 1097 #{ Information about Packages 1098 package = UNKNOWN 1099 """@ivar: API documentation for the module's containing package. 1100 @type: L{ModuleDoc}""" 1101 is_package = UNKNOWN 1102 """@ivar: True if this C{ModuleDoc} describes a package. 1103 @type: C{bool}""" 1104 path = UNKNOWN 1105 """@ivar: If this C{ModuleDoc} describes a package, then C{path} 1106 contains a list of directories that constitute its path (i.e., 1107 the value of its C{__path__} variable). 1108 @type: C{list} of C{str}""" 1109 #{ Information about Imported Variables 1110 imports = UNKNOWN 1111 """@ivar: A list of the source names of variables imported into 1112 this module. This is used to construct import graphs. 1113 @type: C{list} of L{DottedName}""" 1114 #} 1115 1125
1126 - def init_submodule_groups(self):
1127 """ 1128 Initialize the L{submodule_groups} attribute, based on the 1129 L{submodules} and L{group_specs} attributes. 1130 """ 1131 if self.submodules in (None, UNKNOWN): 1132 return 1133 self.submodules = sorted(self.submodules, 1134 key=lambda m:m.canonical_name) 1135 elts = [(m.canonical_name[-1], m) for m in self.submodules] 1136 self.submodule_groups = self._init_grouping(elts)
1137
1138 - def select_variables(self, group=None, value_type=None, public=None, 1139 imported=None, detailed=None):
1140 """ 1141 Return a specified subset of this module's L{sorted_variables} 1142 list. If C{value_type} is given, then only return variables 1143 whose values have the specified type. If C{group} is given, 1144 then only return variables that belong to the specified group. 1145 1146 @require: The L{sorted_variables}, L{variable_groups}, and 1147 L{submodule_groups} attributes must be initialized before 1148 this method can be used. See L{init_sorted_variables()}, 1149 L{init_variable_groups()}, and L{init_submodule_groups()}. 1150 1151 @param value_type: A string specifying the value type for 1152 which variables should be returned. Valid values are: 1153 - 'class' - variables whose values are classes or types. 1154 - 'function' - variables whose values are functions. 1155 - 'other' - variables whose values are not classes, 1156 exceptions, types, or functions. 1157 @type value_type: C{string} 1158 1159 @param group: The name of the group for which variables should 1160 be returned. A complete list of the groups defined by 1161 this C{ModuleDoc} is available in the L{group_names} 1162 instance variable. The first element of this list is 1163 always the special group name C{''}, which is used for 1164 variables that do not belong to any group. 1165 @type group: C{string} 1166 1167 @param detailed: If True (False), return only the variables 1168 deserving (not deserving) a detailed informative box. 1169 If C{None}, don't care. 1170 @type detailed: C{bool} 1171 """ 1172 if (self.sorted_variables is UNKNOWN or 1173 self.variable_groups is UNKNOWN): 1174 raise ValueError('sorted_variables and variable_groups ' 1175 'must be initialized first.') 1176 1177 if group is None: var_list = self.sorted_variables 1178 else: 1179 var_list = self.variable_groups[group] 1180 1181 # Public/private filter (Count UNKNOWN as public) 1182 if public is True: 1183 var_list = [v for v in var_list if v.is_public is not False] 1184 elif public is False: 1185 var_list = [v for v in var_list if v.is_public is False] 1186 1187 # Imported filter (Count UNKNOWN as non-imported) 1188 if imported is True: 1189 var_list = [v for v in var_list if v.is_imported is True] 1190 elif imported is False: 1191 var_list = [v for v in var_list if v.is_imported is not True] 1192 1193 # Detailed filter 1194 if detailed is True: 1195 var_list = [v for v in var_list if v.is_detailed() is True] 1196 elif detailed is False: 1197 var_list = [v for v in var_list if v.is_detailed() is not True] 1198 1199 # [xx] Modules are not currently included in any of these 1200 # value types. 1201 if value_type is None: 1202 return var_list 1203 elif value_type == 'class': 1204 return [var_doc for var_doc in var_list 1205 if (isinstance(var_doc.value, ClassDoc))] 1206 elif value_type == 'function': 1207 return [var_doc for var_doc in var_list 1208 if isinstance(var_doc.value, RoutineDoc)] 1209 elif value_type == 'other': 1210 return [var_doc for var_doc in var_list 1211 if not isinstance(var_doc.value, 1212 (ClassDoc, RoutineDoc, ModuleDoc))] 1213 else: 1214 raise ValueError('Bad value type %r' % value_type)
1215
1216 -class ClassDoc(NamespaceDoc):
1217 """ 1218 API documentation information about a single class. 1219 """ 1220 #{ Information about Base Classes 1221 bases = UNKNOWN 1222 """@ivar: API documentation for the class's base classes. 1223 @type: C{list} of L{ClassDoc}""" 1224 #{ Information about Subclasses 1225 subclasses = UNKNOWN 1226 """@ivar: API documentation for the class's known subclasses. 1227 @type: C{list} of L{ClassDoc}""" 1228 #} 1229 1239
1240 - def is_type(self):
1241 if self.canonical_name == DottedName('type'): return True 1242 if self.bases is UNKNOWN: return False 1243 for base in self.bases: 1244 if isinstance(base, ClassDoc) and base.is_type(): 1245 return True 1246 return False
1247
1248 - def is_exception(self):
1249 if self.canonical_name == DottedName('Exception'): return True 1250 if self.bases is UNKNOWN: return False 1251 for base in self.bases: 1252 if isinstance(base, ClassDoc) and base.is_exception(): 1253 return True 1254 return False
1255
1256 - def is_newstyle_class(self):
1257 if self.canonical_name == DottedName('object'): return True 1258 if self.bases is UNKNOWN: return False 1259 for base in self.bases: 1260 if isinstance(base, ClassDoc) and base.is_newstyle_class(): 1261 return True 1262 return False
1263
1264 - def mro(self, warn_about_bad_bases=False):
1265 if self.is_newstyle_class(): 1266 return self._c3_mro(warn_about_bad_bases) 1267 else: 1268 return self._dfs_bases([], set(), warn_about_bad_bases)
1269
1270 - def _dfs_bases(self, mro, seen, warn_about_bad_bases):
1271 if self in seen: return mro 1272 mro.append(self) 1273 seen.add(self) 1274 if self.bases is not UNKNOWN: 1275 for base in self.bases: 1276 if isinstance(base, ClassDoc) and base.proxy_for is None: 1277 base._dfs_bases(mro, seen, warn_about_bad_bases) 1278 elif warn_about_bad_bases: 1279 self._report_bad_base(base) 1280 return mro
1281
1282 - def _c3_mro(self, warn_about_bad_bases):
1283 """ 1284 Compute the class precedence list (mro) according to C3. 1285 @seealso: U{http://www.python.org/2.3/mro.html} 1286 """ 1287 bases = [base for base in self.bases if isinstance(base, ClassDoc)] 1288 if len(bases) != len(self.bases) and warn_about_bad_bases: 1289 for base in self.bases: 1290 if (not isinstance(base, ClassDoc) or 1291 base.proxy_for is not None): 1292 self._report_bad_base(base) 1293 w = [warn_about_bad_bases]*len(bases) 1294 return self._c3_merge([[self]] + map(ClassDoc._c3_mro, bases, w) + 1295 [list(bases)])
1296
1297 - def _report_bad_base(self, base):
1298 if not isinstance(base, ClassDoc): 1299 log.warning("%s's base %s is not a class" % 1300 (self.canonical_name, base.canonical_name)) 1301 elif base.proxy_for is not None: 1302 log.warning("No information available for %s's base %s" % 1303 (self.canonical_name, base.proxy_for))
1304
1305 - def _c3_merge(self, seqs):
1306 """ 1307 Helper function for L{_c3_mro}. 1308 """ 1309 res = [] 1310 while 1: 1311 nonemptyseqs=[seq for seq in seqs if seq] 1312 if not nonemptyseqs: return res 1313 for seq in nonemptyseqs: # find merge candidates among seq heads 1314 cand = seq[0] 1315 nothead=[s for s in nonemptyseqs if cand in s[1:]] 1316 if nothead: cand=None #reject candidate 1317 else: break 1318 if not cand: raise "Inconsistent hierarchy" 1319 res.append(cand) 1320 for seq in nonemptyseqs: # remove cand 1321 if seq[0] == cand: del seq[0]
1322
1323 - def select_variables(self, group=None, value_type=None, inherited=None, 1324 public=None, imported=None, detailed=None):
1325 """ 1326 Return a specified subset of this class's L{sorted_variables} 1327 list. If C{value_type} is given, then only return variables 1328 whose values have the specified type. If C{group} is given, 1329 then only return variables that belong to the specified group. 1330 If C{inherited} is True, then only return inherited variables; 1331 if C{inherited} is False, then only return local variables. 1332 1333 @require: The L{sorted_variables} and L{variable_groups} 1334 attributes must be initialized before this method can be 1335 used. See L{init_sorted_variables()} and 1336 L{init_variable_groups()}. 1337 1338 @param value_type: A string specifying the value type for 1339 which variables should be returned. Valid values are: 1340 - 'instancemethod' - variables whose values are 1341 instance methods. 1342 - 'classmethod' - variables whose values are class 1343 methods. 1344 - 'staticmethod' - variables whose values are static 1345 methods. 1346 - 'properties' - variables whose values are properties. 1347 - 'class' - variables whose values are nested classes 1348 (including exceptions and types). 1349 - 'instancevariable' - instance variables. This includes 1350 any variables that are explicitly marked as instance 1351 variables with docstring fields; and variables with 1352 docstrings that are initialized in the constructor. 1353 - 'classvariable' - class variables. This includes any 1354 variables that are not included in any of the above 1355 categories. 1356 @type value_type: C{string} 1357 1358 @param group: The name of the group for which variables should 1359 be returned. A complete list of the groups defined by 1360 this C{ClassDoc} is available in the L{group_names} 1361 instance variable. The first element of this list is 1362 always the special group name C{''}, which is used for 1363 variables that do not belong to any group. 1364 @type group: C{string} 1365 1366 @param inherited: If C{None}, then return both inherited and 1367 local variables; if C{True}, then return only inherited 1368 variables; if C{False}, then return only local variables. 1369 1370 @param detailed: If True (False), return only the variables 1371 deserving (not deserving) a detailed informative box. 1372 If C{None}, don't care. 1373 @type detailed: C{bool} 1374 """ 1375 if (self.sorted_variables is UNKNOWN or 1376 self.variable_groups is UNKNOWN): 1377 raise ValueError('sorted_variables and variable_groups ' 1378 'must be initialized first.') 1379 1380 if group is None: var_list = self.sorted_variables 1381 else: var_list = self.variable_groups[group] 1382 1383 # Public/private filter (Count UNKNOWN as public) 1384 if public is True: 1385 var_list = [v for v in var_list if v.is_public is not False] 1386 elif public is False: 1387 var_list = [v for v in var_list if v.is_public is False] 1388 1389 # Inherited filter (Count UNKNOWN as non-inherited) 1390 if inherited is None: pass 1391 elif inherited: 1392 var_list = [v for v in var_list if v.container != self] 1393 else: 1394 var_list = [v for v in var_list if v.container == self ] 1395 1396 # Imported filter (Count UNKNOWN as non-imported) 1397 if imported is True: 1398 var_list = [v for v in var_list if v.is_imported is True] 1399 elif imported is False: 1400 var_list = [v for v in var_list if v.is_imported is not True] 1401 1402 # Detailed filter 1403 if detailed is True: 1404 var_list = [v for v in var_list if v.is_detailed() is True] 1405 elif detailed is False: 1406 var_list = [v for v in var_list if v.is_detailed() is not True] 1407 1408 if value_type is None: 1409 return var_list 1410 elif value_type == 'method': 1411 return [var_doc for var_doc in var_list 1412 if (isinstance(var_doc.value, RoutineDoc) and 1413 var_doc.is_instvar in (False, UNKNOWN))] 1414 elif value_type == 'instancemethod': 1415 return [var_doc for var_doc in var_list 1416 if (isinstance(var_doc.value, RoutineDoc) and 1417 not isinstance(var_doc.value, ClassMethodDoc) and 1418 not isinstance(var_doc.value, StaticMethodDoc) and 1419 var_doc.is_instvar in (False, UNKNOWN))] 1420 elif value_type == 'classmethod': 1421 return [var_doc for var_doc in var_list 1422 if (isinstance(var_doc.value, ClassMethodDoc) and 1423 var_doc.is_instvar in (False, UNKNOWN))] 1424 elif value_type == 'staticmethod': 1425 return [var_doc for var_doc in var_list 1426 if (isinstance(var_doc.value, StaticMethodDoc) and 1427 var_doc.is_instvar in (False, UNKNOWN))] 1428 elif value_type == 'property': 1429 return [var_doc for var_doc in var_list 1430 if (isinstance(var_doc.value, PropertyDoc) and 1431 var_doc.is_instvar in (False, UNKNOWN))] 1432 elif value_type == 'class': 1433 return [var_doc for var_doc in var_list 1434 if (isinstance(var_doc.value, ClassDoc) and 1435 var_doc.is_instvar in (False, UNKNOWN))] 1436 elif value_type == 'instancevariable': 1437 return [var_doc for var_doc in var_list 1438 if var_doc.is_instvar is True] 1439 elif value_type == 'classvariable': 1440 return [var_doc for var_doc in var_list 1441 if (var_doc.is_instvar in (False, UNKNOWN) and 1442 not isinstance(var_doc.value, 1443 (RoutineDoc, ClassDoc, PropertyDoc)))] 1444 else: 1445 raise ValueError('Bad value type %r' % value_type)
1446
1447 -class RoutineDoc(ValueDoc):
1448 """ 1449 API documentation information about a single routine. 1450 """ 1451 #{ Signature 1452 posargs = UNKNOWN 1453 """@ivar: The names of the routine's positional arguments. 1454 If an argument list contains \"unpacking\" arguments, then 1455 their names will be specified using nested lists. E.g., if 1456 a function's argument list is C{((x1,y1), (x2,y2))}, then 1457 posargs will be C{[['x1','y1'], ['x2','y2']]}. 1458 @type: C{list}""" 1459 posarg_defaults = UNKNOWN 1460 """@ivar: API documentation for the positional arguments' 1461 default values. This list has the same length as C{posargs}, and 1462 each element of C{posarg_defaults} describes the corresponding 1463 argument in C{posargs}. For positional arguments with no default, 1464 C{posargs_defaults} will contain None. 1465 @type: C{list} of C{ValueDoc} or C{None}""" 1466 vararg = UNKNOWN 1467 """@ivar: The name of the routine's vararg argument, or C{None} if 1468 it has no vararg argument. 1469 @type: C{string} or C{None}""" 1470 kwarg = UNKNOWN 1471 """@ivar: The name of the routine's keyword argument, or C{None} if 1472 it has no keyword argument. 1473 @type: C{string} or C{None}""" 1474 lineno = UNKNOWN # used to look up profiling info from pstats. 1475 """@ivar: The line number of the first line of the function's 1476 signature. For Python functions, this is equal to 1477 C{func.func_code.co_firstlineno}. The first line of a file 1478 is considered line 1. 1479 @type: C{int}""" 1480 #} end of "signature" group 1481 1482 #{ Decorators 1483 decorators = UNKNOWN 1484 """@ivar: A list of names of decorators that were applied to this 1485 routine, in the order that they are listed in the source code. 1486 (I.e., in the reverse of the order that they were applied in.) 1487 @type: C{list} of C{string}""" 1488 #} end of "decorators" group 1489 1490 #{ Information Extracted from Docstrings 1491 arg_descrs = UNKNOWN 1492 """@ivar: A list of descriptions of the routine's 1493 arguments. Each element of this list is a tuple C{(args, 1494 descr)}, where C{args} is a list of argument names; and 1495 C{descr} is a L{ParsedDocstring 1496 <epydoc.markup.ParsedDocstring>} describing the argument(s) 1497 specified by C{arg}. 1498 @type: C{list}""" 1499 arg_types = UNKNOWN 1500 """@ivar: Descriptions of the expected types for the 1501 routine's arguments, encoded as a dictionary mapping from 1502 argument names to type descriptions. 1503 @type: C{dict} from C{string} to L{ParsedDocstring 1504 <epydoc.markup.ParsedDocstring>}""" 1505 return_descr = UNKNOWN 1506 """@ivar: A description of the value returned by this routine. 1507 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 1508 return_type = UNKNOWN 1509 """@ivar: A description of expected type for the value 1510 returned by this routine. 1511 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 1512 exception_descrs = UNKNOWN 1513 """@ivar: A list of descriptions of exceptions 1514 that the routine might raise. Each element of this list is a 1515 tuple C{(exc, descr)}, where C{exc} is a string contianing the 1516 exception name; and C{descr} is a L{ParsedDocstring 1517 <epydoc.markup.ParsedDocstring>} describing the circumstances 1518 under which the exception specified by C{exc} is raised. 1519 @type: C{list}""" 1520 #} end of "information extracted from docstrings" group 1521 callgraph_uid = None 1522 """@ivar: L{DotGraph}.uid of the call graph for the function. 1523 @type: C{str}""" 1524
1525 - def is_detailed(self):
1526 if super(RoutineDoc, self).is_detailed(): 1527 return True 1528 1529 if self.arg_descrs not in (None, UNKNOWN) and self.arg_descrs: 1530 return True 1531 1532 if self.arg_types not in (None, UNKNOWN) and self.arg_types: 1533 return True 1534 1535 if self.return_descr not in (None, UNKNOWN): 1536 return True 1537 1538 if self.exception_descrs not in (None, UNKNOWN) and self.exception_descrs: 1539 return True 1540 1541 if (self.decorators not in (None, UNKNOWN) 1542 and [ d for d in self.decorators 1543 if d not in ('classmethod', 'staticmethod') ]): 1544 return True 1545 1546 return False
1547
1548 - def all_args(self):
1549 """ 1550 @return: A list of the names of all arguments (positional, 1551 vararg, and keyword), in order. If a positional argument 1552 consists of a tuple of names, then that tuple will be 1553 flattened. 1554 """ 1555 if self.posargs is UNKNOWN: 1556 return UNKNOWN 1557 1558 all_args = _flatten(self.posargs) 1559 if self.vararg not in (None, UNKNOWN): 1560 all_args.append(self.vararg) 1561 if self.kwarg not in (None, UNKNOWN): 1562 all_args.append(self.kwarg) 1563 return all_args
1564
1565 -def _flatten(lst, out=None):
1566 """ 1567 Return a flattened version of C{lst}. 1568 """ 1569 if out is None: out = [] 1570 for elt in lst: 1571 if isinstance(elt, (list,tuple)): 1572 _flatten(elt, out) 1573 else: 1574 out.append(elt) 1575 return out
1576
1577 -class ClassMethodDoc(RoutineDoc): pass
1578 -class StaticMethodDoc(RoutineDoc): pass
1579
1580 -class PropertyDoc(ValueDoc):
1581 """ 1582 API documentation information about a single property. 1583 """ 1584 #{ Property Access Functions 1585 fget = UNKNOWN 1586 """@ivar: API documentation for the property's get function. 1587 @type: L{RoutineDoc}""" 1588 fset = UNKNOWN 1589 """@ivar: API documentation for the property's set function. 1590 @type: L{RoutineDoc}""" 1591 fdel = UNKNOWN 1592 """@ivar: API documentation for the property's delete function. 1593 @type: L{RoutineDoc}""" 1594 #} 1595 #{ Information Extracted from Docstrings 1596 type_descr = UNKNOWN 1597 """@ivar: A description of the property's expected type, extracted 1598 from its docstring. 1599 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 1600 #} end of "information extracted from docstrings" group 1601 1608
1609 - def is_detailed(self):
1610 if super(PropertyDoc, self).is_detailed(): 1611 return True 1612 1613 if self.fget not in (None, UNKNOWN) and self.fget.pyval is not None: 1614 return True 1615 if self.fset not in (None, UNKNOWN) and self.fset.pyval is not None: 1616 return True 1617 if self.fdel not in (None, UNKNOWN) and self.fdel.pyval is not None: 1618 return True 1619 1620 return False
1621 1622 ###################################################################### 1623 ## Index 1624 ###################################################################### 1625
1626 -class DocIndex:
1627 """ 1628 [xx] out of date. 1629 1630 An index that .. hmm... it *can't* be used to access some things, 1631 cuz they're not at the root level. Do I want to add them or what? 1632 And if so, then I have a sort of a new top level. hmm.. so 1633 basically the question is what to do with a name that's not in the 1634 root var's name space. 2 types: 1635 - entirely outside (eg os.path) 1636 - inside but not known (eg a submodule that we didn't look at?) 1637 - container of current thing not examined? 1638 1639 An index of all the C{APIDoc} objects that can be reached from a 1640 root set of C{ValueDoc}s. 1641 1642 The members of this index can be accessed by dotted name. In 1643 particular, C{DocIndex} defines two mappings, accessed via the 1644 L{get_vardoc()} and L{get_valdoc()} methods, which can be used to 1645 access C{VariableDoc}s or C{ValueDoc}s respectively by name. (Two 1646 separate mappings are necessary because a single name can be used 1647 to refer to both a variable and to the value contained by that 1648 variable.) 1649 1650 Additionally, the index defines two sets of C{ValueDoc}s: 1651 \"reachable C{ValueDoc}s\" and \"contained C{ValueDoc}s\". The 1652 X{reachable C{ValueDoc}s} are defined as the set of all 1653 C{ValueDoc}s that can be reached from the root set by following 1654 I{any} sequence of pointers to C{ValueDoc}s or C{VariableDoc}s. 1655 The X{contained C{ValueDoc}s} are defined as the set of all 1656 C{ValueDoc}s that can be reached from the root set by following 1657 only the C{ValueDoc} pointers defined by non-imported 1658 C{VariableDoc}s. For example, if the root set contains a module 1659 C{m}, then the contained C{ValueDoc}s includes the C{ValueDoc}s 1660 for any functions, variables, or classes defined in that module, 1661 as well as methods and variables defined in classes defined in the 1662 module. The reachable C{ValueDoc}s includes all of those 1663 C{ValueDoc}s, as well as C{ValueDoc}s for any values imported into 1664 the module, and base classes for classes defined in the module. 1665 """ 1666
1667 - def __init__(self, root):
1668 """ 1669 Create a new documentation index, based on the given root set 1670 of C{ValueDoc}s. If any C{APIDoc}s reachable from the root 1671 set does not have a canonical name, then it will be assigned 1672 one. etc. 1673 1674 @param root: A list of C{ValueDoc}s. 1675 """ 1676 for apidoc in root: 1677 if apidoc.canonical_name in (None, UNKNOWN): 1678 raise ValueError("All APIdocs passed to DocIndexer " 1679 "must already have canonical names.") 1680 1681 # Initialize the root items list. We sort them by length in 1682 # ascending order. (This ensures that variables will shadow 1683 # submodules when appropriate.) 1684 # When the elements name is the same, list in alphabetical order: 1685 # this is needed by the check for duplicates below. 1686 self.root = sorted(root, 1687 key=lambda d: (len(d.canonical_name), d.canonical_name)) 1688 """The list of C{ValueDoc}s to document. 1689 @type: C{list}""" 1690 1691 # Drop duplicated modules 1692 # [xx] maybe what causes duplicates should be fixed instead. 1693 # If fixed, adjust the sort here above: sorting by names will not 1694 # be required anymore 1695 i = 1 1696 while i < len(self.root): 1697 if self.root[i-1] is self.root[i]: 1698 del self.root[i] 1699 else: 1700 i += 1 1701 1702 self.mlclasses = self._get_module_classes(self.root) 1703 """A mapping from class names to L{ClassDoc}. Contains 1704 classes defined at module level for modules in L{root} 1705 and which can be used as fallback by L{find()} if looking 1706 in containing namespaces fails. 1707 @type: C{dict} from C{str} to L{ClassDoc} or C{list}""" 1708 1709 self.callers = None 1710 """A dictionary mapping from C{RoutineDoc}s in this index 1711 to lists of C{RoutineDoc}s for the routine's callers. 1712 This dictionary is initialized by calling 1713 L{read_profiling_info()}. 1714 @type: C{list} of L{RoutineDoc}""" 1715 1716 self.callees = None 1717 """A dictionary mapping from C{RoutineDoc}s in this index 1718 to lists of C{RoutineDoc}s for the routine's callees. 1719 This dictionary is initialized by calling 1720 L{read_profiling_info()}. 1721 @type: C{list} of L{RoutineDoc}""" 1722 1723 self._funcid_to_doc = {} 1724 """A mapping from C{profile} function ids to corresponding 1725 C{APIDoc} objects. A function id is a tuple of the form 1726 C{(filename, lineno, funcname)}. This is used to update 1727 the L{callers} and L{callees} variables.""" 1728 1729 self._container_cache = {} 1730 """A cache for the L{container()} method, to increase speed.""" 1731 1732 self._get_cache = {} 1733 """A cache for the L{get_vardoc()} and L{get_valdoc()} methods, 1734 to increase speed."""
1735 1736 #//////////////////////////////////////////////////////////// 1737 # Lookup methods 1738 #//////////////////////////////////////////////////////////// 1739 # [xx] 1740 # Currently these only work for things reachable from the 1741 # root... :-/ I might want to change this so that imported 1742 # values can be accessed even if they're not contained. 1743 # Also, I might want canonical names to not start with ?? 1744 # if the thing is a top-level imported module..? 1745
1746 - def get_vardoc(self, name):
1747 """ 1748 Return the C{VariableDoc} with the given name, or C{None} if this 1749 index does not contain a C{VariableDoc} with the given name. 1750 """ 1751 var, val = self._get(name) 1752 return var
1753
1754 - def get_valdoc(self, name):
1755 """ 1756 Return the C{ValueDoc} with the given name, or C{None} if this 1757 index does not contain a C{ValueDoc} with the given name. 1758 """ 1759 var, val = self._get(name) 1760 return val
1761
1762 - def _get(self, name):
1763 """ 1764 A helper function that's used to implement L{get_vardoc()} 1765 and L{get_valdoc()}. 1766 """ 1767 # Convert name to a DottedName, if necessary. 1768 if not isinstance(name, DottedName): 1769 name = DottedName(name) 1770 1771 # Check if the result is cached. 1772 val = self._get_cache.get(name) 1773 if val is not None: return val 1774 1775 # Look for an element in the root set whose name is a prefix 1776 # of `name`. If we can't find one, then return None. 1777 for root_valdoc in self.root: 1778 if root_valdoc.canonical_name.dominates(name): 1779 # Starting at the root valdoc, walk down the variable/ 1780 # submodule chain until we find the requested item. 1781 var_doc = None 1782 val_doc = root_valdoc 1783 for identifier in name[len(root_valdoc.canonical_name):]: 1784 if val_doc is None: break 1785 var_doc, val_doc = self._get_from(val_doc, identifier) 1786 else: 1787 # If we found it, then return. 1788 if var_doc is not None or val_doc is not None: 1789 self._get_cache[name] = (var_doc, val_doc) 1790 return var_doc, val_doc 1791 1792 # We didn't find it. 1793 self._get_cache[name] = (None, None) 1794 return None, None
1795
1796 - def _get_from(self, val_doc, identifier):
1797 if isinstance(val_doc, NamespaceDoc): 1798 child_var = val_doc.variables.get(identifier) 1799 if child_var is not None: 1800 child_val = child_var.value 1801 if child_val is UNKNOWN: child_val = None 1802 return child_var, child_val 1803 1804 # If that fails, then see if it's a submodule. 1805 if (isinstance(val_doc, ModuleDoc) and 1806 val_doc.submodules is not UNKNOWN): 1807 for submodule in val_doc.submodules: 1808 if submodule.canonical_name[-1] == identifier: 1809 var_doc = None 1810 val_doc = submodule 1811 if val_doc is UNKNOWN: val_doc = None 1812 return var_doc, val_doc 1813 1814 return None, None
1815
1816 - def find(self, name, context):
1817 """ 1818 Look for an C{APIDoc} named C{name}, relative to C{context}. 1819 Return the C{APIDoc} if one is found; otherwise, return 1820 C{None}. C{find} looks in the following places, in order: 1821 - Function parameters (if one matches, return C{None}) 1822 - All enclosing namespaces, from closest to furthest. 1823 - If C{name} starts with C{'self'}, then strip it off and 1824 look for the remaining part of the name using C{find} 1825 - Builtins 1826 - Parameter attributes 1827 - Classes at module level (if the name is not ambiguous) 1828 1829 @type name: C{str} or L{DottedName} 1830 @type context: L{APIDoc} 1831 """ 1832 if isinstance(name, basestring): 1833 name = re.sub(r'\(.*\)$', '', name.strip()) 1834 if re.match('^([a-zA-Z_]\w*)(\.[a-zA-Z_]\w*)*$', name): 1835 name = DottedName(name) 1836 else: 1837 return None 1838 elif not isinstance(name, DottedName): 1839 raise TypeError("'name' should be a string or DottedName") 1840 1841 if context is None or context.canonical_name is None: 1842 container_name = [] 1843 else: 1844 container_name = context.canonical_name 1845 1846 # Check for the name in all containing namespaces, starting 1847 # with the closest one. 1848 for i in range(len(container_name), -1, -1): 1849 relative_name = container_name[:i]+name 1850 # Is `name` the absolute name of a documented value? 1851 # (excepting GenericValueDoc values.) 1852 val_doc = self.get_valdoc(relative_name) 1853 if (val_doc is not None and 1854 not isinstance(val_doc, GenericValueDoc)): 1855 return val_doc 1856 # Is `name` the absolute name of a documented variable? 1857 var_doc = self.get_vardoc(relative_name) 1858 if var_doc is not None: return var_doc 1859 1860 # If the name begins with 'self', then try stripping that off 1861 # and see if we can find the variable. 1862 if name[0] == 'self': 1863 doc = self.find('.'.join(name[1:]), context) 1864 if doc is not None: return doc 1865 1866 # Is it the name of a builtin? 1867 if len(name)==1 and hasattr(__builtin__, name[0]): 1868 return None 1869 1870 # Is it a parameter's name or an attribute of a parameter? 1871 if isinstance(context, RoutineDoc): 1872 all_args = context.all_args() 1873 if all_args is not UNKNOWN and name[0] in all_args: 1874 return None 1875 1876 # Is this an object directly contained by any module? 1877 doc = self.mlclasses.get(name[-1]) 1878 if isinstance(doc, APIDoc): 1879 return doc 1880 elif isinstance(doc, list): 1881 log.warning("%s is an ambiguous name: it may be %s" % ( 1882 name[-1], 1883 ", ".join([ "'%s'" % d.canonical_name for d in doc ]))) 1884 1885 # Drop this item so that the warning is reported only once. 1886 # fail() will fail anyway. 1887 del self.mlclasses[name[-1]]
1888
1889 - def _get_module_classes(self, docs):
1890 """ 1891 Gather all the classes defined in a list of modules. 1892 1893 Very often people refers to classes only by class name, 1894 even if they are not imported in the namespace. Linking 1895 to such classes will fail if we look for them only in nested 1896 namespaces. Allow them to retrieve only by name. 1897 1898 @param docs: containers of the objects to collect 1899 @type docs: C{list} of C{APIDoc} 1900 @return: mapping from objects name to the object(s) with that name 1901 @rtype: C{dict} from C{str} to L{ClassDoc} or C{list} 1902 """ 1903 classes = {} 1904 for doc in docs: 1905 if not isinstance(doc, ModuleDoc): 1906 continue 1907 1908 for var in doc.variables.values(): 1909 if not isinstance(var.value, ClassDoc): 1910 continue 1911 1912 val = var.value 1913 if val in (None, UNKNOWN) or val.defining_module is not doc: 1914 continue 1915 if val.canonical_name in (None, UNKNOWN): 1916 continue 1917 1918 name = val.canonical_name[-1] 1919 vals = classes.get(name) 1920 if vals is None: 1921 classes[name] = val 1922 elif not isinstance(vals, list): 1923 classes[name] = [ vals, val ] 1924 else: 1925 vals.append(val) 1926 1927 return classes
1928 1929 #//////////////////////////////////////////////////////////// 1930 # etc 1931 #//////////////////////////////////////////////////////////// 1932
1933 - def reachable_valdocs(self, **filters):
1934 """ 1935 Return a list of all C{ValueDoc}s that can be reached, 1936 directly or indirectly from this C{DocIndex}'s root set. 1937 1938 @param filters: A set of filters that can be used to prevent 1939 C{reachable_valdocs} from following specific link types 1940 when looking for C{ValueDoc}s that can be reached from the 1941 root set. See C{APIDoc.apidoc_links} for a more complete 1942 description. 1943 """ 1944 return reachable_valdocs(self.root, **filters)
1945
1946 - def container(self, api_doc):
1947 """ 1948 Return the C{ValueDoc} that contains the given C{APIDoc}, or 1949 C{None} if its container is not in the index. 1950 """ 1951 # Check if the result is cached. 1952 val = self._container_cache.get(api_doc) 1953 if val is not None: return val 1954 1955 if isinstance(api_doc, GenericValueDoc): 1956 self._container_cache[api_doc] = None 1957 return None # [xx] unknown. 1958 if isinstance(api_doc, VariableDoc): 1959 self._container_cache[api_doc] = api_doc.container 1960 return api_doc.container 1961 if len(api_doc.canonical_name) == 1: 1962 self._container_cache[api_doc] = None 1963 return None 1964 elif isinstance(api_doc, ModuleDoc) and api_doc.package is not UNKNOWN: 1965 self._container_cache[api_doc] = api_doc.package 1966 return api_doc.package 1967 else: 1968 parent = self.get_valdoc(api_doc.canonical_name.container()) 1969 self._container_cache[api_doc] = parent 1970 return parent
1971 1972 #//////////////////////////////////////////////////////////// 1973 # Profiling information 1974 #//////////////////////////////////////////////////////////// 1975
1976 - def read_profiling_info(self, profile_stats):
1977 """ 1978 Initialize the L{callers} and L{callees} variables, given a 1979 C{Stat} object from the C{pstats} module. 1980 1981 @warning: This method uses undocumented data structures inside 1982 of C{profile_stats}. 1983 """ 1984 if self.callers is None: self.callers = {} 1985 if self.callees is None: self.callees = {} 1986 1987 # The Stat object encodes functions using `funcid`s, or 1988 # tuples of (filename, lineno, funcname). Create a mapping 1989 # from these `funcid`s to `RoutineDoc`s. 1990 self._update_funcid_to_doc(profile_stats) 1991 1992 for callee, (cc, nc, tt, ct, callers) in profile_stats.stats.items(): 1993 callee = self._funcid_to_doc.get(callee) 1994 if callee is None: continue 1995 for caller in callers: 1996 caller = self._funcid_to_doc.get(caller) 1997 if caller is None: continue 1998 self.callers.setdefault(callee, []).append(caller) 1999 self.callees.setdefault(caller, []).append(callee)
2000
2001 - def _update_funcid_to_doc(self, profile_stats):
2002 """ 2003 Update the dictionary mapping from C{pstat.Stat} funciton ids to 2004 C{RoutineDoc}s. C{pstat.Stat} function ids are tuples of 2005 C{(filename, lineno, funcname)}. 2006 """ 2007 # Maps (filename, lineno, funcname) -> RoutineDoc 2008 for val_doc in self.reachable_valdocs(): 2009 # We only care about routines. 2010 if not isinstance(val_doc, RoutineDoc): continue 2011 # Get the filename from the defining module. 2012 module = val_doc.defining_module 2013 if module is UNKNOWN or module.filename is UNKNOWN: continue 2014 # Normalize the filename. 2015 filename = os.path.abspath(module.filename) 2016 try: filename = py_src_filename(filename) 2017 except: pass 2018 # Look up the stat_func_id 2019 funcid = (filename, val_doc.lineno, val_doc.canonical_name[-1]) 2020 if funcid in profile_stats.stats: 2021 self._funcid_to_doc[funcid] = val_doc
2022 2023 ###################################################################### 2024 ## Pretty Printing 2025 ###################################################################### 2026
2027 -def pp_apidoc(api_doc, doublespace=0, depth=5, exclude=(), include=(), 2028 backpointers=None):
2029 """ 2030 @return: A multiline pretty-printed string representation for the 2031 given C{APIDoc}. 2032 @param doublespace: If true, then extra lines will be 2033 inserted to make the output more readable. 2034 @param depth: The maximum depth that pp_apidoc will descend 2035 into descendent VarDocs. To put no limit on 2036 depth, use C{depth=-1}. 2037 @param exclude: A list of names of attributes whose values should 2038 not be shown. 2039 @param backpointers: For internal use. 2040 """ 2041 pyid = id(api_doc.__dict__) 2042 if backpointers is None: backpointers = {} 2043 if (hasattr(api_doc, 'canonical_name') and 2044 api_doc.canonical_name not in (None, UNKNOWN)): 2045 name = '%s for %s' % (api_doc.__class__.__name__, 2046 api_doc.canonical_name) 2047 elif getattr(api_doc, 'name', None) not in (UNKNOWN, None): 2048 if (getattr(api_doc, 'container', None) not in (UNKNOWN, None) and 2049 getattr(api_doc.container, 'canonical_name', None) 2050 not in (UNKNOWN, None)): 2051 name ='%s for %s' % (api_doc.__class__.__name__, 2052 api_doc.container.canonical_name+ 2053 api_doc.name) 2054 else: 2055 name = '%s for %s' % (api_doc.__class__.__name__, api_doc.name) 2056 else: 2057 name = api_doc.__class__.__name__ 2058 2059 if pyid in backpointers: 2060 return '%s [%s] (defined above)' % (name, backpointers[pyid]) 2061 2062 if depth == 0: 2063 if hasattr(api_doc, 'name') and api_doc.name is not None: 2064 return '%s...' % api_doc.name 2065 else: 2066 return '...' 2067 2068 backpointers[pyid] = len(backpointers) 2069 s = '%s [%s]' % (name, backpointers[pyid]) 2070 2071 # Only print non-empty fields: 2072 fields = [field for field in api_doc.__dict__.keys() 2073 if (field in include or 2074 (getattr(api_doc, field) is not UNKNOWN 2075 and field not in exclude))] 2076 if include: 2077 fields = [field for field in dir(api_doc) 2078 if field in include] 2079 else: 2080 fields = [field for field in api_doc.__dict__.keys() 2081 if (getattr(api_doc, field) is not UNKNOWN 2082 and field not in exclude)] 2083 fields.sort() 2084 2085 for field in fields: 2086 fieldval = getattr(api_doc, field) 2087 if doublespace: s += '\n |' 2088 s += '\n +- %s' % field 2089 2090 if (isinstance(fieldval, types.ListType) and 2091 len(fieldval)>0 and 2092 isinstance(fieldval[0], APIDoc)): 2093 s += _pp_list(api_doc, fieldval, doublespace, depth, 2094 exclude, include, backpointers, 2095 (field is fields[-1])) 2096 elif (isinstance(fieldval, types.DictType) and 2097 len(fieldval)>0 and 2098 isinstance(fieldval.values()[0], APIDoc)): 2099 s += _pp_dict(api_doc, fieldval, doublespace, 2100 depth, exclude, include, backpointers, 2101 (field is fields[-1])) 2102 elif isinstance(fieldval, APIDoc): 2103 s += _pp_apidoc(api_doc, fieldval, doublespace, depth, 2104 exclude, include, backpointers, 2105 (field is fields[-1])) 2106 else: 2107 s += ' = ' + _pp_val(api_doc, fieldval, doublespace, 2108 depth, exclude, include, backpointers) 2109 2110 return s
2111
2112 -def _pp_list(api_doc, items, doublespace, depth, exclude, include, 2113 backpointers, is_last):
2114 line1 = (is_last and ' ') or '|' 2115 s = '' 2116 for item in items: 2117 line2 = ((item is items[-1]) and ' ') or '|' 2118 joiner = '\n %s %s ' % (line1, line2) 2119 if doublespace: s += '\n %s |' % line1 2120 s += '\n %s +- ' % line1 2121 valstr = _pp_val(api_doc, item, doublespace, depth, exclude, include, 2122 backpointers) 2123 s += joiner.join(valstr.split('\n')) 2124 return s
2125
2126 -def _pp_dict(api_doc, dict, doublespace, depth, exclude, include, 2127 backpointers, is_last):
2128 items = dict.items() 2129 items.sort() 2130 line1 = (is_last and ' ') or '|' 2131 s = '' 2132 for item in items: 2133 line2 = ((item is items[-1]) and ' ') or '|' 2134 joiner = '\n %s %s ' % (line1, line2) 2135 if doublespace: s += '\n %s |' % line1 2136 s += '\n %s +- ' % line1 2137 valstr = _pp_val(api_doc, item[1], doublespace, depth, exclude, 2138 include, backpointers) 2139 s += joiner.join(('%s => %s' % (item[0], valstr)).split('\n')) 2140 return s
2141
2142 -def _pp_apidoc(api_doc, val, doublespace, depth, exclude, include, 2143 backpointers, is_last):
2144 line1 = (is_last and ' ') or '|' 2145 s = '' 2146 if doublespace: s += '\n %s | ' % line1 2147 s += '\n %s +- ' % line1 2148 joiner = '\n %s ' % line1 2149 childstr = pp_apidoc(val, doublespace, depth-1, exclude, 2150 include, backpointers) 2151 return s + joiner.join(childstr.split('\n'))
2152
2153 -def _pp_val(api_doc, val, doublespace, depth, exclude, include, backpointers):
2154 from epydoc import markup 2155 if isinstance(val, APIDoc): 2156 return pp_apidoc(val, doublespace, depth-1, exclude, 2157 include, backpointers) 2158 elif isinstance(val, markup.ParsedDocstring): 2159 valrepr = `val.to_plaintext(None)` 2160 if len(valrepr) < 40: return valrepr 2161 else: return valrepr[:37]+'...' 2162 else: 2163 valrepr = repr(val) 2164 if len(valrepr) < 40: return valrepr 2165 else: return valrepr[:37]+'...'
2166