1
2
3
4
5
6
7
8
9 """
10 Construct data structures that encode the API documentation for Python
11 objects. These data structures are created using a series of steps:
12
13 1. B{Building docs}: Extract basic information about the objects,
14 and objects that are related to them. This can be done by
15 introspecting the objects' values (with L{epydoc.docintrospecter}; or
16 by parsing their source code (with L{epydoc.docparser}.
17
18 2. B{Merging}: Combine the information obtained from introspection &
19 parsing each object into a single structure.
20
21 3. B{Linking}: Replace any 'pointers' that were created for imported
22 variables by their target (if it's available).
23
24 4. B{Naming}: Chose a unique 'canonical name' for each
25 object.
26
27 5. B{Docstring Parsing}: Parse the docstring of each object, and
28 extract any pertinant information.
29
30 6. B{Inheritance}: Add information about variables that classes
31 inherit from their base classes.
32
33 The documentation information for each individual object is
34 represented using an L{APIDoc}; and the documentation for a collection
35 of objects is represented using a L{DocIndex}.
36
37 The main interface to C{epydoc.docbuilder} consists of two functions:
38
39 - L{build_doc()} -- Builds documentation for a single item, and
40 returns it as an L{APIDoc} object.
41 - L{build_doc_index()} -- Builds documentation for a collection of
42 items, and returns it as a L{DocIndex} object.
43
44 The remaining functions are used by these two main functions to
45 perform individual steps in the creation of the documentation.
46
47 @group Documentation Construction: build_doc, build_doc_index,
48 _get_docs_from_*, _report_valdoc_progress
49 @group Merging: *MERGE*, *merge*
50 @group Linking: link_imports
51 @group Naming: _name_scores, _unreachable_names, assign_canonical_names,
52 _var_shadows_self, _fix_self_shadowing_var, _unreachable_name_for
53 @group Inheritance: inherit_docs, _inherit_info
54 """
55 __docformat__ = 'epytext en'
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 import sys, os, os.path, __builtin__, imp, re, inspect
71 from epydoc.apidoc import *
72 from epydoc.docintrospecter import introspect_docs
73 from epydoc.docintrospecter import get_value_from_filename, get_value_from_name
74 from epydoc.docparser import parse_docs, ParseError
75 from epydoc.docstringparser import parse_docstring
76 from epydoc import log
77 from epydoc.util import *
78 from epydoc.compat import *
79
80
81
82
83
85 """
86 Holds the parameters for a documentation building process.
87 """
88 - def __init__(self, introspect=True, parse=True,
89 exclude_introspect=None, exclude_parse=None,
90 add_submodules=True):
91 self.introspect = introspect
92 self.parse = parse
93 self.exclude_introspect = exclude_introspect
94 self.exclude_parse = exclude_parse
95 self.add_submodules = add_submodules
96
97
98 try:
99 self._introspect_regexp = (exclude_introspect
100 and re.compile(exclude_introspect) or None)
101 self._parse_regexp = (exclude_parse
102 and re.compile(exclude_parse) or None)
103 except Exception, exc:
104 log.error('Error in regular expression pattern: %s' % exc)
105 raise
106
108 """
109 Return C{True} if a module is to be introsepcted with the current
110 settings.
111
112 @param name: The name of the module to test
113 @type name: L{DottedName} or C{str}
114 """
115 return self.introspect \
116 and not self._matches_filter(name, self._introspect_regexp)
117
119 """
120 Return C{True} if a module is to be parsed with the current settings.
121
122 @param name: The name of the module to test
123 @type name: L{DottedName} or C{str}
124 """
125 return self.parse \
126 and not self._matches_filter(name, self._parse_regexp)
127
129 """
130 Test if a module name matches a pattern.
131
132 @param name: The name of the module to test
133 @type name: L{DottedName} or C{str}
134 @param regexp: The pattern object to match C{name} against.
135 If C{None}, return C{False}
136 @type regexp: C{pattern}
137 @return: C{True} if C{name} in dotted format matches C{regexp},
138 else C{False}
139 @rtype: C{bool}
140 """
141 if regexp is None: return False
142
143 if isinstance(name, DottedName):
144 name = str(name)
145
146 return bool(regexp.search(name))
147
148
149 -def build_doc(item, introspect=True, parse=True, add_submodules=True,
150 exclude_introspect=None, exclude_parse=None,
151 inherit_from_object=False):
152 """
153 Build API documentation for a given item, and return it as
154 an L{APIDoc} object.
155
156 @rtype: L{APIDoc}
157 @param item: The item to document, specified using any of the
158 following:
159 - A string, naming a python package directory
160 (e.g., C{'epydoc/markup'})
161 - A string, naming a python file
162 (e.g., C{'epydoc/docparser.py'})
163 - A string, naming a python object
164 (e.g., C{'epydoc.docparser.DocParser'})
165 - Any (non-string) python object
166 (e.g., C{list.append})
167 @param introspect: If true, then use introspection to examine the
168 specified items. Otherwise, just use parsing.
169 @param parse: If true, then use parsing to examine the specified
170 items. Otherwise, just use introspection.
171 """
172 docindex = build_doc_index([item], introspect, parse, add_submodules,
173 exclude_introspect=exclude_introspect,
174 exclude_parse=exclude_parse,
175 inherit_from_object=inherit_from_object)
176 return docindex.root[0]
177
178 -def build_doc_index(items, introspect=True, parse=True, add_submodules=True,
179 exclude_introspect=None, exclude_parse=None,
180 inherit_from_object=False):
181 """
182 Build API documentation for the given list of items, and
183 return it in the form of a L{DocIndex}.
184
185 @rtype: L{DocIndex}
186 @param items: The items to document, specified using any of the
187 following:
188 - A string, naming a python package directory
189 (e.g., C{'epydoc/markup'})
190 - A string, naming a python file
191 (e.g., C{'epydoc/docparser.py'})
192 - A string, naming a python object
193 (e.g., C{'epydoc.docparser.DocParser'})
194 - Any (non-string) python object
195 (e.g., C{list.append})
196 @param introspect: If true, then use introspection to examine the
197 specified items. Otherwise, just use parsing.
198 @param parse: If true, then use parsing to examine the specified
199 items. Otherwise, just use introspection.
200 """
201 try:
202 options = BuildOptions(parse=parse, introspect=introspect,
203 exclude_introspect=exclude_introspect, exclude_parse=exclude_parse,
204 add_submodules=add_submodules)
205 except Exception, e:
206
207 return None
208
209
210 log.start_progress('Building documentation')
211 if introspect:
212
213 _import_docs_from_items(items, options)
214 doc_pairs = _get_docs_from_items(items, options)
215 log.end_progress()
216
217
218 if options.parse and options.introspect:
219 log.start_progress('Merging parsed & introspected information')
220 docs = []
221 for i, (introspect_doc, parse_doc) in enumerate(doc_pairs):
222 if introspect_doc is not None and parse_doc is not None:
223 if introspect_doc.canonical_name not in (None, UNKNOWN):
224 name = introspect_doc.canonical_name
225 else:
226 name = parse_doc.canonical_name
227 log.progress(float(i)/len(doc_pairs), name)
228 docs.append(merge_docs(introspect_doc, parse_doc))
229 elif introspect_doc is not None:
230 docs.append(introspect_doc)
231 elif parse_doc is not None:
232 docs.append(parse_doc)
233 log.end_progress()
234 elif options.introspect:
235 docs = [doc_pair[0] for doc_pair in doc_pairs if doc_pair[0]]
236 else:
237 docs = [doc_pair[1] for doc_pair in doc_pairs if doc_pair[1]]
238
239 if len(docs) == 0:
240 log.error('Nothing left to document!')
241 return None
242
243
244 docindex = DocIndex(docs)
245
246
247
248 if options.parse:
249 log.start_progress('Linking imported variables')
250 valdocs = sorted(docindex.reachable_valdocs(
251 imports=False, submodules=False, packages=False, subclasses=False))
252 for i, val_doc in enumerate(valdocs):
253 _report_valdoc_progress(i, val_doc, valdocs)
254 link_imports(val_doc, docindex)
255 log.end_progress()
256
257
258 log.start_progress('Indexing documentation')
259 for i, val_doc in enumerate(docindex.root):
260 log.progress(float(i)/len(docindex.root), val_doc.canonical_name)
261 assign_canonical_names(val_doc, val_doc.canonical_name, docindex)
262 log.end_progress()
263
264
265 log.start_progress('Checking for overridden methods')
266 valdocs = sorted(docindex.reachable_valdocs(
267 imports=False, submodules=False, packages=False, subclasses=False))
268 for i, val_doc in enumerate(valdocs):
269 if isinstance(val_doc, ClassDoc):
270 percent = float(i)/len(valdocs)
271 log.progress(percent, val_doc.canonical_name)
272 find_overrides(val_doc)
273 log.end_progress()
274
275
276 log.start_progress('Parsing docstrings')
277 suppress_warnings = set(valdocs).difference(
278 docindex.reachable_valdocs(
279 imports=False, submodules=False, packages=False, subclasses=False,
280 bases=False, overrides=True))
281 for i, val_doc in enumerate(valdocs):
282 _report_valdoc_progress(i, val_doc, valdocs)
283
284 parse_docstring(val_doc, docindex, suppress_warnings)
285
286 if (isinstance(val_doc, NamespaceDoc) and
287 val_doc.variables not in (None, UNKNOWN)):
288 for var_doc in val_doc.variables.values():
289
290
291
292 if (isinstance(var_doc.value, ValueDoc)
293 and var_doc.value.defining_module is UNKNOWN):
294 var_doc.value.defining_module = val_doc.defining_module
295 parse_docstring(var_doc, docindex, suppress_warnings)
296 log.end_progress()
297
298
299 log.start_progress('Inheriting documentation')
300 for i, val_doc in enumerate(valdocs):
301 if isinstance(val_doc, ClassDoc):
302 percent = float(i)/len(valdocs)
303 log.progress(percent, val_doc.canonical_name)
304 inherit_docs(val_doc, inherit_from_object)
305 log.end_progress()
306
307
308 log.start_progress('Sorting & Grouping')
309 for i, val_doc in enumerate(valdocs):
310 if isinstance(val_doc, NamespaceDoc):
311 percent = float(i)/len(valdocs)
312 log.progress(percent, val_doc.canonical_name)
313 val_doc.init_sorted_variables()
314 val_doc.init_variable_groups()
315 if isinstance(val_doc, ModuleDoc):
316 val_doc.init_submodule_groups()
317 val_doc.report_unused_groups()
318 log.end_progress()
319
320 return docindex
321
327
328
329
330
331
350
352 subpackage_filenames = set()
353 module_filenames = {}
354 pkg_path = getattr(pkg, '__path__', ())
355 for subdir in pkg_path:
356 if os.path.isdir(subdir):
357 for name in os.listdir(subdir):
358 filename = os.path.join(subdir, name)
359 if is_module_file(filename):
360 basename = os.path.splitext(filename)[0]
361 if os.path.split(basename)[1] != '__init__':
362 module_filenames[basename]