source: products/qPloneEpydoc/tags/0.1.2/epydoc_patch.py @ 458

Last change on this file since 458 was 1, checked in by myroslav, 18 years ago

Building directory structure

File size: 11.8 KB
Line 
1# Author: Melnychuk Taras
2# Contact: fenix@quintagroup.com
3# Date: $Date: 2005-11-23 12:35:02
4# Copyright: quintagroup.com
5
6from epydoc.uid import UID, Link, make_uid, findUID
7from epydoc.objdoc import ObjDoc, _find_base_order, _lookup_class_field, Var
8from epydoc.uid import _ZopeType, _ZopeMethodType, _ZopeCMethodType
9from epydoc.cli import _internal_error
10import epydoc.markup as markup
11import sys, os.path, re, getopt, types
12from epydoc.cli import _Progress
13import epydoc.cli
14import epydoc.html
15import epydoc.objdoc
16
17def epydoc_html_write_breadcrumbs(self, public, private, where=None):
18        """
19        Write the HTML code for the breadcrumbs line to the given
20        streams.  The breadcrumbs line is an invisible table with a
21        list of pointers to the current object's ancestors on the
22        left; and the show/hide private selector and the
23        frames/noframes selector on the right.
24
25        @param where: An identifier indicating what page we're
26            creating a navigation bar for.  This is either a UID
27            (for an object documentation page); or a string.  If
28            it is a UID, then a list of pointers to its ancestors
29            is displayed.
30        @param public: The output stream for the public version of the page.
31        @param private: The output stream for the private version of the page.
32        """
33        # Write the breadcrumbs (pointers to ancestors)
34        str = '<table width="100%" cellpadding="0" cellspacing="0">\n'
35        str += '  <tr valign="top">\n    <td width="100%">\n'
36        if isinstance(where, UID): str += self._breadcrumbs(where)
37        str += '    </td>\n    <td>'
38        str += '<table cellpadding="0" cellspacing="0">\n'
39        public.write(str); private.write(str)
40
41        # Write the public/private link
42        if self._create_private_docs:
43            link = self._public_private_link(where, from_private=0)
44            public.write('      <tr><td align="right">%s</td></tr>\n' % link)
45            link = self._public_private_link(where, from_private=1)
46            private.write('      <tr><td align="right">%s</td></tr>\n' % link)
47
48        # Write the frames/noframes link.
49        frames_link = ""
50        if self._frames_index:
51            frames_link = self._frames_link(where)
52        str = ('      <tr><td align="right">%s</td></tr>\n' % frames_link)
53        str += '    </table></td>\n'
54        str += '</tr></table>\n'
55        public.write(str); private.write(str)
56
57def epydoc_object__init__(self, uid, verbosity=0):
58        cls = uid.value()
59        # Variables:
60        self._tmp_ivar = {}
61        self._tmp_cvar = {}
62        self._tmp_type = {}
63        self._property_type = {}
64
65        ObjDoc.__init__(self, uid, verbosity)
66
67        # Handle methods & class variables
68        self._methods = []
69        self._cvariables = []
70        self._ivariables = []
71        self._staticmethods = []
72        self._classmethods = []
73        self._properties = []
74
75        # Find the order that bases are searched in.
76        base_order =  _find_base_order(cls)
77        self._base_order = [make_uid(b) for b in base_order]
78
79        try: fields = dir(cls)
80        except: fields = []
81        for field in fields:
82            # Don't do anything for these special variables:
83            # this is fenix changes
84            docstring = ''
85            try:
86                docstring = getattr(cls, field).__doc__
87            except:
88                pass
89            if field in ('__doc__', '__module__', '__dict__',
90                         '__weakref__', '__basicnew__', '__reduce__','__repr__')\
91            or (not field.startswith('__') and docstring in ( "PermissionRole",
92                                                              "Default Accessor.",
93                                                              "Default Mutator.",
94                                                              "Default Edit Accessor."
95                                                            )):
96                continue
97
98            # Find the class that defines the field; and get the value
99            # directly from that class (so methods & variables have
100            # the right uids).
101            (val, container) = _lookup_class_field(cls, field, base_order)
102
103            linkname = field
104            private_prefix = '_%s__' % container.shortname()
105            if field.startswith(private_prefix):
106                if container == self._uid:
107                    # If it's private and belongs to this class, then
108                    # undo the private name mangling.
109                    linkname = linkname[len(private_prefix)-2:]
110                else:
111                    # If it's private, and belongs to a parent class,
112                    # then don't even list it here.
113                    continue
114
115            # Deal with static/class methods and properties. (Python 2.2)
116            try:
117                # Get the un-munged value.
118                try: rawval = container.value().__dict__.get(field)
119                except: pass
120
121                if isinstance(rawval, staticmethod):
122                    vuid = make_uid(rawval, container, linkname)
123                    vlink = Link(linkname, vuid)
124                    self._staticmethods.append(vlink)
125                    continue
126                elif isinstance(rawval, classmethod):
127                    vuid = make_uid(rawval, container, linkname)
128                    vlink = Link(linkname, vuid)
129                    self._classmethods.append(vlink)
130                    continue
131                elif isinstance(rawval, property):
132                    vuid = make_uid(rawval, container, linkname)
133                    vlink = Link(linkname, vuid)
134                    self._properties.append(vlink)
135                    continue
136            except NameError: pass
137
138            # Create a UID and Link for the field value.
139            vuid = make_uid(val, container, linkname)
140            vlink = Link(linkname, vuid)
141
142            # Don't do anything if it doesn't have a full-path UID.
143            if vuid is None: continue
144            # Don't do anything for modules.
145            if vuid.is_module(): continue
146
147            # Is it a method?
148            if vuid.is_routine():
149                self._methods.append(vlink)
150
151            elif container == self._uid:
152                # Is it an instance variable?
153                if self._tmp_ivar.has_key(field):
154                    descr = self._tmp_ivar[field]
155                    del self._tmp_ivar[field]
156                    typ = self._tmp_type.get(field)
157                    if typ is not None: del self._tmp_type[field]
158                    else: typ = markup.parse_type_of(val)
159                    self._ivariables.append(Var(field, vuid, descr, typ, 1))
160
161                # Is it a class variable?
162                else:
163                    autogen = 1 # is it autogenerated?
164                    descr = self._tmp_cvar.get(field)
165                    if descr is not None:
166                        del self._tmp_cvar[field]
167                        autogen = 0
168                    typ = self._tmp_type.get(field)
169                    if typ is not None:
170                        del self._tmp_type[field]
171                        autogen = 0
172                    else: typ = markup.parse_type_of(val)
173                    self._cvariables.append(Var(field, vuid, descr,
174                                                typ, 1, autogen))
175
176        # Keep track of types for properties.
177        for prop in self._properties:
178            name = prop.name()
179            typ = self._tmp_type.get(name)
180            if typ is not None:
181                if prop.target().cls() != self._uid:
182                    estr = "@type can't be used on an inherited properties"
183                    self._field_warnings.append(estr)
184                self._property_type[prop.target()] = typ
185                del self._tmp_type[name]
186
187        # Add the remaining class variables
188        for (name, descr) in self._tmp_cvar.items():
189            typ = self._tmp_type.get(name)
190            if typ is not None: del self._tmp_type[name]
191            vuid = make_uid(None, self._uid, name)
192            self._cvariables.append(Var(name, vuid, descr, typ, 0))
193
194        # Add the instance variables.
195        for (name, descr) in self._tmp_ivar.items():
196            typ = self._tmp_type.get(name)
197            if typ is not None: del self._tmp_type[name]
198            vuid = make_uid(None, self._uid, name)
199            self._ivariables.append(Var(name, vuid, descr, typ, 0))
200
201        # Make sure we used all the type fields.
202        if self._tmp_type:
203            for key in self._tmp_type.keys():
204                estr = '@type for unknown variable %s' % key
205                self._field_warnings.append(estr)
206        del self._tmp_ivar
207        del self._tmp_cvar
208        del self._tmp_type
209
210        # Add links to base classes.
211        try: bases = cls.__bases__
212        except AttributeError: bases = []
213        self._bases = [Link(base.__name__, make_uid(base)) for base in bases
214                       if (type(base) in (types.ClassType, _ZopeType) or
215                           (isinstance(base, types.TypeType)))]
216
217        # Initialize subclass list.  (Subclasses get added
218        # externally with add_subclass())
219        self._subclasses = []
220
221        # Is it an exception?
222        try: self._is_exception = issubclass(cls, Exception)
223        except TypeError: self._is_exception = 0
224
225        # Inherited variables (added externally with inherit())
226        self._inh_cvariables = []
227        self._inh_ivariables = []
228
229        # Assemble a list of all methods
230        self._allmethods = (self._methods) #XXX+ self._classmethods +
231                            #self._staticmethods)
232
233        # Put everything in sorted order.
234        self._methods = self._sort(self._methods)
235        self._classmethods = self._sort(self._classmethods)
236        self._staticmethods = self._sort(self._staticmethods)
237        self._properties = self._sort(self._properties)
238        self._cvariables = self._sort(self._cvariables)
239        self._ivariables = self._sort(self._ivariables)
240        self._bases = self._sort(self._bases)
241        self._subclasses = self._sort(self._subclasses)
242        self._allmethods = self._sort(self._allmethods)
243
244        # Print out any errors/warnings that we encountered.
245        self._print_errors()
246
247def epydoc_cli_make_docmap(modules, options):
248    """
249    Construct the documentation map for the given modules.
250
251    @param modules: The modules that should be documented.
252    @type modules: C{list} of C{Module}
253    @param options: Options from the command-line arguments.
254    @type options: C{dict}
255    """
256    from epydoc.objdoc import DocMap, report_param_mismatches
257
258    verbosity = options['verbosity']
259    document_bases = 0
260    document_autogen_vars =1
261    inheritance_groups = (options['inheritance'] == 'grouped')
262    inherit_groups = (options['inheritance'] != 'grouped')
263    d = DocMap(verbosity, document_bases, document_autogen_vars,
264               inheritance_groups, inherit_groups)
265    if options['verbosity'] > 0:
266        print  >>sys.stderr, ('Building API documentation for %d modules.'
267                              % len(modules))
268    progress = _Progress('Building docs for', verbosity, len(modules))
269
270    for module in modules:
271        progress.report(module.__name__)
272        # Add the module.  Catch any exceptions that get generated.
273        try: d.add(module)
274        except Exception, e:
275            if options['debug']: raise
276            else: _internal_error(e)
277        except:
278            if options['debug']: raise
279            else: _internal_error()
280
281    if not options['ignore_param_mismatch']:
282        if not report_param_mismatches(d):
283            estr = '    (To supress these warnings, '
284            estr += 'use --ignore-param-mismatch)'
285            print >>sys.stderr, estr
286
287    return d
288
289epydoc.cli._make_docmap = epydoc_cli_make_docmap
290epydoc.html.HTMLFormatter._write_breadcrumbs = epydoc_html_write_breadcrumbs
291epydoc.objdoc.ClassDoc.__init__ = epydoc_object__init__
Note: See TracBrowser for help on using the repository browser.