source: products/qPloneEpydoc/trunk/epydoc_patch.py @ 2683

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

Building directory structure

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